GPIO 模拟红外发射(NEC)
来源:互联网 发布:mac 下的虚拟机性能差 编辑:程序博客网 时间:2024/06/04 18:20
前段时间做过一个通过gpio口来模拟红外loop out 的功能。整理记录一下.
一.概念和NEC协议:
1.基本概念:
GPIO:General Purpose Input Output (通用输入/输出)详情可查看Kernel 中的 GPIO 定义和控制
NEC:一种红外遥控器传输协议,由NEC开发.
从网上找到的概念图,很形象,借用一下:
红外遥控通常是由发送端和接收端两个部分组成。发送端将要发送的二进制信号编码成一系列的脉冲信号,然后通过红外发射管发射红外信号。
接收端完成对红外信号的接收,放大,整形,并解调出遥控编码脉冲。这个过程如下:
2.NEC协议:
1.从上面图中可以看到 首先发送端是需要发送二进制信号编码,二进制信号编码由 Customer Code (客户码) 和 Data Code (数位码) 两部分构成。
2.一般都采用载波提高红外信频率,提高发射效率,载波频率为38KHZ:
用38KHZ的高频信号去调制然后通过红外二极管发射出去,那么就是在信号高电平期间加载波,
38K调制波形:
3.协议中一个bit的表示:
0:一个560us高电平+560us的低电平 合计 1.12ms
1:一个560us高电平+1690us的低电平 合计 2.25ms
如下图:代表一个1然后紧跟一个0
4.按键一次的NEC波形组成:
一个完整的NEC波形如下,它主要由5个部分组成:前导码(Head Code)+ 客户码(Customer Code)+ 客户反码 + 数位码(Data Code) + 数位反码
前导码也叫引导码 代表一次传输的起始标志:
9ms 高电平+4.5ms 低电平。
完整波形如图:
发的数据是:0x59 + 0xA6 + 0x16 +0xE9
都是从低位开始,后面会详细写发送过程。
5.重复按键NEC波形:
重复按键的引导码如下:
9ms 高电平+2.25ms 低电平。
它是以一个9ms的Head Code + 2.25ms的低电平 + 560us的高电平组成(必须拉高电平以区分2.25ms的低电平结束),
如下图正常发送一次nec之后一直重复:
6.软件解码模式图:
如图中红色箭头所示,这两次的正边沿触发就是引导码的开始与结束位置的时间差值放到寄存器中。
二.GPIO口模拟NEC发射:
通过对IO口的拉高拉低,高低电平产生符合协议的波形,我的实现主函数如下:
void sendkeytodvb(U8 u8key){printk("ir out put key for stb==%x\n",u8key);mdelay(100);U8 u8datOpposite = 0;u8datOpposite=~u8key;sendcarrier(9000,CARRIERNUM1); //delay 9msmdelay(4); //delay 4.5 msudelay(500);sendirbyte(GPIO_IR_HEADER_CODE0);sendirbyte(GPIO_IR_HEADER_CODE1);sendirbyte(u8key);sendirbyte(u8datOpposite);sendcarrier(560,CARRIERNUM2);}
u8key 是需要发送的 数位码,也就是遥控器的键值。延时调用了kernel里面的delay忙延时函数。
以下是需要用到的GPIO口控制接口以及相关宏:
extern void MDrv_GPIO_Set_Low(U8 u8IndexGPIO);extern void MDrv_GPIO_Set_High(U8 u8IndexGPIO);#define GPIO_IR_HEADER_CODE00x08//0x10//0x00 /* Custom 0*/#define GPIO_IR_HEADER_CODE10xF7//0xEF//0xFF /* Custom 1*/#define CARRIERNUM1 90000/264#define CARRIERNUM2 5600/264
高电平需要38KHZ载波调制:
void sendcarrier(U32 utime, U32 unum){U32 icount = 0;while (1){if (icount == unum)break;MDrv_GPIO_Set_High(gpioindex);udelay(13);MDrv_GPIO_Set_Low(gpioindex);udelay(13);ndelay(400);icount++;}MDrv_GPIO_Set_Low(gpioindex);}
因为考虑在liunx下对gpio口的操作耗时,想要做到完全和NEC协议一样的精确是很难实现的,细微的偏差是可以的,所以我在icount==unum时就break出来.
通过sendirbyte(...),来发送一个byte:
void sendirbyte(U8 u8keydata){U8 u8Mask = 0x01;while (u8Mask){sendbit(u8keydata & u8Mask);u8Mask <<= 1;}}
通过移位与,从低位开始发送八位二进制:
void sendbit(U8 byte){sendcarrier(560, CARRIERNUM2); //delay 560usudelay(byte == 0x00 ? 560 : 1690);}
高低电平保持时间遵循NEC协议中的0和1的标准。
撰写不易,转载请注明出处 http://blog.csdn.net/jscese/article/details/21398961
- GPIO 模拟红外发射(NEC)
- GPIO模拟红外发射
- 红外遥控系统之二:GPIO模拟红外遥控发射
- 红外发射、接收头(红外基础知识)
- 红外发射、接收头(红外基础知识)
- NEC 红外遥控协议
- NEC红外遥控解码
- NEC 红外遥控协议
- NEC协议红外遥控器
- NEC协议红外解码
- NEC 红外遥控协议
- NEC协议红外遥控器
- NEC 红外遥控
- NEC的红外编码!
- 51单片机模拟红外遥控发射传输温湿度数据
- NEC格式红外解码程序
- 红外遥控协议-NEC协议
- 红外遥控协议-NEC协议
- Android JNI 开发中 C++的输出问题
- 阶段自考之二
- 大数阶乘(nyoj28)
- 解压缩Android 根文件系统 ramdisk
- c中堆和栈的区别(整理别人的资料)
- GPIO 模拟红外发射(NEC)
- 爬虫代理ip设置
- vs 提示图标的含义
- 比较数据库中的日期格式
- cocos2d-x学习笔记——坐标系,锚点,文本类
- Runtime Engine Architecture
- 定点数与浮点数区别
- ORA-19573: cannot obtain exclusive enqueue for datafile 2
- rtc实时时钟