The PIC Instruction Set
For low-end chips with only a small amount of program memory, you might choose to program in assembly language instead of C. Here we’re assuming that you’ve already done some assembly coding on a different processor and, for that reason, that you only need to learn about PIC specifics. You’ll easily be able to do that as a self-learning exercise, but a few words on the peculiarities of the PIC 16 series instruction set will, hopefully, help you get up to speed.
Higher-end PIC devices differ but the thing you’ll probably find surprising about PIC 16 series chips is that they don’t have any conditional branch instruction such as BRZ (BRanch if Zero). Certainly the chips have the necessary status bits – specifically zero and carry bits – but a different method is used for conditional flow control.
There are four conditional flow control instructions, all of them causing the next instruction to be skipped depending on whether a condition is met. These are BTFSS and BTFSC, which execute a bit test followed by a skip on set or clear, respectively, and DECFSZ and INCSFSZ, which execute a decrement or increment, respectively, followed by a skip if the result is zero. In most cases, the instruction following the conditional instruction – the one that may or may not be skipped – will be an unconditional branch, with the result that a PIC 16 assembly program will be slightly more like the proverbial spaghetti code than assembly programs for most other processors.
program memory is being written to. Some SBCs that are used with an IDE on a PC run their code automatically as soon as it’s been downloaded. With the Curiosity, though, you’ll have to unplug it from your PC’s USB port and reconnect it. This, of course, is a perfect analogy of what happens in real embedded applications – the code runs as soon as power is applied.
This demonstration code has several so-called labs, which are selected by pressing and releasing the pushbutton labelled S1, which is near the bottom left of the board, to the left of the mTouch button. To start, none of the labs will be running so you’ll need to press and release S1 to select Lab 1, and you’ll subsequently do the same to move from each lab to the next, cycling back to Lab 1 after Lab 10. You’ll be able to see the output of each lab by looking at the four red LEDs (D4, D5, D6 and D7) to the left of the potentiometer, and the action of Labs 1, 2 and 3 will be obvious.
Lab 4 will only be exercised properly if you try adjusting the potentiometer and you’ll then notice that the LEDs display a binary number related to the position of the potentiometer. In Lab 5 the LEDs rotate at a speed depending on the potentiometer position, and in Lab 6 the brightness of the left-most LED is controlled by the potentiometer. We’re not going to get embroiled in the other labs because the descriptions are a bit more involved. However, if you do want to read up on them, click EXAMPLES again and on the line for the Curiosity - PICF16F1619 example, click the red title.
Programming Curiosity
The primary language for programming PIC chips – certainly the more powerful ones – is C, but it isn’t our intention here to deviate from our topic of PIC programming by providing any instructions on coding in C. This being the case, if you’re not sufficiently au fait with this language, you’ll need to get up to speed, although at least the first of our suggested programming exercises are so trivial that not being proficient in C is no deterrent.
To help get a better feel for the workings of MPLAB Xpress, we’ll make an extremely simple change to Curiosity - PIC16F1619 so that, in Lab 2, the LED flashes at a different speed. First of all, though, let’s just take a look at what’s displayed on screen with the sample project loaded.
At the top left is an area labelled Project that shows, hierarchically, all the source and headers files associated with the project. Navigating around this is intuitive. You’ll also notice, in the largest area of the screen, that the source file main.c is already open for you to view and edit. If you do take a quick look at it, though, you’ll see that its function is nothing more than to increment the lab number as pushbutton S1 is pressed, and to call the appropriate function for the selected lab.
You’ll also notice that, since we want to alter the speed of flashing in Lab 2, the function we need is one called Blink. You’ll find the code for this under Curiosity PIC16F1619 > Source Files > Labs > Lab02_Blink in the tree structure of the project, so click Blink.c to open it in a new tab in the main area of the screen. A one-line change is all we need to make. That line is numbered 58 and is a macro definition for a constant called FLAG_
COUNTER_MAX , and which is defined as 3 to give a flash rate of 1.5 seconds. Try changing it to 1 to give a faster half-second flash rate, or to 20 to change the rate to 10 seconds. If you want more fine-tuning over the speed you’ll need to delve elsewhere, and we leave that as an exercise for you when you’ve finished working through our other examples.
Next up we’ll suggest another way in which you can alter the code and, while it’s still simple, at least it involves adding a few instructions instead of just changing a single line. Our change is going to be to Lab 2 again, and we’ll still see LEDs flashing so, if you’ve changed FLAG_ COUNTER_MAX to a large value, we suggest, first of all, that you change it back to 2 or 3 so you don’t have to wait too long to see things change. Next, go down to line 85 where you’ll find a function call to toggle LED D4 . What we’re suggesting is to add three lines after the one containing LED_D4_ Toggle(); with the instructions LED_D5_Toggle(); , LED_D6_ Toggle(); and LED_D7_Toggle(); . It’s fairly obvious what should happen, but go ahead anyway and
try it out. Hopefully all four LEDs will now flash instead of just the one.
Rather than jump straight in at this point by creating your own project from scratch, we recommend that you continue in this incremental approach of amending the Curiosity PIC16F1619 project in ever more ambitious ways. First of all continue modifying the labs to change their operation in various ways. Then, before moving on to a completely new project, how about adding a brand new lab, Lab 11, that performs totally new function. We’re sure you’ll have ideas aplenty.
Before moving on to our next topic of assembly programming, we should tell you some news about MPLA Xpress that Microchip was keen to tell us. There’s an improved version of MPLAB Xpress coming soon. Microchip is providing a GitHub interface for its community of users to store, collaborate and share their projects, and are moving the cloud services to scale for larger bandwidth. Apparently it’s already started to release examples there and we’ll see more of that in the time to come. It’s possible, therefore, that some of the ways of working with the new IDE will differ slightly from the one we describe here, although we don’t anticipate major changes and, after all, our primary aim has been to provide you with an overview of programming PIC chips, not a detailed tutorial on MPLAB Xpress.
PIC assembly
Assembly programming might sound like something from the pages of a history book but this isn’t necessarily true in the world of PICs. C code is rarely going to be as compact or efficient as assembly code, although this is often considered a price worth paying for convenience of high-level language programming with more powerful processors. However, if you’ve writing code for a chip with just a few hundred bytes of program memory, you might feel the need to bite the bullet and abandon C in favour of assembly code for smaller and faster code. We say a few words about the PIC 16 series instruction set in the box (above), but here we’ll take a quick look at how to program in assembly in the MPLAB Xpress IDE.
To use the PIC assembler instead of C, go to Project Properties in the File menu and then, under Compiler Toolchain, select mpasm. Now, whenever you create a new file it’ll be given a suitable extension and it’ll be passed over to the assembler, rather than the C compiler, when you come to build the project and program the PIC chip.
You might also be interested to learn that the XC8 compiler, which is MPLAB Xpress’ default C compiler for eight-bit PICs, enables you to use inline assembly code in a C program. This can be achieved by placing your block of assembly code between a #asm and a #endasm. However, for compatibility with the latest standards, this is now discouraged and instead, you’re advised to use the asm statement. Unfortunately, however, this makes the code look more untidy, and it’s more laborious to write, with each line of assembler looking rather like this example: asm( “DECFSZ COUNT” ); . Use inline assembler with caution, though, because altering the contents of a register could cause the surrounding C code to fail.