The first thing that has been added is a couple of variables
delay_1 and delay_2
A variable is basically something that we give a name to (practically any name you want really) and MPLAB will then set aside 1byte of ram for our variable. this means that our variable can hold one byte (or 8 bits) of data. In this case, delay_1 and delay_2 will be used in our delay routine. You will hopefully understand variables more as we progress through the tutorials.
The next piece of code that has been added is in between our ‘begin’ label and ‘goto begin’ statment.
bsf PORTB, 0
bsf basically means SET which ever bit i say, at whatever memory location, register or PORT that i say. In this case we are saying SET pin 0 of PORTB to a logic 1. whenever we say set, it means ‘make it a logic 1′ By setting PORTB pin 0, we have effectively turned our LED on, because our LED is connected to PORTB pin 0.
call delay
whenever we say ‘call’ it means stop what your doing for just a moment, jump to whatever label it is that i am calling and do whatever the code says in that label. once we have finished our code in the called label, it will then return to our code, where we left off. In this case, we want to call a delay routine which will make sure that our LED doesn’t turn on and off so fast, so that we can’t see it flashing. So the LED is ON - then we call a delay to keep it on for just a little while (less than a second as you will soon find out) and then once the delay has finished doing what it was doing, it will RETURN to our code here and then continue with the rest of the LED flasher code. (as you will see in the next step - we will turn the LED OFF)
bcf PORTB, 0
bcf basically means CLEAR which ever bit i say, at whatever memory location, register or PORT that i say. In this case we are Clearing pin 0 of PORTB to a logic 0. Whenever we say CLEAR, it means ‘make it a logic 0′ By CLEARING PORTB pin 0 we have effectively turned our LED OFF, because our LED is connected to PORTB pin 0.
call delay
see above for explanation of this (it does exactly the same thing again - but this time holds the LED OFF for a split second)
goto begin
Even though this is in the templae from before, i thought i’d explain it here anyway. whenever we say goto, we basically just want to forget about what we are doing at the present time and just all out - go somewhere else and do that piece of code. We don’t have any intention of trying to return back to this spot and continue on (which is what the call instruction was doing) So that is the difference between using the CALL instruction and the GOTO instruction. So all of the above is our ‘main program’ or ‘main routine’ this is what runs the show if you like. but you will notice that underneath the main piece of code, we have some other bits of code. I.E. delay. This is called a sub-routine. we call this sub routine from within our main routine. A sub routine just helps us along to get everything running smoothly and more efficiently.
Let’s now look into this delay sub-routine:
movlw d’255′
movlw means ‘move whatever number i tell you (whether it be a hex number, octal, binary or decimal) into the w or working register. In this case we are telling it to move the decimal number (denoted by the letter d) ‘255′. it just so happens that the decimal number 255 is the largest number that we can fit in any one of our variables. This is because the pic 16f648a / 16f628a is an 8-bit microcontroller this means that we can store any binary number from all zeros 00000000 to all ones 11111111 (all zeros in binary 0000000 is equal to zero decimal 0) and (all ones in binary 11111111 is equal to 255 decimal) this means that there are 256 combinations within each 8-bit variable. we could also just have written this movlw b’11111111′ and would have donw exactly the same thing (because binary 11111111 equals decimal 255) or if you like hex numbers you coudl have written this - movlw h’ff’ and it would also have done exactly the same thing. If you’re not exactly sure about number conversions, then some scientific calculators have an inbuilt converter between hex, dec, oct and bin. Or i am sure you could download a free app online to help you also. In a moment, we will move the number from the w or working register into our delay_1 and delay_2 variables. You may ask “why not just copy 255 straight into delay_1 and delay_2, why bother wasting time first copying it to the w register and then to where we actually want it?” We’ll i’m glad you asked that question. Everytime we want to copy data anywhere, it first has to go through the w register. it’s kind of like the post office. if you want to send a letter to someone, you first have to give it to the post office who then gives the letter to your friend. the post office is like the w register, it is the in-between guy.
movwf delay_1
movwf delay_2
These two lines of code practially do the same thing. movwf means ‘copy whatever is in the w register, into wherever i say’ So in these two cases, the W register contains the decimal number 255 (because we put it in there just before) we are now giving it the instruction to copy this number in to delay_1 and delay_2. So now, delay_1 contains the decimal number 255 and delay_2 also contains 255. From here, we will focus on counting down from 255 to 0. When we reach zero, we will return to our main program.
delay_loop
This is a label. you will soon see that when we have not yet reached zero, we will jump back to this label, this is why we call this delay routine a form of LOOP. because it keeps looping back around or going in circles untill it is complete.
decfsz delay_1, f
This is quite an involved instruction. decfsz basically means ‘decrement (or take 1 away from) the delay_1 variable. store the answer back in delay_1. If the answer is NOT zero, then just continue on with the very next liine BUT if the answer IS zero, then skip the very next line and continue from there.’ It’s quite a big instruction! these are very handy instructions for using in loops. In this case, we are starting from 255, we take 1 away (so the answer is 254) since the answer is NOT zero, then we goto the next line which will tell us to goto the ‘delay_loop’ label. As you can see it will keep looping around, taking 1 away each time untill it finally reaches zero. When it does get to zero, it will skip the next line (which would normally tell us to go to the ‘delay_loop’ label. and it jumps to the next piece of code which is very similar to this piece of code! An extra note with the above instruction. The ‘f’ at the end of the instruction means that we want the answer stored back in the variable (in this case, the variable is delay_1) we can change the ‘f’ to a ‘w’ if we want and this will store the answer in the w register, rather than in our variable. We will use that function in a later tutorial though.
goto delay_loop
As described above, this will take us back to the ‘delay_loop’ label everytime we come to this line of code. But, we will only come to this line of code as long as the delay_1 variable is not zero.
decfsz delay_2, f
This does basically exactly the same thing as the decfsz delay_1, f except this time we are decrementing the number stored in delay_2. So what happens is delay_1 decrements 255 times, then once that happens, delay_2 decrements once, then it goes back to the delay_loop label and again, delay_1 decrements 255 times, then delay_2 decrements once etc… So what you should be able to see is that we count down from 255 to 0, 255 times! Once we have finished, the next instruction is to return to where we just came from.
|