The previous posts about PIC16F84A explained about controlling the GPIO(General Purpose I/O) pins of the IC. Previously laid circuits explained only about how to switch on or off an LED. You just simply set the desired pin to output and then send a high/low signal to switch on/off the LED. Now, in this post, let us implement the blinking of LED – “The hello world program of embedded electronics” . So what do you do to make an LED blink? Just switch it on and off in an infinite loop. – yeah its right, but this is not going to work in our case. Since the PIC operates at very high speeds,though the LED is blinking you will not be able to see the LED blinking and it will appear as though its on continuously.
So, how to we tackle this problem? Its just simple, add a delay routine which keeps the pic busy for a while so that you could actually see the LED blinking. So, how do you add a delay loop?
- Store a number say 255 in a general purpose register
- Decrement the number by 1 until it reaches 0.
I know this sounds foolish and its a waste of time, delaying the operation of the PIC. But you will come to know in a due course that delay routines are very important. So, how to implement the above steps in program? Now, time to play with delay routines.
DELAY DECFZ 0C,1
any code here….
Now the above program does a pretty good job of keeping the PIC busy for roughly 255 instructions. Decoding the above program goes as, We first move the value 255 (value greater than255 is not allowed since registers of 16F84A are 8 bits in size) to a address location 0CH which specifies a general purpose register. The next line introduces a new instruction DECFZ which does two jobs. This instruction DECFZ, decrements the register by a amount specified. Here, it decrements the register by 1 and also checks whether the contents of the register 0CH (in our case) becomes zero. If the contents of the register becomes zero, then it skips the next line and then the program continues. So, the register is decremented till zero on a continuous loop. There is yet another instruction: EQU – which carries out the assignment operation. For example REG EQU 0CH means, oCH is assigned to the variable REG and in the place of 0CH, you can use REG. This is a handy instruction which makes the program more readable.
The above delay routine is not enough for our PIC!. Its that smart in executing instructions at amazing speeds. So, you need to introduce another delay routine – a delay within a delay.
DELAY DECFZ 0C,1
Hmm… thats a good amount of delay. Here, the controller decrements 255 to zero 255 times. This is sufficient to make the LED blink for our eyes.
Here is the full program to make a LED connected to pin 13 (PORTB,0) to blink. (Note the EQU instruction used here)
NUM1 EQU 0CH
NUM2 EQU 0DH
MOVLW B ‘00000000’
START BSF PORTB,0
DELAY DECFZ NUM1,1 ; Delay routine 1
DELAY DECFZ NUM1,1 ;Delay routine 2
DECFZ DECFZ NUM2,1
Note: Other instructions except labels such as START and DELAY should begin with a space because, the oshon compiler interprets whatever without a space as a label.
Circuit diagram for the above code:
If the LED blinks, you’ve done a spectacular job!. Try with different delay routines such as one routine, two routine etc.. at different crystals frequencies (4,10,16,20 MHz) and observe the results.