记录一次使用NEC协议编码的红外遥控信号的解码方式。
NEC协议简要记录
NEC协议是红外遥控协议的一种,由其编码的数据帧分别由引导码、用户码、用户码(或者是用户码的反码)、数据码(即按键码)和数据码的反码这五部分组成,最后还有一个停止位。引导码表示即将开始传输32位的二进制数据;引导码之后的部分长度为4字节一共32位;第一字节为用户码;第二字节可能是用户码,也可能是用户码的反码,具体由厂商决定;第三字节是当前按键的按键码;第四字节是按键码的反码;停止位主要起隔离作用,一般不进行判断,也不需要理会。每一字节的数据从低位到高位依次发送。
NEC协议编码方式
NEC协议的每一比特数据本身也需要进行编码,编码后再进行载波调制。
引导码:9ms的高电平 + 4.5ms的低电平
比特值0:0.56ms的高电平 + 0.56ms的低电平
比特值1:0.56ms的高电平 + 1.68ms的低电平
发射端和接收端的电平相反,即:
引导码:9ms的低电平 + 4.5ms的高电平
比特值0:0.56ms的低电平 + 0.56ms的高电平
比特值1:0.56ms的低电平 + 1.68ms的高电平
源程序记录
按下红外遥控器的任一按键1~9,即可在开发板的数码管模块的左边第一位上显示对应的按键数字。
- #include<reg51.h>
- sbit OUTPUT=P3^2; //P3.2引脚为单片机外部中断0的触发引脚,同时连接红外接收模块IR 1838的输出端,在模块输出信号的同时进入外部中断0的服务函数
- sbit Wei=P2^7; //数码管模块位锁存
- unsigned char Code[9]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管显示从“1”到“9”的段码
- unsigned char Code0[4];
- unsigned char Code1[33];
- unsigned char time;
- bit m,n; //定义两个标志位;标志位m表示一帧数据解码完毕,标志位n表示一帧数据接收完毕
- void ET_0() interrupt 1 using 1 //定时器0中断
- {
- time++; //对两个下降沿之间的时间间隔进行计数
- }
- void EX_0() interrupt 0 //外部中断0
- {
- static unsigned char i;
- static bit START;
- if(START)
- {
- if(time<63&&time>=33) //引导码,9ms+4.5ms
- {
- i=0;
- }
- Code1[i]=time; //存储两个下降沿之间的时间间隔,将用于数据帧的“0”和“1”
- time=0;
- i++;
- if(i==33)
- {
- n=1;
- i=0;
- }
- }
- else
- {
- time=0;
- START=1;
- }
- }
- void ET0_init() //定时器0中断初始化
- {
- TMOD=0x02; //定时器0工作在方式2
- TH0=0x00; //重载值
- TL0=0x00; //初始值
- ET0=1; //开启定时器0中断
- TR0=1;
- }
- void EX0_init() //外部中断0初始化
- {
- IT0=1; //设置外部中断0为下降沿触发
- EX0=1; //开启外部中断0
- EA=1; //开启总中断
- }
- void DECODE() //红外解码
- {
- unsigned char i,j,k;
- unsigned char x,y;
- k=1;
- for(i=0;i<4;i++) //对数据帧中的4个字节进行处理
- {
- for(j=1;j<=8;j++) //对一个字节中的8位进行处理
- {
- x=Code1[k];
- if(x>7) //时间间隔大于某值则为1,与晶振(12MHz)相关,允许误差
- {
- y|=0x80;
- }
- if(j<8)
- {
- y>>=1;
- }
- k++;
- }
- Code0[i]=y;
- y=0;
- }
- m=1;
- }
- void NUMBER() //将红外遥控器的按键值转换为数码管的段值
- {
- switch(Code0[2])
- {
- case 0x0c:P0=Code[0];break;
- case 0x18:P0=Code[1];break;
- case 0x5e:P0=Code[2];break;
- case 0x08:P0=Code[3];break;
- case 0x1c:P0=Code[4];break;
- case 0x5a:P0=Code[5];break;
- case 0x42:P0=Code[6];break;
- case 0x52:P0=Code[7];break;
- case 0x4a:P0=Code[8];break;
- default:break;
- }
- m=0;
- }
- void main()
- {
- ET0_init();
- EX0_init();
-
- P0=0xfe; //取数码管模块左边第一位选通
- Wei=1;
- Wei=0;
-
- while(1)
- {
- if(n)
- {
- DECODE();
- n=0;
- }
- if(m)
- {
- NUMBER();
- }
- }
- }
复制代码 原理图:
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|