【摘要】 NEC協議是眾多紅外線協議中的一種,以前廣泛用在電視機,投影儀設備里,很早之前經常說的萬能電視遙控器就是NEC協議的;當前文章就介紹如何在Linux下通過紅外線接收模塊,編寫一個NEC協議的紅外線解碼驅動,解析遙控器傳輸過來的各種控制指令,完成對應的動作響應;驅動里用到了外部中斷接收數據,通過定時器計算間隔時間完成解碼。
1. 紅外線知識點介紹
在光譜中波長自760nm至400um的電磁波稱為紅外線,它是一種不可見光。目前幾乎所有的視頻和音頻設備都可以通過紅外遙控的方式進行遙控,比如電視機、空調、影碟機等,都可以見到紅外遙控的影子。這種技術應用廣泛,相應的應用器件都十分廉價,因此紅外遙控是我們日常設備控制的理想方式。
紅外線遙控是目前使用最廣泛的一種通信和遙控手段。由于紅外線遙控裝置具有體積小、功耗低、功能強、
成本低等特點,因而,繼彩電、錄像機之后,在錄音機、音響設備、空凋機以及玩具等其它小型電器裝置上也紛
紛采用紅外線遙控。工業設備中,在高壓、輻射、有毒氣體、粉塵等環境下,采用紅外線遙控不僅完全可靠而且
能有效地隔離電氣干擾。
NEC協議是眾多紅外線協議中的一種,以前廣泛用在電視機,投影儀設備里,很早之前經常說的萬能電視遙控器就是NEC協議的。
當前文章就介紹如何在Linux下通過紅外線接收模塊,編寫一個NEC協議的紅外線解碼驅動,解析遙控器傳輸過來的各種控制指令,完成對應的動作響應;驅動里用到了外部中斷接收數據,通過定時器計算間隔時間完成解碼。
NEC協議的特點如下:
單個碼一共分為5各部分(沒有算重復碼): 引導碼+用戶碼+用戶反碼+按鍵碼+按鍵反碼
對于接收方_引導碼: 9ms的低電平+4.5ms的高電平。
接收的數據是0: 560us低電平+560us高電平
接收的數據是1: 560us低電平+1680us高電平
2. 硬件環境
當前開發板采用友善之臂的Tiny4412,CPU是三星的EXYNOS4412,最高主頻為1.5GHZ,Linux內核版本是3.5。
下面是紅外線接收模塊原理圖:
通過杜邦線接在開發板的中斷輸入腳上:(GPX1_0接口上,第9個排針。)
驅動安裝后,解碼的效果:
3. 案例代碼
驅動代碼思路: 采用外部中斷接收NEC的數據,在工作隊列里完成協議解析,最終通過printk打印出來。
#include
#include
#include
#include
#include
#include
#include
#include
static int irq;
#define NEC_INFRARED_GPIO EXYNOS4_GPX1(0)
static struct work_struct work;
/*獲取高電平持續時間--us單位*/
static u32 GetTimeH(void)
{
ktime_t my_time,my_time2;
unsigned int i,j;
my_time=ktime_get(); //獲取當前時間
i=ktime_to_us(my_time); //轉 us
while(gpio_get_value(NEC_INFRARED_GPIO)){}
my_time2=ktime_get(); //獲取當前時間
j=ktime_to_us(my_time2); //轉 us
return j-i;
}
/*獲取低電平持續時間--us單位*/
static u32 GetTimeL(void)
{
ktime_t my_time,my_time2;
unsigned int i,j;
my_time=ktime_get(); //獲取當前時間
i=ktime_to_us(my_time); //轉 us
while(gpio_get_value(NEC_INFRARED_GPIO)==0){}
my_time2=ktime_get(); //獲取當前時間
j=ktime_to_us(my_time2); //轉 us
return j-i;
}
/*
工作函數
*/
static u8 buf[4];//[0]用戶碼 [1]用戶反碼 [2]按鍵碼 [3]按鍵反碼
static void new_work_func(struct work_struct *work)
{
u8 data=0;
u32 time_us;
/*1. 判斷引導碼*/
time_us=GetTimeL();
if(time_us>12000 || time_us <7000)return; //標準9000
time_us=GetTimeH();
if(time_us>6000 || time_us <3000)return; //標準4500
/*2. 接收32位數據*/
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
time_us=GetTimeL();
if(time_us>700 || time_us <400)return; //標準560
time_us=GetTimeH();
if(time_us<700 && time_us>400) // 0 :標準560
{
data<<=1;
}
else if(time_us<1800 && time_us>1500) // 1 :標準1680
{
data<<=1;
data|=0x01;
}
else
{
return;
}
}
buf[i]=data;
}
printk("用戶碼:%d,按鍵碼:%d\n",buf[0],buf[2]);
}
/*中斷服務函數*/
irqreturn_t nec_irq_handler_func(int irq, void *dev)
{
/*添加工作到工作隊列*/
schedule_work(&work);
return IRQ_HANDLED;
}
static int __init tiny4412_hello_module_init(void)
{
/*初始化工作函數*/
INIT_WORK(&work,new_work_func);
/*1. 獲取中斷號*/
irq=gpio_to_irq(NEC_INFRARED_GPIO);
/*2. 注冊中斷*/
request_irq(irq,nec_irq_handler_func,IRQF_TRIGGER_FALLING,"tinyy412_nec",NULL);
printk("驅動測試: 驅動安裝成功\n");
return 0;
}
static void __exit tiny4412_hello_module_cleanup(void)
{
free_irq(irq,NULL);
printk("驅動測試: 驅動卸載成功\n");
}
module_init(tiny4412_hello_module_init); /*驅動入口--安裝驅動的時候執行*/
module_exit(tiny4412_hello_module_cleanup); /*驅動出口--卸載驅動的時候執行*/
MODULE_LICENSE("GPL"); /*設置模塊的許可證--GPL*/
-
紅外線
+關注
關注
14文章
623瀏覽量
56317 -
NEC
+關注
關注
0文章
238瀏覽量
99165 -
解碼
+關注
關注
0文章
183瀏覽量
27424
發布評論請先 登錄
相關推薦
評論