Prerequisites
An assembled copy of the 2022 electrical tutorial board.
A basic understanding of KiCad.
The KiCad files for the 2022 tutorial board.
A basic understanding of C.
Required Software
We use the MPLAB X IDE and the XC8 and XC16 compilers from Microchip. Having a recent (3.8+) version of Python installed is also useful, but won’t be necessary for this tutorial.
Creating a Project
First, open the MPLAB IDE and create a project (File → New Project).
Leave the default of Microchip Embedded Standalone Project.
Under “Device”, input the name of the microcontroller we are writing this code for. Leave “Tool” as “No Tool” for now.
Tip: You can find this in KiCad. Typically when writing firmware it will be much easier to read things like part numbers and pinouts from the schematic as opposed to the PCB. Open up the schematic now and leave it open, we’ll need it later.Select the version of XC8 that you have installed.
Give the project a name and hit the browse button to find a place to store it. Leave encoding alone.
Tip: Unless you check “Use project location as the project folder”, MPLAB will create a new folder (with the project’s name) and put it inside the location you selected. This can be fine, it just depends what you want.We now have a very barebones project. As you can see from the file browser on the left, there isn’t even a
main.c
!
Blink an LED
Add a
main.c
by adding a new file (File → New File) and under the “Microchip Embedded / XC8 Compiler” folder selectingmain.c
. Make sure to set the file name tomain
.With PIC microcontrollers, we control everything by reading from and writing to special named registers. These registers do everything from turning on and off output pins to configuring complicated peripherals like a CAN bus.
Let's turn on the red LED, which we can see on the schematic is connected to pinRA1/ICSPCLK
. First, we need to tell the PIC that we want to use that pin (referred to asRA1
) as a digital output. We do that by writing to theTRISA1
register inside ourmain
function:TRISA1 = 0; // Set A1 to be an output
Now that the pin is set as an output, we can turn the LED on or off by writing a 1 or a 0 to the
LATA1
register. Try to make a while loop that will blink the LED on and off forever!
Tip: An easy way of adding a delay is to busyloop. Try using a for loop that does nothing 1000 times as a delay.Now, time to test your code! Please call someone who knows how to program PICs over, there are just too many things that can go wrong here to explain them all in this guide.
Why did that work?
Congratulations on your first PIC program! Now, lets dive a little deeper and explain how I came up with the magic registers you needed to set to make that work.
Starting with the schematic, recall that the LED is connected to the pin labeled
RA1/ICSPCLK
. The/
means the pin has two functions, it is bothRA1
(the normal name for it) andICSPCLK
(a special pin used to program the PIC). SinceICSPCLK
is only used for programming, we can ignore it and just treat the pin asRA1
.
Let’s break down whatRA1
means. TheR
can be ignored, it just differentiates this pin from something like a power pin (VDD
orVSS
). TheA1
means that this is pin 1 of port A. When we start to deal with PICs that have more pins, there will be more ports (typically A, B and C) , each of which has (typically 8) numbered pins. Now, how do we control this pin?To learn how to do this, we will need to turn to The Datasheet. To find it, go to the product page for the specific PIC we are using (in this case here) and click the “Download Data Sheet” link. The Datasheet is a very long document that details every bit of functionality on the PIC. If there is something you want to know, it is almost certainly somewhere in The Datasheet. In our case, somewhere is chapter 14.0, “IO Ports” (page 172).
Now, unfortunately the writing of The Datasheet isn’t the most beginner friendly. However, in the left column on the first page we can see that they call the
LATx
registers “output latch” and talk about writing to them, so we can guess that settingLATx
is how we control digital outputs.
Tip: The lowercasex
is a common pattern to notice in PIC datasheets, it means that you should substitute something (a pin number for example) into the name.If we keep reading the first page we get some more general overview and important warnings (which we will need later) and come to a nice diagram which confirms our guess about writing to
LATx
(or in fact toPORTx
) being how we get data from the “Data bus” into the “Data Register”. We can also see that there is a buffer labeledTRISx
between the “Data Register” and the “I/O Pin”, this is a good clue. Continuing to read and our assumptions are confirmed by the first paragraph on the next page! “Clearing a TRISA bit (= 0) will make the corresponding PORTA pin an output.” This gives us everything we needed earlier: setting the pin to an output by settingTRISA1
to 0 and controlling the pin’s valve by settingLATA1
.Now, you might wonder how I knew to substitute
A1
intoTRISx
andLATx
. If you scroll down a few more pages in The Datasheet you will get to the “Register Definitions” section. You will find a register definitions section after every section in The Datasheet, and it tells you every single bit of every single register associated with that section. Taking a look at “Register 14-2 TRISA” we can see that each bit in the register (corresponding to a specific pin) is labeled, and explained below. We can then refer to those labels in our code, like we just did.Remember how we saw that we could have written to
PORTx
instead ofLATx
? Use the register definitions and make you code also blink the green LED, this time via thePORTA
register. Upload your code to the board to test it.