c & c++ - Further Input

Contact
PC-compilers
last-news
PIC-microcontroller
AVR-microcontroller
Supports
weakly newsletter
c++
Counter
DS1821Thermostat Programmer
pic-asm-foundations
=> first programme
=> Time delays
=> Subroutines
=> Input
=> Further Input
free links downloads
free downloads
mikroc library
PWM software
Home



 

Further Input:

The next project is to develop the 4 bit counter to accept input. In this section, we will introduce a number of important topics. Let's start with a program specification:

A program that outputs a number between 0 and 15. The number can be changed by two switches designated "UP" and "DOWN". The counter should "wrap around" - in other words it should go from 15 to 0 when "UP" is pressed at a count of 15, and it should go from 0 to 15 when "DOWN" is pressed at a count of 0.

Seems simple enough, and we've already covered most of the elements before. We know how to set up our variables, and how to output them. We know how to check our Counter variable to see if it's reached the highest number allowed, and we could probably work out how to check for zero. We've seen how to test for a switch press, so surely we're almost there...

We can take our basic 4 bit counter and modify it for this purpose. The first step is to remove the incf Count,f line, and also the time delay. This means that our program will sit in a loop, outputing the value of Count. Unfortunately, there is nothing in the program to actually modify Count, so it will do nothing...

So we need to check for switch presses and modify Count accordingly. Here is the flow-diagram for this section:

As we saw on the previous page, coding this is actually quick straightforward:

btfss    PORTA, 0       ;Is "UP" switch pressed?
incf     Count,f        ; Yes, increment Count
                        ; No
btfss    PORTA, 1       ;Is "DOWN" switch pressed?
decf     Count,f        ; Yes, decrement Count
                        ; No

So we just insert these lines in the loop, and every few microseconds, the switches will be checked and Count will be modified accordingly.

After modifying Count, we must ensure that Count stays within the designated limits, and "wrap" Count as specified above.

For the first check, we've already used something similar for the original 4-bit counter:

movlw    d'16'       ;
xorwf    Count,w     ;W = Zero if Count = 16
btfsc    STATUS,Z    ;Is Z-flag set?
clrf     Count       ;  Yes, so reset Count
                     ;  No, OK

 Count is compared with MAX+1, and if equal, the Z-flag is set. The clrf Count line is skipped except when Count reaches 16. This is neat and easy because the reset only requires one line.

This deals with Count > MAX, but how are we going to check for Count < 0? This is more tricky to understand, but ultimately straightforward. We can also introduce a new "trick"...

Assume Count is currently 0, and the "DOWN" button is pressed. What happens to Count? In a normal number system, the answer would be -1, but what is this in our 8-bit binary world? The answer is "1111,1111", or 255.

So here we compare Count to 255. But to "wrap around" (make Count = 15) takes 2 lines. There are a number of ways to achieve this - this example demonstrates using goto to skip lines.

     movlw    d'255'      ;
     xorwf    Count,w     ;W = Zero if Count = 255 ("-1")
     btfss    STATUS,Z    ;Is Z-flag set?
     goto     ok          ;  No, Ok...
     movlw    d'15'       ;  Yes, so count had reached "-1"
     movwf    Count       ;  Count = 15
ok                        ;

 

 This would work perfectly well, but here's a neater way:

movlw    d'255'      ;
xorwf    Count,w     ;W = Zero if Count = 255 ("-1")
movlw    d'15'       ;Setup W - Note this doesn't affect Z!
btfsc    STATUS,Z    ;Is Z-flag set?
movwf    Count       ;  Yes, so count had reached "-1"
                     ;  No, ok...

We still XOR Count with 255, but note that we load W with 15 before doing the bit-test instruction. This works because movlw doesn't affect the Z flag. Having loaded W, we decide whether we need to move this into Count. This subtle change is neat - it avoids using a goto, saves a word in programme memory and saves a few clock cycles. I've been surprised by how often I use this trick...

To save you having to type this in, you can download input1.ASM - I recommend you study it, and then programme this into a PIC. Use the same circuit as before, but add some more LED's. We'll use the same circuit for the rest of this page, so it's definitely worth taking the time to try this.

If you haven't spotted the problem from studying the source code, you will discover it when you press the buttons. The LED's all light up continuously, or at least appear to. In actual fact, the PIC counts rapidly while a switch is held. If you have access to an oscilloscope, you comfirm this - also check the frequency of each of the LEDs and determine the relationship between them...

This circuit does have a practical use - because the counter runs so very fast, it is impossible for you to predict the result you'll get when you release the button - therefore, it generates a random number between 0 and 15. We'll return to this topic soon...

It's clear that we need to do something that involves waiting for the switch to be released. And this is easy to achieve:

This flow diagram shows the steps necessary to deal with one switch - this needs to be repeated for each switch. As there are more steps for each switch, it worth considering using subroutines for each one:

btfss    PORTA,0   ;Is "UP" switch pressed?
call     Up        ;  Yes, so count up
btfss    PORTA,1   ;Is "UP" switch pressed?
call     Down      ;  Yes, so count down

In the above program, we did the limit-checking and wrapping after all the switches had been checked, but before we outputted the result. This meant that we didn't output any spurious values.

On to the next section - Subroutines explained .

Today, there have been 6 visitors (21 hits) on this page!
This website was created for free with Own-Free-Website.com. Would you also like to have your own website?
Sign up for free