ir remote control 加入 repeat/long key

Posted by: 邱小新 at 下午1:47 in

ir remote control NEC protocol 裏只是提到如何處理一個按鍵的處理。在實際應用上,常常會有遇到按著不放時,要重覆處理這個按鍵,或是按住某個按鍵多久才處理。現在我們就來討論這二個應用方法。

下面主要是用來做一個 buffer,免得 mcu 處理來不急,ir_put 都放在 interrupt 內使用,並沒有給一般常式使用;而 ir_get 只有 ir_process 會用到,但是 counter 跟 ir_put 共用到,所以加上中斷排除,免得發生同時修改的慘況。

#define IR_BUFFER_MAX 4 #define IR_BUFFER_MASK 3 static xdata unsigned char ir_buffer[IR_BUFFER_MAX]; static data unsigned char get_index, put_index, counter; static unsigned char ir_debound, ir_key, ir_repeat_key, ir_long_key; static unsigned char code ir_repeat[] = { IR_UP, IR_DOWN, IR_LEFT, IR_RIGHT }; #define IR_REPEAT_MAX (sizeof(ir_repeat)/sizeof(unsigned char)) static void ir_put(unsigned char value) { if (counter < IR_BUFFER_MAX) { ir_buffer[put_index] = value; counter++; put_index++; put_index &= IR_BUFFER_MASK; } } static unsigned char ir_get(void) { unsigned char value; value = ir_buffer[get_index]; ET0 = LOW; counter --; ET0 = HIGH; get_index++; get_index &= IR_BUFFER_MASK; return value; }

下面是在 interrupt 內會用到 ir_put 的片斷,只有二個地方;一個是輸入 repeat 訊號,一個是輸入按鍵訊號。

if (IS_IR_REPEAT(pulse)) { if (ir_pos == 32) ir_put(IR_REPEAT); return; } if(ir_pos >= 32) { ir_mode = 0; stop_timer(); if ((ir_code[0] | ir_code[1]) != 0xef) return; if ((ir_code[2] | ir_code[3]) != 0xff) return; if (ir_code[0] == 0x40) ir_put(ir_code[2]); }

下面是放在 main loop 裏的函數,ir_function 用來處理按鍵事件,而 ir_process 是用來計算處理 normal,repeat,long 按鍵的函數。

void ir_function(unsigned char key) { switch (key) { default: printf_tiny("ir recv: %x,%d,%d,%d\n\r", ir_key, get_index, put_index, counter); } } void ir_process(void) { unsigned char key; if (counter == 0) { return; } key = ir_get(); switch (key) { case IR_REPEAT: if (ir_debound == 0) { ir_debound++; if (ir_key == IR_LONG_KEY) { ir_long_key = IR_LONG_KEY; break; } for (key=0; key<IR_REPEAT_MAX; key++) { if (ir_key == ir_repeat[key]) break; } if (key < IR_REPEAT_MAX) ir_repeat_key = ir_key; } else if (ir_repeat_key != IR_NONE) { if (ir_debound > IR_REPEAT_COUNT) ir_function(ir_repeat_key); else ir_debound++; } else if (ir_long_key != IR_NONE) { if (ir_debound < IR_LONG_COUNT) { ir_debound++; } else if (ir_debound == IR_LONG_COUNT) { ir_function(ir_long_key); ir_debound++; } } break; default: ir_debound = 0; ir_long_key = IR_NONE; ir_repeat_key = IR_NONE; ir_key = key; if (key != IR_LONG_KEY)&#12288;ir_function(key); } }

1 意見

謝謝你分享IR相關的知識~
請問ir_long_key 與 ir_repeat_key 的差異與用意是如何?

張貼留言