??? 06/26/06 16:13 Modified: 06/26/06 16:37 Read: times |
#119126 - Conditional executing versus branching Responding to: ???'s previous message |
Arvind said:
1) Start
2) Intitialize the timer and interrupts 3) Is any key is pressed ... If YES then goto STEP - 4 else goto STEP - 2 4) Is the key pressed is valid ... If YES then goto STEP - 5 else goto STEP- 2 5) Is the key pressed is hited the 1st time or second time ... If hit 1st time then got to STEP - 6, else goto STEP - 7 6) Make the corresponding LED glow ... goto STEP - 8 7) Make the corresponding LED OFF 8) Is the key pressed is released ... If NO ... repeate the same STEP ... 9) goto STEP -2 Roughly spoken your algorithm does the right thing. But you make it very complicated and there are some traps and mistakes. a.) You distinguish between a first and second pressing of key. But your code performs an endless loop. So, what happens if the key is pressed for the third time? Is there any need for distinguishing between a first and second key pressing, at all? No, not really. You only want to make the LED's state to change, when the key is pressed. Means, was it on, shall it go off, or was it off shall it go on. So, you only need to know, whether the key was just pressed or not. If so, then the LED's state must change. If not, then nothing is to happen. Again, you don't need to know, whether the LED is on or off right now, when the switch is pressed. You only must change the state. Then, the infinite loops make sense again. b.) In step 4 you state "If the key pressed is valid..." Here you hide the debouncing. You should elaborate, how you perform this debouncing. Take care, step 8 should also be part of the debouncing scheme. You should name it correctly: "If the key is validly released...". I would recommend the reverse way: First find out how to debounce, then code what the key pressings shall do. Design a module called "debouncing", which can be a separate subroutine and which delivers the main program via a status byte, what key was actually pressed right now. c.) You have many jumps and conditional branches in your algorithm. This can lead to total confusion! It's much better to choose a coding, which performs this conditional executing without conditional branches. Let me give you an example: Assume you want to change the state of LED, but only when the key was just pressed. You can do this by two ways (at least): A.) By a piece of code, which performs a conditional branch, like this here: 1. If the key wasn't just pressed, then jump to step 3. 2. Else, change the state of LED. 3. Next instruction B.) Or by a logical operation: Assume you have a status byte "KEY_STATUS", which tells the main program whether a key was just pressed or not: "0" shall mean "not pressed", "1" shall mean "pressed". State of LEDs shall be represented by another byte, for instance by P2 of special function registers. Then, the following instruction will do the same as the first example, but without any conditional branching: XRL P2,KEY_STATUS What fabricates this instruction? If the according bit of KEY_STATUS is "0", then the XOR operation will not change the state of LED, because of: bit of KEY_STATUS old bit of P2 new bit of P2 -------------------------------------------------------- 0 XOR 0 = 0 0 XOR 1 = 1 So, the state of LED isn't changed. But, when the according bit of KEY_STATUS is "1", means when the according switch was just pressed, we get bit of KEY_STATUS old bit of P2 new bit of P2 -------------------------------------------------------- 1 XOR 0 = 1 1 XOR 1 = 0 So, the state of according LED becomes changed. Now, please look, how the following little code snippet does the job: mov r7,r6 ;save r6 mov r6,r5 ;save r5 mov r5,r4 ;save r4 mov r4,r3 ;save r3 mov r3,r2 ;save r2 mov a,p1 ;take a new sample mov r2,a ;store it in r2 cpl a ;complement the last sample anl a,r7 ;AND sample in r7 to it anl a,r6 ;AND sample in r6 to it anl a,r5 ;AND sample in r5 to it anl a,r4 ;AND sample in r4 to it anl a,r3 ;AND sample in r3 to it xrl p2,a ;actualize P2 First, all the old samples of P1 are shifted by one step to make place for the new sample. Then, the new sample is taken and stored into r2. Afterwards the new sample is inverted and ANDed with the old samples, to detect the situation, when the switch was just pressed after it was released for a duration of at least 50msec, means when we get /"0" AND "1" AND "1" AND "1" AND "1" AND "1" = "1". ("/" means "complement".) After this operation the accumulator contains a "1" right where the according switch was just pressed. And the last XRL-instruction finally changes the state of according LED if so, as explained above. Kai |
Topic | Author | Date |
Multiple switch debouncing | 01/01/70 00:00 | |
Otherways | 01/01/70 00:00 | |
Vertical counters | 01/01/70 00:00 | |
vertical conters in C | 01/01/70 00:00 | |
and here | 01/01/70 00:00 | |
vertical counter with press detection | 01/01/70 00:00 | |
debounce and denoise needed | 01/01/70 00:00 | |
You are right of course, but... | 01/01/70 00:00 | |
Reminds me... (off topic) | 01/01/70 00:00 | |
XRL P2,A | 01/01/70 00:00 | |
some hair-splitting | 01/01/70 00:00 | |
exchange | 01/01/70 00:00 | |
thanx Kai ... | 01/01/70 00:00 | |
my way | 01/01/70 00:00 | |
exactly! | 01/01/70 00:00 | |
Spot on. | 01/01/70 00:00 | |
Two samples enough? | 01/01/70 00:00 | |
varies with design | 01/01/70 00:00 | |
Conditional executing versus branching | 01/01/70 00:00 | |
KEY RELEASE SUBROUTINE ... | 01/01/70 00:00 | |
Not really... | 01/01/70 00:00 | |
a TOTAL misconception or -very annoying | 01/01/70 00:00 | |
He does not | 01/01/70 00:00 | |
Beer o'clock | 01/01/70 00:00 | |
Yes, good idea | 01/01/70 00:00 | |
never did, never will | 01/01/70 00:00 | |
Agree![]() | 01/01/70 00:00 |