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:

01010000000111
01011010000011
00000110000111

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
end

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 2.2.2.1 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 microchip.com. 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
end

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.