Wednesday, 24 October 2012

More Numbers

We're gradually decyphering the instructions in our world's smallest PIC program and turning numbers into names to make the program more readable. So far we know that register 7 is called PORTC and register 3 is called STATUS. We've also seen that register 87 is called TRISC but that 87 doesn't mean 87 decimal but 87 hex (87h).

Well you probably won't be surprised to hear that the instruction Bit Set File (bsf) is also just a name representing a number. Take another look at the PIC16F690 INSTRUCTION SET and you'll see that the  instruction bsf 7,0 is fully represented by a 14 bit opcode. The least significant 7 bits define the register (or file) and are shown as fffffff. The next 3 bits define which bit of the register is being tested or altered. These are shown as bbb. But the most significant 4 bits (the left hand 4 bits) are shown as 0101. So 'bsf' is just a symbol representing the code 0101.

Similarly the complete instruction 'bsf 7,0' is just a more readable version of the instruction 0101 000 0000111. I've split this binary number into three groups of bits representing the instruction, the bit and the file. Note that in the readable version, the file number comes first and the bit number second. In the binary version it's the other way around.

When the assembly language program is turned into machine code and transferred into the PICs program memory, it's in a pure binary format. So inside the PIC, the world's smallest program looks like this:


What about 'end', the 4th line of our program. There's no 'end' instruction in the PIC16F690 INSTRUCTION SET.

That's because 'end' isn't an instruction - it's an assembler directive. The assembler doesn't convert it into machine code. The programmer doesn't program it into the microcontroller. It just tells the assembler to stop assembling. I wouldn't have included it if I didn't have to, but without it the assembler generates an error and won't produce any object code.

Number Bases

Before we go any further, we need to talk about number bases. It's so fundamental to the way microcontrollers work that not much more can be done until we fully understand at least 2 different number bases, binary and hexadecimal.

If someone tells you that their number of friends is in single figures (or single digits) we immediately know the number is between zero and 9. That's because we (human beings) do all our counting in base 10, and in base 10, the number of different numerical characters is 10. But note that there is no single digit representation of the number 'ten' in base 10. Ten has to be expressed using two digits, one and zero, specifically a 'one' followed by a 'zero'.

Similarly, in base 2, there is no single digit representation of the number 'two'.

Now look at the 16F690 data sheet, figure 2-5 SPECIAL FUNCTION REGISTERS and you'll notice that after register 09h is register 0Ah (PCLATH). It's not until a bit further down that you'll find register 10h. But 10h is not 'ten' as we would normally understand it. In fact 10h is sixteen.

The clue here is the little h after the number. Actually it's more than just a clue, it's a clear indication that this number is not expressed in base 10. It's expressed in base sixteen, also called hexadecimal.

In PIC programming, the number base is also called the Radix and in assembly language there's a default radix. That's the number base that's assumed if your numerals have no radix indicator like the lowercase h that indicates hexadecimal. The default radix is hexadecimal, so in the third line of our world's smallest program, 87 is not 87 decimal but 87 hex (87h).

I've always felt that using the letters A to F to represent the six additional digits in hexadecimal is a bit of a cop out. I'd like to have seen six new number characters drawn up - six new exotic squiggles that would have be learnt. But that's not what happened and so A to F is what we have to work with.

Now it's my time to cop out and refer you to the Wikipedia article on Radix. It's very very short and so easily digested in a couple of minutes.

Bank Select

Moving on now to the second line in our world's smallest PIC program. Here's the program again:

bsf 7,0
bsf 3,5
clrf 87

The second instruction is also a 'bit set file' instruction, but this time it's bit 5 of register 3 that's being set. The data sheet tells us that register 3 is known as the STATUS register.

Now we have to consult a different part of the 16F690 data sheet. Go to section where the Status register is described. You can see that bit 5 is one of two bits (6 and 5) called RP1 and RP0, which are the register bank select bits.

Selecting register banks is an area of PIC programming that is often overlooked and can lead to very elusive program errors. The midrange PIC microcontrollers have a reduced instruction set which is only 14 bits wide. Of those 14 bits, just seven are used to define the file (or register) number that the instruction is to operate on. 7 bits gives us just 128 registers that are directly addressable by the instruction. But the 16F690 has 512 bytes of memory where the special purpose and general purpose registers are located.

So prior to using any of these registers in an instruction, the bank select bits must be properly set up to select the correct bank.

So, for example, PORTC is register 7 which is in the first of the four register banks. Be careful here, because the first bank is also called bank zero. This is a classic example of knowing whether to start counting from 0 or from 1.

We didn't need to worry about setting the bank select bits prior to our first instruction because they default to bank zero after boot up and PORTC is in bank zero. But TRISC (register 87) is in bank 1 and that's the register we need to write to in the 3rd line of the program.

Saturday, 20 October 2012

Ports and Airports

So we've discovered (by reading the 16F690 data sheet) that file 7 is also known as PORTC and that it's one of the special function registers. Files and registers are pretty much the same thing.

Like sea ports or airports, PIC ports are gateways to the outside world. On the 16F690, PORTC is an 8-bit port. Each of the 8 bits is connected to a pin (those sharp metal spiky things) on the outside of the chip. And on the Low Pin Count Demo Board, four of the pins are connected to red LEDs mounted on the board.

Time to look at another data sheet. Download the data sheet for the Low Pin Count Demo Board User's Guide (dated 2005). Find the LPC Demo Board Overview (section 1.4 on my data sheet) and scroll down to Figure 1-1 LPC DEMO BOARD.

You can see from this image (click it to enlarge it) that RC0, RC1, RC2 and RC3 are connected via copper tracks to the four LEDs. The lower four bits of PORTC have LEDs connected to them and if certain conditions are met, setting one of these bits will light the LED.

It should be starting to make sense now why setting bit 0 of file 7 (PORTC) makes LED DS1 light up.

Understanding Instructions

In this post we'll have a go at de-cyphering the first line of code in the world's smallest (and worst) PIC microcontroller program. Here it is:

bsf 7,0

What does bsf 7,0 mean? It means set bit 0 of file 7. Make sense? Nope? That's because we haven't read any of the data sheets yet. If you genuinely want to learn to program PIC microcontrollers, you'll need to read data sheets - and lots of them.

You probably have at least two windows open on your computer right now, one for your browser (to read this blog) and another for the MPLAB IDE (Integrated Development Environment). Well now it's time to open another, and that's Adobe Reader.

Do a Google search for 16F690 and click the first result with [PDF] at the beginning. Also make sure it's coming from Save the PDF to your computer. Open the PDF and make sure it's the data sheet for the PIC16F690.

In the bookmarks, find the section called Instruction Set Summary (it's section 15.0 in my data sheet). Scroll down to the table PIC16F685/687/689/690 INSTRUCTION SET and there's our instruction BSF in the section labelled BIT-ORIENTED FILE REGISTER OPERATIONS.

BSF or bsf (doesn't matter if it's upper or lower case) means Bit Set File. The first number after the instruction is the file number and the second number is the bit number. The numbers must be separated by a comma.

We know that bit 0 corresponds to LED DS1 on the demo board. And that bit 1 is LED DS2. You can predict the rest, but notice that there's an 'out by one' discrepancy here. You'll see these crop up again and again.

So what's file 7?

In the bookmarks, find the section called Memory Organisation (it's section 2.0 in my data sheet). Scroll down to the table PIC16F690 SPECIAL FUNCTION REGISTERS and there's our file at address 07h. It's called PORTC.

Finally, what does set mean? It's the opposite of clear. It means 1 (the opposite of zero). It means high (the opposite of low). It means 5 volts (the opposite of 0 volts). It means true (the opposite of false).

Quick task: find the instruction that does the opposite of BSF

A Few Positive Comments

So in this post, let's make a start on fixing some of the problems with the world's smallest (and worst) PIC microcontroller program.

First, lets add a comment which will serve as a title and an introduction to what the program does and how it works.

;Comments start with a semicolon, so in assembly source code, this sentence is a comment.

Here's the updated program:

;Assembly language program for the 16F690 which lights LED DS1 on the Low Pin Count Demo Board. It works, but it's full of bugs.

bsf 7,0 ;change 0 to 1, 2, or 3 to light different LEDs
bsf 3,5
clrf 87

You'll notice I've also added a comment to the end of the first line of code. This technique can be used to explain what that particular line does. Everything after a semicolon (until the line ends) is treated as a comment and is ignored by the assembler.

The rule with comments is:

Add as many comments as necessary to remind yourself how your program works.

Bad Start

So the world's smallest PIC program is also the world's worst program. Why exactly is that?

Well, for one thing, it's almost completely unreadable. All those numbers disguise what's actually going on here. We do know what one of the numbers does. The zero at the end of the first line determines which of the four LEDs lights up.

But far worse than poor readability, this program is full of bugs. So much so, that we'll have real problems moving to the next stage if we don't weed them out.

So in the next few posts, we'll fix the bugs and make the program more comprehensible, so that we can move on to making the LED flash on and off.

Friday, 19 October 2012

The World's Smallest PIC Program

So now we're going to erase the demo program that comes pre-programmed in the 16F690 and replace it with our own code. The program simply lights LED DS1 on the Low Pin Count Demo board. Here's the program:

bsf 7,0
bsf 3,5
clrf 87

In MPLAB IDE, open a new file and save the program as 'smallest.asm'. From the Configure menu, choose Select Device and in the pop-up window, make sure Device: is the 16F690. Click OK. Then from the Project menu select Quickbuild smallest.asm. Then from the Programmer menu select Program. You may also need to select Release from Reset from the Programmer menu.

Nice and simple isn't it? And it works. It's the world's smallest PIC microcontroller program (that actually does something useful).

And you can modify it to change which LED comes on. Replace the zero at the end of the first line with either a 1, or 2, or 3 to choose which LED lights up.

Oh and by the way, it's also the world's worst PIC program.

Get Something Working

Time to get the Low Pin Count Demo board fired up. Connect it to the PICkit2 (make sure the arrows indicating pin1 align). Connect the USB cable to your Windows PC and wait for the PICkit to be detected as a USB device.

Now run up MPLAB IDE. Go to the Programmer menu bar item and Select Programmer → PICkit2.

The Target LED on the programmer should light up, but the flashing light program in the 16F690 may not appear.

Again go to Programmer on the menu bar and select Release from Reset. The LEDs should start flashing.

Thursday, 18 October 2012

Be Prepared

If you're serious about programming PIC microcontrollers, you must be prepared to tackle a number of things. For example:
  • Be prepared to read data sheets. All of them from cover to cover. Take data sheets to bed with you. Read them once and be totally baffled. Read them again and pick up a few ideas. Read them a third time and things start falling into place.
  • Be prepared to learn basic electronics. Understand voltage, current and resistance. Learn Ohms law. I'll help you through it.
  • Be prepared to embrace different number bases. Understand binary. Understand hexadecimal. Loosen your attachment to base 10. Think about how to represent the world in 256 different values. Forget percentages.
  • Be prepared to understand the 'Out-by-One' error. Learn when to start counting from zero and when to start counting from 1.
  • Be prepared to get stuck. Learn to persevere. Understand that everyone hits a low point. You will climb out of it.


The scope of this blog will be defined initially by the PICkit2 and the Low Pin Count demo board that came with it. So the first code examples will be written for the 16F690 that came with the board. Then I'll try other midrange microcontrollers on the LPC demo board.

We'll work our way through the on-chip peripherals by flashing an LED in as many different ways as possible using each of the hardware elements in turn. We'll look at areas where you can get caught out so that you don't fall into that trap when you're writing more complex programs.

Starting Again

I've been programming PIC microcontrollers since 1992, which is probably not long after they first appeared. I started with a PICstart system, then advanced to the PICkit1, but now I'm having another go with the PICkit2.

This blog will be a beginners guide with the focus very much on starting from the beginning. There will be lots of flashing LED programs and simple code examples using timers, counters and other basic peripherals.