...
An assembled copy of the 2022 electrical tutorial board.
Note: Due to supply chain issues we had to go with a different microcontroller than was originally intended so the potentiometer isn’t usable for analog input without doing some complex bodges. Thus, it is optional for the purposes of this tutorial,A basic understanding of KiCad.
The KiCad files for the 2022 tutorial board.
A basic understanding of C.
...
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 1411.0, “IO Ports” (page 17295).
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 we can skip the next page about alternate pin function and our assumptions are confirmed by the first paragraph on the next page 97! “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 to the next page 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 1411-2 3: 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.
...
Now let’s try to turn an LED on and off in response to the button! We’ve already got the LED control sorted, so all we need to do is to figure out how to read the digital value of the button pin! If you feel confident, The Datasheet sections we just went over contain all the information you need to get this working. However, there are a few subtle tripping points I’ll point out below.
Right off the bat, we need to know which register we should be reading from. Read through the first page of section 14 11 and try to figure it out.
Hint: What’s the difference between reading from TRISx and PORTx?Go ahead and code up your solution based on the register you found above. I’ll spoil the surprise a bit and let you know that it won’t work yet, but its good to have something we can tweak and test with.
Now it’s time to debug! Let’s start by using a multimeter to probe the voltage on the pin, to make sure it’s not a hardware issue (as it too often is 😧). This is where pulling up the PCB in KiCad can be helpful - if you have both the schematic and the PCB open and you click on something on the schematic it will select it for you in the PCB! This is very helpful for finding where to probe.
Tip: Remember to be very careful not to short two pins together when probing. Feel free to call someone over to help you figure out the multimeter and how best to probe.Now, you should find that when you press and release the button, the voltage on the pin doesn’t change! First of all make sure you are using the multimeter correctly by probing something you know is +3V3 (eg one of the pads +3V3 pad on C1 or R2), and once you’ve confirmed that, think about why you’re not reading something different when the button is pressed.
Take a look at the schematic. You’ll notice that the button merely connects the pin to ground when pressed, and when released the pin isn’t actually connected to anything! This is called “floating”, and if you try to read the value of a floating pin you will get a random value that depends on things like electromagnetic interference and the specific internals of the PIC. To fix this, we would typically add a pull-up resistor between the pin and +3V3. As it turns out, I didn’t need to include one on this board because the PIC has its own internal pull-ups that we can enable! See section 14.2.7 Unfortunately the only info on the internal pull-ups is a brief mention in the first page and the corresponding register definition for how this is done, and give it a try! ! Go ahead and give enabling the pull-up a try, remember to look at the bit description and notes in the register definition. If you’ve done it correctly you should now see the pin go to +3V3 when the button is released.
So now we’ve fixed the “hardware” issue (which was really still a software issue), but why is it still not working? For this, I point you to the last two paragraphs paragraph in section 1411.0 and all of section 1411.23.63. For some godforsaken reason the PIC designers thought it would be a good idea for ANSEL to be enabled by default, and you just read about what that does. If your code does not work after fixing this last issue, call someone over to give you a hand.