Linux驱动开发-编写NEC红外线协议解码驱动

【摘要】 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 6000 || time_us <3000)return; //标准4500 /*2. 接收32位数据*/ int i,j; for(i=0;i<4;i++) { for(j=0;j700 || time_us <400)return; //标准560 time_us=gettimeh(); if(time_us400) // 0 :标准560 { data<<=1; } else if(time_us1500) // 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*/
共话“AI生态”意义,商汤首届集团生态合作伙伴大会成功举办
AMD推动技术创新 助力高性能算力不断突破
大型语言模型有哪些用途?大型语言模型如何运作呢?
适用PLC使用的步进电机控制驱动器
优步出售自动驾驶部门给竞争对手
Linux驱动开发-编写NEC红外线协议解码驱动
国内半导体材料产业发展正进入黄金时期
中控智慧科技门禁一体机F20plus简介
台积电公布的2020年第二季度财务报告
日本四大摩托车企成立合作联盟 联手推电动两轮车换电模式
C8051F040的车用CAN总线智能节点设计
将异构块添加到固态电解质中的策略
量子货币是怎么一回事
5mm红外线发光二极管 佰鸿红外发射管的常规参数
老龄化社会催生的跌倒检测报警系统的设计
智能语音的落地,分享智能语音的产业观察
执法证据保全系统|智证据DW-S404
如何鉴别轻触开关质量
海拉为新款大众途锐生产LED矩阵头灯
为什么时钟树上要用clock inverter(min pulse width check)?