萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 安卓開發 >> android平台應用GPIO模擬IR控制車載DTV

android平台應用GPIO模擬IR控制車載DTV

 數字電視—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裡面供上層應用使用。

copyright © 萬盛學電腦網 all rights reserved