數字電視—DTV對我們來說早已不是一個新東西,在車載電子上DTV大多是以模塊的形式獨立存在的,是可配的。在車載的市場上,客戶的需求是多種多樣的,如果把DTV也做到車載導航主PCB上去,還是不靈活,不要DTV的就得是不同的PCB板,這對於售後維護、開發都不是一個好辦法。
DTV在家裏,大家一般都是通過遙控器來操作,當然現在有些android的電視盒子可以通過手機來控制,有個泰捷遙控器的apk,通過同一個wifi熱點的電視盒,可以用手機來操作也挺方便。但是在車上,怎麼去操作DTV呢?在小車上,一般空間都是比較狹窄的,使用遙控器是很不方便的,因此我們需要把控制做到導航主控上去。在遙控器的協議中,NEC協議是使用得最普遍的,下面就以NEC協議爲例學習一下使用GPIO模擬IR按鍵消息的方法。
NEC的一條按鍵信息由數據頭、客戶碼、客戶碼反碼、鍵值、鍵值反碼、停止位組成,在此不介紹重複碼。數據頭是一個9ms + 4.5ms的高低組合,後面就是緊跟4個字節的數值,也就是32bit的0、1組合。IR口的gpio口一般是默認是高電平的,解碼驅動大多都是採用下降沿觸發中斷。在此我們主要是要編出一串IR脈衝。組合這一串脈衝的代碼如下:
- gpio_write_one_pin_value(simulate_ir_gpio_hdle, 0, "simulate_ir_gpio");
- Delay10us(900);// 9ms
- gpio_write_one_pin_value(simulate_ir_gpio_hdle, 1, "simulate_ir_gpio");
- Delay10us(450);// 4.5ms
- //IR Customer Code: 0x807f , NEC IR protocol
- SendByteData(0x80); // DVB HEADER_CODE0
- SendByteData(0x7F); // DVB HEADER_CODE1
- SendByteData(IRData);
- SendByteData(~IRData);
- gpio_write_one_pin_value(simulate_ir_gpio_hdle, 0, "simulate_ir_gpio");
- Delay10us(56);
- gpio_write_one_pin_value(simulate_ir_gpio_hdle, 1, "simulate_ir_gpio");
在此有一個問題,就是編這一段脈衝需要50ms以上,標準的一個完整的消息大概是108ms-110ms。這就要求我們在發送4字節數據以及停止碼中間不能被任務調度,因爲任務一調度的話編的碼的寬度就會有很大出入,接收端解析就會認爲是一個錯誤的遙控值。那我們怎麼去盡力保證呢?在linux中有一個spinlock,也就是自旋鎖,一旦獲得這個鎖就可以保證當然執行的進程不被調度搶佔。因此在上面的這段代碼前後加上鎖以及取消鎖操作,筆者在實際操作中,在近百次的操作中,發送IR鍵值的成功率是百分之百。加鎖的相關代碼如下:
- #include <linux/spinlock.h>
- spinlock_t lock;
- spin_lock_init(&lock);
- spin_lock(&lock);
- ////////////////for your process//////////////////
- spin_unlock(&lock);
在android上層,可以通過ioctl來控制,向上層可以封裝在service裏面供上層應用使用。
以上僅供參考。