??? 06/21/10 14:43 Read: times |
#176806 - Don't lock up in infinite loops everywhere Responding to: ???'s previous message |
10ms or 25ms is often a quite good time for a hw timer to run, and to run one or more sw timers.
But a big issue with your code. Do not think in terms of loops. Don't lock up everywhere. Do look at state machines. Then you can keep your main loop active while waiting for keys. Below is some form of pseudo-code. 5 minutes of typing with no testing. enum { KBD_STATE_IDLE, KBD_STATE_WAIT_RELEASE, }; char key_lookup[12] = { "ABC1", "DEF2", ... }; unsigned char kbd_state = KBD_STATE_IDLE; unsigned char kbd_rotate_state = 0; // which of multiple alternatives to lookup and return for current key unsigned char kbd_timeout = 0; // tick down in interrupt handler - timeout for rotating characters for same key unsigned char kbd_was_rotate = FALSE; // if returned key should replace previously returned key signed char kbd_prev = -1; // remember pressed key so we can compare with next pressed key void my_keyboard_handler(void) { signed char key; // poll keyboard, or poll queue filled from interrupt-driven keyboard scanner. /// note - keyboard poll required to handle debounce. key = poll_keyboard(); // key < 0 => no key pressed. // key 0..11 => specific key pressed. switch (kdb_state) { case KBD_STATE_IDLE: if (key >= 0) { kbd_state = KBD_STATE_WAIT_RELEASE; if (key == kbd_prev && kbd_timeout > 0) { // repetition of same key without timeout period. Rotate through accepted keys. kbd_rotate_state = (kbd_rotate_state+1) % strlen(kbd_lookup[key]); kbd_was_rotate = TRUE; // redraw last character on display ] else { kbd_prev = key; kbd_was_rotate = FALSE; kbd_rotate_state = 0; } kbd_timeout = KEY_TIMEOUT; return kbd_lookup[key][kbd_rotate_state]; } return 0; // no key pressed case KDB_STATE_WAIT_RELEASE: // For now - don't support keyboard repeat, so wait for key release // before new presses (same key or other) may be accepted. if (!key) { // finally idle keyboard. Arm for next key press. kbd_state = KBD_STATE_IDLE; } return 0; default: // Invalid keyboard state machine state! kdb_state = KDB_STATE_IDLE; kbd_prev = -1; return 0; } // switch } // my_keyboard_handler() |
Topic | Author | Date |
Ideas for Multi-tap keyboard routine | 01/01/70 00:00 | |
just follow | 01/01/70 00:00 | |
Multi-tap is not too difficult | 01/01/70 00:00 | |
Two-step operation. Keyboard input + post-processing | 01/01/70 00:00 | |
State Machine! | 01/01/70 00:00 | |
Agree 100% | 01/01/70 00:00 | |
Time to code | 01/01/70 00:00 | |
Software Timers! | 01/01/70 00:00 | |
Practical Limits | 01/01/70 00:00 | |
Don't lock up in infinite loops everywhere | 01/01/70 00:00 | |
In the pseudo code... | 01/01/70 00:00 | |
State Machine | 01/01/70 00:00 | |
Divide by 5 | 01/01/70 00:00 | |
Timer resolution | 01/01/70 00:00 | |
State Machine | 01/01/70 00:00 | |
Looks not bad programming practice | 01/01/70 00:00 | |
Using Timer May Still be Possible | 01/01/70 00:00 | |
Done ! | 01/01/70 00:00 | |
Very Cool!!! | 01/01/70 00:00 | |
Compare with zero is better | 01/01/70 00:00 | |
Avoid ISR jitter using timer T1 | 01/01/70 00:00 | |
Code! | 01/01/70 00:00 | |
Thanks Munish...![]() | 01/01/70 00:00 |