Newbie to PIC programming, need some guidance! - Page 1
Forum section: electronics / general

author: fubar.gr
author_rank: Unknown
timestamp: February 07, 2016, 11:40:40 am
content: I want to get started with PIC programming and I would need some guidance with respect to the typical project workflow.So far I have a PICkit 3 programmer with the 44 pin demo board:https://i.ytimg.com/vi/s2d_TwzXFFQ/maxresdefault.jpgI've downloaded and installed MPLAB X IDE and IPE.So far I have figured out how to upload a ready made hex file into the microcontroller in the demo board, but I am not sure how to make a simple project from scratchSome questions:1) When starting a new project there's a point where you have to select the compiler toolchain. By default, MPLAB comes with MPASM, but some guides I've seen on the internet use C18 or XC8 toolchains. Is there any significant difference for beginner projects?2) Header files. If I'm not mistaken, the workflow goes like that: Bring up the configuration bits window, make the appropriate changes in the various options and then generate the code and copy it to a header file. This file is then invoked in the source file using an include command.Is the above correct or am I missing something?3) What is the purpose of a linker file and where can I find them?4) Are the header, linker and source files all I need to generate a hex file or am I missing something?

author: AndyC_772
author_rank: Super Contributor
timestamp: February 07, 2016, 11:49:31 am
content: Hi,You'll need to download and install XC8 as well as MPLABX. C18 is obsolete, don't bother with it.To configure the device, the easiest way is to open Window -> PIC memory views > Configuration bits, then make any changes and click 'generate source code to output'. I normally then copy this code into a file called config.h, and #include it at the start of my main.c.A linker file tells the compiler where in memory to place code and data. If you're just starting out, don't worry about this, it's not something you'll need to change. In fact, I'm not sure I've ever needed to modify linker scripts on a PIC platform.Strictly speaking, the minimum you need is just one source file; even headers are optional, but they become extremely useful once you start writing code that's large and complex enough to warrant splitting over multiple files.

author: Daving
author_rank: Contributor
timestamp: February 09, 2016, 05:14:53 pm
content: You'll need MPLAB X:http://www.microchip.com/pagehandler/en-us/family/mplabx/XC8:http://www.microchip.com/pagehandler/en-us/devtools/mplabxc/home.htmlThen there's a few video tutorials to get you started:Hope that helps get you started. Let us know how it goes.

author: dannyf
author_rank: Super Contributor
timestamp: February 09, 2016, 10:37:29 pm
content: If you want to stay with pics, xc8 is a good compiler, even in the free mode.However, I would argue that avrs are far better choices for hobbyists.

author: westfw
author_rank: Super Contributor
timestamp: February 10, 2016, 08:27:08 am
content: QuoteMPASM is an assembler. The other two are C compilers. Those are pretty significantly different! MPLAB requires that the compilers be downloaded and installed separately from te IDE itself. (as others have said, go ahead and install XC8.) Arguably, an 8bit PIC is not "beginner friendly" in either C or assembler.QuoteMaybe what you describe is one use for header files, but they're also used for importing the names of the registers associated with all the chip peripherals, the values of the various bits, definitions of functions associated with libraries, and ... more.QuoteAside from the stuff that the IDE includes that should be mostly invisible, all you need is "source files." Anything that could go into a header file can go into a source file, and the IDE has the normal system header files, and linker files. If you're talking about what files are present "behind the curtain", then there are probably lots of other things, including the assembler or compiler binaries, a wide range of files that configure the tools, and some sort of "project" file that describes the location and content of your particular project.

author: KL27x
author_rank: Super Contributor
timestamp: February 10, 2016, 10:10:35 am
content: QuoteEven on a short code, you should learn to include your own header files. Life changing, really. It took me a long time to figure out what I was missing, and I am still probably using them incorrectly and will make some mistakes in terminology. And I still use 8, not X, so maybe some things are different:For instance, the #include <P16F1628.inc> will include the default register definitions in MPLAB for that device. That's a header file.Your own header files could beError/warning messages. When you want to turn on/off error messages, click on your_error_reporting.inc file to open up your list of error codes to suppress. Just #include your_error_reporting.inc in your source code.your EEPROM initilizationyour Variables definitionsyour Pin definitionsyou could include any macros... if you use themYou can break up your source code, even, and #include it on the main page.Scrolling through a page of code can become unmanageable. You can make code-bookmarks. Right clicking on the page, you can jump to lines/labels, but when this list, itself, is several pages long, it's still a pain. And in 8 you can sorta kinda open a split window to look at two parts of once source file at the same time, but it's kinda broken IMO, so breaking your code (even if temporarily) can be very helpful. And taking all the major "non-code" stuff that you will want to frequently reference while writing code and putting it into header files allow you to always see it in a list of files in your main project window. Now you can click it to open it in a new window to read/modify/reference side by side with the window where you are writing new code. Play around with header files (and compiler/ide directives, too!), because it's a powerful tool.

author: dannyf
author_rank: Super Contributor
timestamp: February 10, 2016, 12:00:45 pm
content: QuoteMost of the code a compiler compiles is actually in the header files. My header file handling configure settings on PICs are over 100KB for XC8.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: February 10, 2016, 07:32:37 pm
content: 1) When starting a new project there's a point where you have to select the compiler toolchain. By default, MPLAB comes with MPASM, but some guides I've seen on the internet use C18 or XC8 toolchains. Is there any significant difference for beginner projects?MPASM is an assembler. With it you can write machine code in a structured way with variable names etc. C18 and XC8 arecompilers, which produce machine code from 'high level' C source code.As a beginner you should start with a simple assembler program (eg. blink a LED) where all the code necessary to run the program is visible. Get familiar with what the instructions do, how the hardware registers are accessed etc. and step through your code in the simulator or debugger to see exactly what it does. Then write the same program in C, and compare its output to the machine code produced by the assembler.2) Header files. If I'm not mistaken, the workflow goes like that: Bring up the configuration bits window, make the appropriate changes in the various options and then generate the code and copy it to a header file. This file is then invoked in the source file using an include command.Yes. A header file is just some source code which is put into another file. 'Including' the file tells the compiler or assembler to read the file and parse the text in it, just as if it was typed into the main program.3) What is the purpose of a linker file and where can I find them?Most compilers don't produce ready to run machine code. Instead they createobject codewhich has external references to other bits of code that need to be combined and have absolute addresses resolved. The linker file tells thelinkerwhich files to collect and how to combine them. MPLAB generates the linker file automatically so you don't need to know where to find it.The linker stage may seem superfluous, but in large projects it speeds up compilation greatly because only source code files that have been modified need to be recompiled. Also it permits advanced techniques such as combining the output of different compilers or assemblers, using precompiled libraries etc. But you don't have to be concerned about these things until/unless you need them.4) Are the header, linker and source files all I need to generate a hex file or am I missing something?Generally you only need the source file(s) and any extra header files that are not already provided with the compiler. If you are writing your own code from scratch then that's all you need. However many projects use libraries or other code that is not included in the distribution and has to be installed separately. This is often the hardest part of getting someone else's code to work.As a beginner you should try to avoid 'cutting and pasting' other people's code. Write everything yourself, making sure that you understand what it does. You will make lots of mistakes - which is agood thingbecause then you will learn how to fix them. Don't ignore compiler warnings, eliminate them! Debug your code (even when it seems to work perfectly) until you are happy that it is doing exactly what you intended.

author: eugenenine
author_rank: Frequent Contributor
timestamp: February 11, 2016, 01:41:48 am
content: You can download and play with Microchip's example codehttp://www.microchip.com/forums/FindPost/701984I've been messing with it a bit myself.

author: KL27x
author_rank: Super Contributor
timestamp: February 11, 2016, 01:55:19 am
content: Compiler warnings are one of the most impordant tools you have in your ide. Learn how to trigger warning messages intentionally to give yourself bookmarks. Warning messages will take you to specific places anywhere in your code when u click on the warning. Vs jumping to line/label, where you can only go within one file, and you cannot jump to areas that do not generate code, such as defines and configuration and variable assignments etc, which are really directives. (Labels have a line number. So writing a label at the top of say your eeprom initilization cant take you there. If you try to open that label, the ide will take you to the next point in your code that has a line, i.e. an instruction that produces code, which could be a c9mpletsly differnt page/file. So warning messages are really useful to make.So for instance writing a label that is indented will trigger a warning. You can use these improper labels to tag areas of interest or any experimental code. After everthing is tested and trusted, then u can fix everything to clear out the warnings.You will not be able to fix all warnings. You will have to suppress certain ones dealing with bank bits nd paging. Those will always be generated even if done correctly.

author: Daving
author_rank: Contributor
timestamp: February 12, 2016, 04:00:15 pm
content: Quote from: dannyf on February 10, 2016, 12:00:45 pmWoah...The header files contain the declarations of functions, and constants needed by the user of an API.The code that actually compiles to instructions in flash goes in the C file.If you have code that compiles to instructions in the header files, then you are duplicating instructions and wasting flash space. On an 8-bit MCU, this can be particularly wasteful.-RB

author: dannyf
author_rank: Super Contributor
timestamp: February 12, 2016, 04:10:25 pm
content: Quoteinlined code is typically done in the header files.

author: Daving
author_rank: Contributor
timestamp: February 12, 2016, 04:24:05 pm
content: True, but that's also not the majority of code, and presents a special case.How inline behaves is very compiler specific, and embedded design should be used with care.

author: dannyf
author_rank: Super Contributor
timestamp: February 12, 2016, 04:27:13 pm
content: that example is to show that the statement that you can have code outside of a source file.Another example would be the jump table for interrupt handlers. Typically defined in the header file but actually compiled and linked to jump instructions (to a user defined locations).

author: Daving
author_rank: Contributor
timestamp: February 12, 2016, 07:40:19 pm
content: My point still stands. Most of the code that's compiled is not in the header. The implications of that statement are very wrong, and potentially dangerous.Also, Interrupt jump tables are typically an extension off of ANSI C. Interrupt behaviors are compiler and platform dependent.Inlines can be in the header or in the c file. Which is better is compiler dependent.There are some embedded compilers where inline means nothing, and others that tend to break inlined function.There are almost always exceptions to any. That doesn't mean don't follow the rules, but rather that you better know what you're doing when you break them. It's also a waste of time to go over any and all exceptions, especially since most exceptions have exceptions

author: Daving
author_rank: Contributor
timestamp: February 12, 2016, 07:44:50 pm
content: Quote from: KL27x on February 11, 2016, 01:55:19 amMost IDEs, like netbeans and eclipse have TODO in coments for creating those bookmarks. That way you don't get real warnings drowned out by bookmark warnings.But, this could be handy when working with the compiler outside of any IDE.You can also just use #warning in most compilers.I have a header template that I use that has a #error to remind me to change the code guards, and TODOs for most other things, like copyright year, etc.

author: Howardlong
author_rank: Super Contributor
timestamp: February 12, 2016, 08:59:30 pm
content: About three days ago I did a 15 minute video on how to do a blinky with a PIC16 from components, then breadboarding, writing the program through to programming and running it with a PICkit3. This was deliberately a single continuous video clip, warts and all, from parts to finished product.Although the ~$0.50 PIC16 I used is different, the concepts are the same. It looks like the main differences are that your device starts up with an _XTAL_FREQ of 4MHz rather than 16MHz, and that the LEDs are on TRISD/LATD rather than TRISA/LATA.https://youtu.be/vV1hCSU5uuc

author: dannyf
author_rank: Super Contributor
timestamp: February 12, 2016, 10:02:59 pm
content: QuoteTrue.But that's quite different from this earlier statement of yours:QuoteThat's what I was trying to point out for you.

author: Howardlong
author_rank: Super Contributor
timestamp: February 12, 2016, 10:23:38 pm
content: Quote from: Howardlong on February 12, 2016, 08:59:30 pmAlmost there, as luck would have it I found your board in my stash of dev boards. The PIC16F887 device is quite old and doesn't use LATx for its output bits, it uses old school PORTx instead... which has its own complications but let's ignore that for now. Anyway, here is the code for a Blinky. You'll also see an extra #pragma config LVP = OFF in there as well as the _XTAL_FREQ and LATA to PORTD changes. The extra #pragma is because by default the chip requires a special programming mode which we need to switch off.Code:#include <xc.h>#pragma config WDTE = OFF#pragma config LVP = OFF#define _XTAL_FREQ 4000000void main(void){TRISDbits.TRISD2=0;while (1){PORTDbits.RD2=1;__delay_ms(500);PORTDbits.RD2=0;__delay_ms(500);}return;}

author: Eric_the_EE
author_rank: Contributor
timestamp: March 01, 2016, 05:53:27 pm
content: If you continue in PIC programming, this is a great book that walks through many common topics:http://www.amazon.com/Programming-16-Bit-PIC-Microcontrollers-Second/dp/1856178706/ref=sr_1_1?ie=UTF8&qid=1456854747&sr=8-1&keywords=learning+to+fly+the+pic24

author: KL27x
author_rank: Super Contributor
timestamp: March 02, 2016, 04:28:40 am
content: QuoteI noticed in one of my newer PIC datasheets, it said that writing to PORTX will write to the LATX, automatically. I haven't tried this yet. Maybe I interpreted it wrong. This could save a bit of jumping around between banks.

author: Howardlong
author_rank: Super Contributor
timestamp: March 02, 2016, 06:10:21 am
content: Quote from: KL27x on March 02, 2016, 04:28:40 amThe danger of doing this (that I alluded to earlier "which has its own complications") is that in situations that require rapid successive read-modify-write such as bit set and clear operations you risk reading back the wrong value on bits that you're not actually trying to change because of propagation delays and pin capacitance. It's one of those things that you experience once in your career and learn quickly from it!Rule of thumb is write to LAT read from PORT. In situations where there's no LAT, you just have to be careful and be wary of the limitations particularly when using bit set/clear or other RMW operations.

author: KL27x
author_rank: Super Contributor
timestamp: March 02, 2016, 06:20:19 am
content: The datasheet for one of my newer enhanced midrange"A write to the LATx register has the same effect as a write to corresponding PORTx register."This is not followed up with a caveat about read-modify-write. Again, I haven't verified it, but the way it is written suggests that it is equivalent. I'm aware of read-modify-write error.I am thinking it is possible that the enhanced midrange has been modified so that you can't read-modify-write to PORTx, but it will instead read-modify-write to the corresponding LATx register, automatically? And that it's only necessarily there for reading PORTx vs LATx? (I can't even imagine how that could be done in silicon, so maybe it's not realistic to even think this, LAT and PORT being on different memory banks.) So then again, maybe it's just trying to explain what is the LAT register. I suppose I am probably reading too much into this sentence, already being familiar with LAT register from previous PICs. For all I know, this is the same way LAT has been explained since the beginning.

author: dannyf
author_rank: Super Contributor
timestamp: March 02, 2016, 11:30:43 am
content: Essentially, rmw issues arise if the physical state of the pin deviates from the intended state of the pin - as indicated by the port output register.A write to the portx registers writes to the latx registers. A read from the portx registers reads from the portx registers. So no more rmw.

author: Howardlong
author_rank: Super Contributor
timestamp: March 02, 2016, 06:34:30 pm
content: A bit set or clear, for example, does RMW. It's the way the the PIC16 core works, and one of the reasons it takes four clocks per cycle. By doing a bit set or clear on PORTx rather than LATx you run the risk of incorrectly setting the latch on other bits particularly in the event of rapid successive port operations.