MPLab and XC8 file organization

Started by PrimarySignal87 5 years ago10 replieslatest reply 5 years ago850 views

To get a better understanding of microcontroller programming beyond Arduino, I purchased a book on PIC programming in C.  I have done a few things with the IDE and a Dev board but wanted a deeper understanding of things like PWM, interrupts, communication protocols etc.  The book I purchased is listed here, Programming PIC Microcontrollers with XC8 by Armstrong Subero.  https://www.amazon.com/gp/product/1484232720/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

the book is fairly simple and easy to follow, but what I am bothered by is very little explanation past the authors minimal code comments.  my questions has to do with the different files he is creating and including/not including in subsequent files for a project.

An example is for using IIC to communicate with an EEprom.  he shows how to create a header file for the IIC communication IIC.h , then another file IIC.c where there is the code implementing the communication.  the next step jumps to a Main.c file that includes only the IIC.h file but not the IIC.c file.  how when compiling does the Main.c know to look for the IIC.c file if it is not called in the program?

The source code is also posted on GitHub with no more explanation than in the book, here.


I fairly new to the MPlab IDE as well as C programming in general so if there is some kind of code structure or organization I haven't learned yet I would appreciate some advice on learning materials that i can use to improve my embedded development skills.

[ - ]
Reply by msimunicJune 11, 2019

Hi PrimarySignal87,

Anybody could write an extensive answer how and why to build C project in a particular way. If you are looking for deeper understanding, I would suggest one of the books with topics about C Programming. Just plain old C (ANSI C 89) for x86 aka PC. If you find good book with ANSI C99 in the Title - don't worry, it's ok.

When you get from x86 architecture to 8-bit PIC then some aspects of C comes into focus which aren't in the focus when you are starting C Programming for the x86. For example, you don't have stdout and stderr on the PIC18, what FILE* means on PIC18, storage atributes, const, extern, volatile, static.

Working with pointers, struct, typedef, arrays is a must (like drinking water) no matter if you are programming for PIC18 or x86 or ARM-Cortex M...

After that there comes things like building a project. You can use some IDE like MPLAB X and "project" file or make file. How and why to isolate things in a modules (.c files) and how to connect them (.h files).

I would expect that you need one or two serious books to cover all aspects of C language.
I'm not read much of the books to suggest some particular.

Clearly, I would start with Kernigan & Ritchis's ANSI C, then maybe K.N King's C Programming - A modern approach.
Some specifics I could'nt find explained in any particular book but rather on some blogs or forum threads.

Wishing you a good cooding.


[ - ]
Reply by Bob11June 11, 2019

I'm unfamiliar with the MPlab IDE, but it appears the github example may be missing a project file or something similar. In essence the C compiler doesn't know anything about IIC.c other than what it knows from the IIC.h file. It's the job of the linker to 'link' the generated Main.c and IIC.c object files together. Both files need to be combined together somehow, either as a 'project' in the IDE, specified together on the command line, or in most production embedded projects specified together in a separate link phase in a makefile.

[ - ]
Reply by PrimarySignal87June 11, 2019

That makes sense, there is a folder in the project tree of MPlab IDE for "Linker Files" i must assume that is where the IIC.c would go and the header file would go in the normal header files" folder for that project.  Not having any of that introduced or explained in the book is a bit of a letdown as it is marketed as an "Intro" or maker class book.  Thanks for the clarification.  

On a side note, is there a reason for separating the two programs into a header and main file for the IIC protocol setup and execution? It seems like all of the code in both files could be implemented in the header file and then included in the Main.c as a single header without the need for a separate .c file.

Thanks again for the reply

[ - ]
Reply by Bob11June 11, 2019

mr_bandit addresses most of the C issues, although he's perhaps a bit harsh on the PIC. It's customary in C programs for 'main.c' to be the startup code for a project, while subsystems are specified in other source (.c) files. The header (.h) files contain only interfaces to those other subsystems. The purpose of this separation is more computer science than embedded programming; separating interface from implementation creates a more robust software architecture.

The book you have looks like a good introduction to PIC embedded programming, but as the Amazon description states "This book assumes knowledge of the C programming language and basic knowledge of digital electronics though a basic overview is given for both." With only 15 pages in your book devoted to C, you'll definitely need another reference for understanding the C programming paradigm. K&R is the usual classic, but there are plenty of other C books out there that will get you started as well.

[ - ]
Reply by mr_banditJune 11, 2019

Well - a death-march on a project with a PIC24 and one of the worst POS compilers (CCS) will do that. It could not even do a U32 divide the same way every time. Hacking a U32 divide at 3am is not my idea of fun - the algorithm was fun, but I could have used that 3..4 hours (including tracking down the bug) for *sleep*.

I will admit the CCS C compiler for the PIC16 is reasonable. But they just scaled up the compiler for a normal stack machine && got it *wrong*. I documented and counted - 60 hours for all of their bugs - that I found....

And I had debated changing to the GCC compiler && decided I was going to lose up to 60 hours converting the code. Never again...

I still have my copy of the White Book...

(The White Book is K&R first volume for the youngsters out there...)

K&R (both editions) are *THE BEST* technical books I have ever had the pleasure of using. I ALWAYS found the answer, even if it was "up to the compiler writer". 

You cannot go wrong with K&R 2. And, you can get the final ANSI draft versions for free. They are close enough to the final (approved) draft.

Pay attention to the "unspecified" and "undefined" tables. They will make or break you. C has many sinkholes and cliffs - stay away from them. Young padawan - keep your code simple. Mine looks like "run dick run". If you do something tricky, DOCUMENT the code on WHY and HOW.

I was on a gig. We (three core developers) had an hour-long discussion if we HAD TO use a ***ptr - meaning ANY OTHER WAY was going to be really crufty and grody. We finally agreed we needed to do it, but had 40+ lines of comments on WHY and HOW. There was much drawing of data structures on the white board... and "vocabulary" ....

[ - ]
Reply by AlexmouseJune 11, 2019

The functions in IIC.c are declared in IIC.h, so if Main.c is aware on IIC.h, it can find the functions in IIC.c. The 'include' is giving it directions as to where to look to find what it needs.

[ - ]
Reply by mr_banditJune 11, 2019

To expand on Alexmouse's comments:

Main.c and IIC.c are compiled separately. The linker needs to know about Main.obj and IIC.obj in order to make a .hex file that gets loaded.

(I have not used MPLAB for a long time - the file extensions might be different - eg .obj might be .o)

Logically, IIC.c "exports" the functions it "exposes" to the outside world as an "API" via IIC.h - meaning IIC.h are the functions the programmer who wrote the IIC functions wanted other programmers to know about. IIC.c might contain utility functions that it needs, but there is no reason for other programmers to know about them for normal uses. This is just like the Arduino build sequence.

I know you dropped some cash on the PIC stuff. I used to use PICs when I had no other choice, but I am now an AVR Freak - the MPU for Arduinos. The AVR toolkit is free from Microchip (they bought Atmel) and you can do straight C. You can use the Arduino loader.

You can also write straight C with the Arduino. Just don't use the libraries.

Whatever you do: DO NOT USE THE CCS compiler. I lost 60 hours of my life - in the middle of a tight deadline project. Use the GCC compiler.

Learn vim. Or emacs. Get away from GUI-type text editors. (long rant, but basically take off the training wheels.)

Advice for general development: Read the datasheet. Pick a section. Read it. Many times.

If you start with the UART, for example, take an Arduino and have it generate a UART stream of bytes. 0x55 or 0xAA is good, because the bits alternate. Keep in mind the difference between TTL and RS232 levels. You can easily do TTL to TTL for development. Remember TX and RX are from the Device viewpoint, so TX on one side goes to RX on the other.

The reason for doing this is the drivers for Arduino are already written - use them as a tool for your development. I have been in the biz before you were born and I do this all of the time. Also, look at adafruit and sparkfun for expansion boards.

For I2C master, take a look at https://www.sparkfun.com/products/13314 - it is an I2C temperature sensor. No setup, just read a register.

You should get a rigol DS1054Z for $375. I will not tell you there is a free tool on the interwebs that will change it from 50Hz to 100Hz. It you are serious about learning embedded systems, you need a scope. This oscope is almost as good as my Tek 2024B scope  I bought 10+ years for $2400. And - it has 4 cghannels. If you use a 2 channel scope, you will always need 3 channels...



I have written almost 100 device drivers for all sorts of devices. You want to reduce "friction" as much as you can - specifically, you want to make it as easy as you can to find bugs. You want to have reliable inputs if you are writing an input device driver, outputs the same. There is a reason a blinking LED is the embedded "Hello World".

[ - ]
Reply by matthewbarrJune 11, 2019

I was going to answer, but now I don't have to! I agree with all the comments and suggestions in Mr_Bandit's answer. In particular, read the data sheet, there is no substitute. The beauty of these relatively simple MMU-less microcontrollers is that you can get your arms around the device and instruction set architecture with relative ease. The ante goes up with a high-end processor from ST Micro, ARM, or a current generation Intel processor.

I emphatically second the Rigol DS1054Z suggestion. I have one for hacking at home and find it to be a great scope for the money, particularly with the included options for serial decode, advanced trigger and trace depth. You might take a look at tequipment.net (I have no affiliation) if you're seriously considering buying one.


By creating a free account you get a "member discount" which takes the price down to $348.75, ships free. I would never advocate doing something like this, but rumor has it the 100 MHz bandwidth hack works. The scope will report that it is a DS1104Z (Warranty? What warranty?) but your mileage may vary as regards the actual bandwidth increase. You have to characterize the channel inputs and find the true -3dB frequency to know what you really have.

[ - ]
Reply by mr_banditJune 11, 2019

Not sure where you live. There should be a hacker/makerspace near you. See hackerspaces.org or http://themakermap.com/ - keep in mind the may not be totally accurate or up-to-date.


Google "Mini Maker Faire" for your area. Contact the organizer - they usually are put on or invite or know the local makerspaces. They have members with deep knowledge in many areas && always willing to help.

[ - ]
Reply by PrimarySignal87June 11, 2019

 Thanks all for the informative replies! 

I've been learning electronics as a hobby for several years so I do have a couple of scopes and meters and bench power supply to work with. Im kind of stepping into the programming with the use of both PIC and atmel chips side by side since I was using the Arduino IDE and their line of hardware for a while.  I had bought the PICkit2 a long time ago and never ended up using it and just got the pickit3 recently to start focusing on the PIC line of hardware.  Partly I think was that it would "force" me to look inside the arduino libraries or other examples to understand how they work since the libraries wouldn't work for a PIC. I'll definitely look into the literature suggested a few posts ago, I was able to borrow a book from a friend as well that i'll give a read "C Programming: A Modern Approach" by KN King that he had from college.