NEC协议的红外遥控器驱动程序
- 格式:doc
- 大小:117.01 KB
- 文档页数:5
红外遥控协议标准(NEC/RC5/RC5X)及编程目录1.NEC码遥控器技术标准2.RC5/RC5X码遥控器技术标准3.解码原理及算法(NEC)4.实例代码(NEC)1.NEC码遥控器技术标准特点:8位的系统码和8位的命令码长度为了增加可靠性,地址码(即用户码)和命令码都要发送两次脉冲宽度调制载波频率为38K每一位的时间长度为1.12ms或2.25ms其逻辑1与逻辑0的表示如图所示:逻辑1为2.25ms,脉冲时间560us;逻辑0为1.12ms,脉冲时间560us。
所以我们根据脉冲时间长短来解码。
推荐载波占空比为1/3至1/4。
NEC协议格式:首次发送的是9ms的高电平脉冲,其后是4.5ms的低电平,接下来就是8bit 的地址码(从低有效位开始发),而后是8bit的地址码的反码(主要是用于校验是否出错)。
然后是8bit 的命令码(也是从低有效位开始发),而后也是8bit的命令码的反码。
地址和命令发送两次。
第二次发送时,所有的位取反,用来验证第一次发送的消息。
如果开发者不用验证,则可以忽略验证的数据,或者将地址或命令扩展为16bit以上是一个正常的序列,但可能存在一种情况:你一直按着1个键,这样的话发送的是以110ms为周期的重复码,如下图:就是说,发了一次命令码之后,不会再发送命令码,而是每隔110ms时间,发送一段重复码。
重复码由9ms高电平和2.25ms的低电平以及560us的高电平组成。
需要注意的是:1838红外一体接收头为了提高接受灵敏度。
输入高电平,其输出的是相反的低电平。
2、编程注意事项2.1红外接收头引脚信号是相反的电平。
2. 2数据从LSB(低位)开始发送,所以选择右移方式接收数据。
四个字节的数据都是先发送D0,最后发送D7。
所以接收到1位数据后,给变量的最高位赋值,右移。
或者先右移,再给变量的最高位赋值。
2.3.可以用一个数组保存32个数据的持续时间,用于后面判断高低电平。
用定时器对两个数据(中断)之间的时间计时,并保存这个持续时间用于以后判断是位1还是位0。
nec码红外遥控完整编码红外遥控编码程序如下:NEC .SECTION 'DATA'a_REM_CODE DB ? ;KEY DATA CODEa_CUSTOMER_1 DB ? ;遥控器头码(客户码)低八位a_CUSTOMER_2 DB ? ;遥控器头码(客户码)高八位#define CUS_6221_1 00110100b ;1234H#define CUS_6221_2 00010010b ;@------------------------------------------------NEC_CODE .SECTION 'CODE';@************* SUBROUTINE[xx]: Send Remote Code ************;;遥控码发送:SEND_REMOTE_CODE:clr WDT ;清除进位标志,检测遥控发送的有效的按键SZ fg_SendActive ;SZ表示以0结尾的字符串JMP READY_SEND ;跳转到READY_SEND模块retREADY_SEND:NEC_CODE:mov A,a_KEY_NUM ;将数值发送到寄存器A中,直接寻址mov M_TBLP,ATABRDL a_REM_CODE ;查表专用指令;读取遥控头码(客户码)低八位数值 MOV A,CUS_6221_1MOV a_CUSTOMER_1,AMOV A,CUS_6221_2MOV a_CUSTOMER_2,A以上为READY_SEND运行模块,同时是为后面NEC码发送的准备;首先将一个按键的数值已以直接寻址方式发送到寄存器A中,将寄存器A的是发送到M_TBLP 中,然后查表a_REM_CODE,将CUS_6221_1的值发送到寄存器中,在赋值给遥控器头码(客户码)低八位a_CUSTOMER_1,同理,将CUS_6221_2赋值给遥控器头码(客户码)低八位a_CUSTOMER_2,随后即开始发送NEC遥控码。
红外遥控原理与nec协议介绍
红外遥控原理与NEC协议介绍
在现代家居中,我们经常使用的电器设备多数都配备了红外遥控功能,这是一种非常方便的控制方式,它使得我们可以在不接触设备的情况下,方便地控制它们的开关、调节等操作。
那么,红外遥控是如何实现的呢?NEC协议又是什么?
红外遥控原理
红外遥控所用的信号是红外线,光波的频率高于红外线的频率,因此红外线是我们肉眼无法看到的。
当我们按下遥控器上的按钮后,遥控器内部的红外LED会发出一个特定频率的光波,这个光波会通过空气传递到电器设备中的红外接收器(IR Receiver)。
红外接收器会将接
收到的光波转化为电信号,并将其传递给设备的中央处理器,中央处理器便会根据接收到的电信号执行相应的操作。
NEC协议介绍
NEC是红外遥控信号最为常用的协议之一,它是由日本NEC公司开发的。
NEC协议采用了脉冲编码调制技术(Pulse Coded Modulation, PCM),将发送的数据进行脉冲编码,以使接收端可以正确地解码。
NEC
协议的传输速率为38kHz,每个数据包由4个字节组成,其中第一个字节表示设备地址,第二个字节表示设备地址的反码,第三个字节表示数据码,第四个字节表示数据码的反码。
NEC协议可以支持多达256个设备地址,因此可以同时控制多个设备。
总结
红外遥控技术在现代家居中得到广泛应用,它是一种方便、快捷的控制方式,使得我们可以在不接触设备的情况下控制它们。
NEC协议是红外遥控信号最为常用的协议之一,它采用了脉冲编码调制技术,能够支持多达256个设备地址,因此能够满足多设备控制的需求。
基于NEC 标准的主要器件:AT89c51、HS0038HS0038工作频率为38 kHz,能对得到TTL 电平的编码信号,再送给外只有3 个引脚: VS 、GND 和原理:采用 常用电器的NEC 38KHZ (即脉宽调制的方法)信息传给单片机,再通过单片机编码:NEC 标准:用 0.56ms 用0.565ms 高电平+1.685ms 发送的格式:引导码+用户码电平+4.5ms 的低电平组成。
用第二次发送的用户码可为第一次是为了判断发送的信息是否正确注意:上面说的低电平和高电平志。
即低电平期间不发射38KH 间发射38KHZ 的红外波。
标准的红外编码及解码原理及进程0038红外接收头、红外发射管、能对收到遥控信号进行放大、检波、整形、解再送给单片机,经单片机解码并执行相关控制程1个脉冲信号输出引脚,使用方便,性能可EC 标准实现红外编码及解码。
将要发送的通法)的载波发送出去,再由一体化红外接收单片机程序实现解码。
ms 的高低平+0.565ms 的低电平代表数据中5ms 的低电平代表数据中的1。
户码+用户码+操作码+操作反码。
引导码为成。
用户码和操作码均用8位的十六进制发送。
第一次发送用户码的反码,也可不为,发送反码,操作码也一样。
高电平不是实际的电平概念,只是个代表0和38KHZ 的红外波,此时发射管可亮可灭。
高电平 形、解调,制程序,对可靠。
数据通过头接收把中的0,9ms 的高送。
反码主要1的标高电平期发射电路:如上图所示,D1为红外发射管,9014为低噪小功率NPN三极管,R1为10欧姆,R2为50欧姆,为了使发射管发射的距离加长常使R2为零,R1为4.7K欧姆。
功能:优势:通过对NEC标准红外编码的学习,可同时控制多个接收装置而不产生干扰。
因红外发射芯片的地址码为固定的一个,只能控制单独的一个装置或控制相同地址码的装置,且只能控制与遥控器上键数相同的功能,大多数为十多个。
而学习编码的优势是只用一个单片机就能至少有256个地址码(地址码不取反的话地址码将更多),一个地址码有对应的多个受控装置,可见学习红外编码可大大节约资源。
/**************************************************************************** NEC_INF_S.h用于NEC协议的遥控器与51单片机结合的驱动程序,可用任意IO口,不占用中断资源。
用户码8位,分布于2-17个脉冲;按键码8位,分布于18-33个脉冲。
皆为前8原码,后8反码,并且接收数据时低位在前,高位在后。
主控器为51单片机,晶振频率为11.0592MHz。
注意:由于未用中断,所以信号的接收是靠查询方式的,可能会漏掉若干次红外信号。
*****************************************************************************/ #include<reg52.h>#define uchar unsigned char#define uint unsigned int#define N 5000//用于在while()中循环时超时跳出的数的上限,可小刀sbit nec_dat=P3^3;//任意IO口,用到哪个自己改哪个uchar nec_id[2]={0};//遥控器的编码号,第一个为原码,第二个为反码uchar nec_data[2]={0};//遥控器的命令号,第一个为原码,第二个为反码uchar nec_status=0;//遥控器的按键状态信息。
0:无按键;1:一次按键;2:连续按键uchar nec_actflag=0;//用于带到主函数里的按键响应标志。
0:不动作;1:动作#ifndef NEC_INF_S_h#define NEC_INF_S_hvoid nec_init();//初始化函数,注意一定要拉高,拉低就错误了void nec_delay();//延时0.8ms左右,要求要非常精确,这是正确读数的关键void nec_pulsedat();//读第2到第32个脉冲,第一个脉冲已判定void nec_getdat();//扫描式读遥控器的数据,可能有时会扫描不到#endifvoid nec_init()//初始化函数,注意一定要拉高,拉低就错误了{nec_dat=1;}void nec_delay()//延时0.8ms左右,要求要非常精确,这是正确读数的关键{uchar i;for(i=0;i<245;i++);}/*void nec_act()//按键响应程序,根据自己需要写{nec_getdat();//先扫描一遍红外信号if(nec_actflag==1)//如果是正确的红外信号才处理,否则跳过{if(nec_data[0]==~nec_data[1])//验证所接收数据是否正确{switch(nec_data[0])//自己写所需要的程序段{case 69:/*点亮二极管,让蜂鸣器发声,什么都行,写在这里*/ break;case 70: /*以下都一样,对应的遥控器按键见图1-1*/ break;case 71: break;case 68:break;case 64:break;case 67:break;case 7:break;case 21:break;case 9:break;case 22:break;case 25:break;case 13:break;case 12:break;case 24:break;case 94:break;case 8:break;case 28:break;case 90:break;case 66:break;case 82:break;case 74:break;}}nec_actflag=0;}}*/void nec_pulsedat()//读第2到第32个脉冲,第一个脉冲已判定{uchar i=0;uint num=0;for(i=1;i<32;i++){num=0;while((nec_dat==0)&&(num<N))num++;nec_delay();{if((i>=1)&&(i<=7))nec_id[0]=nec_id[0]|(0x01<<i);if((i>=8)&&(i<=15))nec_id[1]=nec_id[1]|(0x01<<(i-8));if((i>=16)&&(i<=23))nec_data[0]=nec_data[0]|(0x01<<(i-16));if((i>=24)&&(i<=31))nec_data[1]=nec_data[1]|(0x01<<(i-24));num=0;while((nec_dat==1)&&(num<N))num++;}else{if((i>=1)&&(i<=7))nec_id[0]=nec_id[0]&(~(0x01<<i));if((i>=8)&&(i<=15))nec_id[1]=nec_id[1]&(~(0x01<<i-8));if((i>=16)&&(i<=23))nec_data[0]=nec_data[0]&(~(0x01<<i-16));if((i>=24)&&(i<=31))nec_data[1]=nec_data[1]&(~(0x01<<i-24));}}}void nec_getdat()//扫描式读遥控器的数据,可能有时会扫描不到{uint num=0;if(nec_dat==1){num=0;while((nec_dat==1)&&(num<N))num++;}nec_delay();if(nec_dat==0){nec_delay();if(nec_dat==0){nec_delay();if(nec_dat==0){nec_delay();if(nec_dat==0){nec_status=1;num=0;while((nec_dat==0)&&(num<N))num++;num=0;while((nec_dat==1)&&(num<N))num++;}}}}if(nec_status==1){num=0;while((nec_dat==0)&&(num<N))num++;if(nec_dat==1){nec_delay();nec_delay();nec_delay();if(nec_dat==1)nec_status=2;else{nec_id[0]=0x01;nec_pulsedat();}}else{nec_id[0]=0x00;nec_pulsedat();}nec_actflag=1;//一次按键的响应程序}if(nec_status==2){//持续按键的响应程序}nec_status=0;//必须归零,非常重要}图1-1 红外遥控器按键对应的接收码图1-2 本程序使用的遥控器注意:本程序适用于NEC协议的红外遥控器,但是每一款遥控器的按键码可能不同,需要自己找到自己手头上遥控器的按键码资料来对程序进行改动。
//---------------------------------------------// NEC红外协议解码模块//---------------------------------------------#include "Infrared_nec_decode.h"/*红外接收端口根据开发板重新设置*//*红外端口根据开发板重新设置*/sbit INFRARED_RECV = P3^2;//红外接收头数据口连接的位置//---------------------------------------------//红外接收初始化//设置定时器0工作方式1 16位定时器//---------------------------------------------void infrared_nec_decode_init(){TMOD &= 0x0f;TMOD |= 0x10;IT1 = 1;EX1 = 1;EA = 1;}//---------------------------------------------// 获取高、低电平的计数值// level为0时获取低电平,1时获取高电平//---------------------------------------------unsigned int infrared_nec_get_count(unsigned level){TH1 = 0;TL1 = 0;TR1 = 1;if(level)while(INFRARED_RECV);elsewhile(!INFRARED_RECV);TR1 = 0;return (TH1 * 256 + TL1);}//---------------------------------------------// 解码NEC协议,将四字节解码结果存入缓冲区// 返回值:0成功,1失败//---------------------------------------------unsigned char infrared_nec_get_code(unsigned char* buf){unsigned int count = 0; //定时器计数unsigned char i, j;//计算是否为引导码count = infrared_nec_get_count(0); //引导脉冲低电平8500~9500usif(count < 7372 || count > 9216)return 1;count = infrared_nec_get_count(1); //引导脉冲高电平4000~5000us if(count < 3686 || count > 4608)return 1;for(i = 0; i < 4; i++) //4个字节{for(j = 0; j < 8; j++) //每个字节8位{count = infrared_nec_get_count(0); //200~800usif(count < 184 || count > 737)return 1;count = infrared_nec_get_count(1); //200~2000usif(count < 184 || count > 1843)return 1;buf[i] >>= 1;if(count > 1032)buf[i] |= 0x80;}}return 0;}。
NEC格式红外发射C程序 C51nec格式红外发射c程序c51//**********************************************////**********nec格式红外遥控发射程序*************////*******************idwrok*******************////************* **20210315_zxq*******************////****20s-m-1s-40eb728d-3s-idwr(40ee6699)******////**********************************************//#inclu de#defineuintunsignedint#defineucharunsignedcharstaticbitopt;sbitir=p3^4;//sbi tkey=p1^7;staticuintcount;staticuintendcount;staticucharflag;staticucharsyscod e_h;staticucharsyscode_l;ucharir_bufdata[4];voidinit(void);voidsend_ir(ucharcustomcode);//voiddelay_ms(uintms);voiddelay_s(uchars);voidmain(void){init();delay_s(20);syscode_l=0xee;send_ir(0x01);delay_s(1);sysc ode_l=0xeb;send_ir(0x72);delay_s(3);syscode_l=0xee;send_ir(0x66);delay_s(17);w hile(1){delay_s(1);syscode_l=0xee;send_ir(0x67);}}//红外发射管的状态十一位0,1//红外升空端口//延时计数器//中止延时计数//红外传送标志//系统码点低8十一位//系统码点高8十一位//遥控代码放置缓冲区//升空数据码//ms延后子程序//s延后子程序//起始//等候开机//系统码设置//传送遥控代码m//系统码设置//传送遥控代码//系统码设置//传送遥控代码idwr//系统码设置//传送遥控代码led提示信息voidtimeint(void)interrupt1{th0=0xff;tl0=0xe6;count++;if(flag==1){opt=~opt;}else{opt=0;}ir=opt;}voidinit(void){count=0;flag=0;opt=0;ir=0;syscode_h=0x40;syscode_l=0xbf;ea=1;tm od=0x01;et0=1;th0=0xff;tl0=0xe6;tr0=1;}voidsend_ir(ucharcustomcode){uinti,j;ir_bufdata[0]=syscode_h;ir_bufdata[1]=sys code_l;ir_bufdata[2]=customcode;ir_bufdata[3]=~customcode;endcount=223;flag=1;count=0;//定时器0中断处理//26us中断一次,频率为38khz//cpu开总中断//设立定时器0为16十一位模式1//定时器0中断容许//26us中断一次频率为38khz//开始计数//syscode数据迁移至ir_bufdata[]内//发送9ms的起始码while(countendcount=117;//传送4.5ms的结果码flag=0;count=0;while(count>1;}}endcount=10;//每个代码传送完后的延时flag=1;count=0;while(countvoiddelay_ms(uintms)//ms延后子程序{for(;ms>0;ms--){flag=0;count=0;while(count<24);}}*/voiddelay_s(uchars){for(;s>0;s--){flag=0;count=0;while(count<27772);}}//1ms//s延后子程序//1s。
nec红外协议NEC红外协议。
NEC红外协议是一种用于红外遥控器通信的协议标准,广泛应用于家电、电子设备等领域。
它采用了38kHz的载波频率,通过调制不同的脉宽来实现数据的传输,具有传输距离远、抗干扰能力强等优点。
本文将对NEC红外协议的原理、格式、编码方式等进行详细介绍,以便对该协议有更深入的了解。
NEC红外协议的原理是通过调制38kHz的载波信号来传输数据。
在NEC协议中,逻辑“0”和逻辑“1”分别用不同的脉宽来表示,通常逻辑“0”用560us的脉宽表示,而逻辑“1”用1690us的脉宽表示。
通过这种方式,接收端可以根据脉宽的不同来解析出发送端发送的数据,从而实现通信的目的。
NEC红外协议的格式通常包括引导脉冲、地址码、反码、命令码等部分。
其中,引导脉冲是一个9ms的高电平脉冲和4.5ms的低电平脉冲交替组成,用于唤醒接收器;地址码用来表示遥控器的地址信息;反码是地址码的反码,用于提高数据传输的可靠性;命令码用来表示具体的操作命令,比如开关机、音量调节等。
通过这样的格式组织,NEC红外协议可以实现对各种遥控器指令的准确传输。
NEC红外协议的编码方式是采用了32位的编码格式,其中包括8位的地址码、8位的地址反码、8位的命令码和8位的命令反码。
这种编码方式可以保证数据的准确性和可靠性,同时也便于接收端对数据进行解析和识别。
通过这种编码方式,NEC红外协议可以实现对各种遥控器指令的精准传输。
总的来说,NEC红外协议作为一种广泛应用的红外遥控器通信协议,具有传输距离远、抗干扰能力强、编码方式简单等优点。
通过对NEC红外协议的原理、格式、编码方式等方面的介绍,相信读者对该协议有了更深入的了解,可以更好地应用于实际的产品开发和设计中。
总结一下,NEC红外协议在红外遥控器通信领域有着重要的地位,其原理简单明了,格式清晰规范,编码方式可靠性高。
相信随着科技的不断发展,NEC红外协议将会有更广泛的应用和发展。
创作编号:BG7531400019813488897SX
创作者:别如克*
是不是觉得红外遥控+51单片机是绝妙组合?但是在编程时才发现超级纠结?其实也没那么纠结,自己摸索摸索,总能找出办法来的。
本程序占用了51单片机的定时器0以及中断1两个资源,为的是使单片机能接收到每一个红外脉冲信号,一个都不能少。
如果舍不得用这两个资源,还有另一种查询的办法,就是不一定每个信号都能收到,可自己琢磨一下。
需要全套NEC协议红外遥控器资料的,到网上找,到处都有,而且很全。
另外,对着资料写程序如果实在写不出,可以找个示波器,把波形录下来好好研究研究。
毕竟有些时候资料会过时,只要里面有一点东西变化了,程序就完全不一样了。
这种弯路,尽量少走。
本程序只是头文件,具体到应用上还要各位自己动脑筋了,希望对大家有所帮助。
共同学习,共同进步!
/******************************************************************
INF_NEC.h
用于NEC协议的遥控器,主控器为51单片机。
用户码8位,分布于2-17个脉冲;按键码8位,分布于18-33个脉冲。
皆为前8原码,后8反码。
注意:本驱动占用51单片机的外部中断1以及定时器0两个资源,编程时注意
不要再乱动这两个资源。
*******************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar nec_flag=0;//nec_flag:遥控码的标志位。
0:无信号;1、2:信号采集;3、可用信号
uchar nec_num=0;//nec_num:红外码的序号
uint nec_time=0;//nec_time:定时器的计时次数nec_time*250us
uchar nec_cod[2]={0,1};//遥控器的编号,编号0为原码,编号1为反码
uchar nec_dat[2]={0,1};//遥控器的数据,数据0为原码,数据1为反码
#ifndef __INF_NEC__
#define __INF_NEC__
extern void nec_init();
extern void nec_act();
#endif
void nec_init() //外中断1及定时器0的初始化函数
{
TMOD=(TMOD&0xf0)|0x02; //定时器0模式2,8位自动重装
TH0=0x19;
TL0=0x19; //11.0592MHz晶振,计数230次,大概时间250us
ET0=1;TR0=0; //定时器0使能,先关着
IT1=1;EX1=1; //外部中断1使能,用来接收红外信号
EA=1; //开总中断
创作编号:BG7531400019813488897SX
创作者:别如克*
}
void nec_act()//按键功能程序
{
if((nec_dat[0]==~nec_dat[1])&&(nec_flag==3))
{
switch(nec_dat[0])
{
case 69: break;
case 70: break;
case 71: break;
case 68:break;
case 64:break;
case 67:break;
case 7:break;
case 21:break;
case 9:break;
case 22:break;
case 25:break;
case 13:break;
case 12:break;
case 24:break;
case 94:break;
case 8:break;
case 28:break;
case 90:break;
case 66:break;
case 82:break;
case 74:break;
}
}
}
void timer0(void) interrupt 1
{
nec_time++;
if(nec_time>1000)//长时间无红外遥控信号时关定时器
{
nec_time=0;nec_num=0;nec_flag=0;TR0=0;
}
}
void exint1(void) interrupt 2
{
uint intime=0;//intime:为了不打扰计时器工作,所以用intime把nec_time提出来intime=nec_time;nec_time=0;//nec_time置0,准备计数
if(nec_num==0)TR0=1;//开定时器,开始计数
if(nec_num==1){if((intime>50)&&(intime<60))nec_flag=1;}
if(nec_num==2){if((intime>2)&&(intime<11))nec_flag=2;}
if(nec_flag==2)
{
if((nec_num>=2)&&(nec_num<=9))
{
if((intime>2)&&(intime<6))nec_cod[0]=nec_cod[0]&~(0x01<<(nec_num-2));
else
if((intime>7)&&(intime<11))nec_cod[0]=nec_cod[0]|(0x01<<(nec_num-2));
}
if((nec_num>=10)&&(nec_num<=17))
{
if((intime>2)&&(intime<6))nec_cod[1]=nec_cod[1]&~(0x01<<(nec_num-10));
else
if((intime>7)&&(intime<11))nec_cod[1]=nec_cod[1]|(0x01<<(nec_num-10));
}
if((nec_num>=18)&&(nec_num<=25))
{
if((intime>2)&&(intime<6))nec_dat[0]=nec_dat[0]&~(0x01<<(nec_num-18));
else
if((intime>7)&&(intime<11))nec_dat[0]=nec_dat[0]|(0x01<<(nec_num-18));
}
创作编号:BG7531400019813488897SX
创作者:别如克*
if((nec_num>=26)&&(nec_num<=33))
{
if((intime>2)&&(intime<6))nec_dat[1]=nec_dat[1]&~(0x01<<(nec_num-26));
else
if((intime>7)&&(intime<11))nec_dat[1]=nec_dat[1]|(0x01<<(nec_num-26));
}
}
nec_num++;if(nec_num>35){nec_num=35;nec_flag=3;}
}
创作编号:BG7531400019813488897SX
创作者:别如克*。