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