电工技术基础_电工基础知识_电工之家-电工学习网

欢迎来到电工学习网!

NEC协议红外遥控器

2017-04-15 04:26分类:电工考证知识 阅读:

 

  家电遥控器通讯距离通常央求不高,而红外的本钱比别的无线设备要低的多,所以家电遥控器运用中红外一贯占有着一席之地。遥控器的基带通讯协议很多,大约有几十种,常用的就有ITT协议、NEC协议、Sharp协议、PhilipsRC-5协议、SonySIRC协议等。用的最多的便是NEC协议了,因而咱们KST-51开发板随板的遥控器直接选用NEC协议,咱们这节课也以NEC协议规范来阐明一下。

  NEC协议的数据格式包含了引导码、用户码、用户码(或许用户码反码)、按键键码和键码反码,终究一个接连位,接连位首要起隔绝效果,通常不进行区别,编程时咱们也不予答理。其间数据编码一共是4个字节32位,如图1所示。榜首个字节是用户码,第二个字节或许也是用户码,或许是用户码的反码,详细由出产商挑选,第三个字节便是其时按键的键数据码,而第四个字节是键数据码的反码,可用于对数据的纠错。

NEC协议数据格式

图1NEC协议数据格式

  这个NEC协议,标明数据的办法不像咱们之前学过的比方uart那样直观,而是每一位数据自身也需求进行编码,编码后再进行载波调制。

  引导码:9ms的载波+4.5ms的闲暇。

  比特值“0”:560us的载波+560us的闲暇。

  比特值“1”:560us的载波+1.68ms的闲暇。

  联络图1咱们就能看了解了,最前面黑乎乎的一段,是引导码的9ms载波,紧接着是引导码的4.5ms的闲暇,然后边的数据码,是很多载波和闲暇穿插,它们的长短就由其要传递的详细数据来挑选。咱们的HS0038B这个红外一体化接纳头,当收到有载波的信号的时分,会输出一个低电平,闲暇的时分会输出高电平,咱们用逻辑剖析仪抓出来一个红外按键通过HS0038解码后的图形来了解一下,如图2所示。

红外遥控器按键编码

图2红外遥控器按键编码

  从图上能够看出,先是9ms载波加4.5ms闲暇的初步码,数据码是低位在前,高位在后,数据码榜首个字节是8组560us的载波加560us的闲暇,也便是0x00,第二个字节是8组560us的载波加1.68ms的闲暇,能够看出来是0xFF,这两个字节便是用户码和用户码的反码。按键的键码二进制是0x0B,反码便是0xF3,终究跟了一个560us载波接连位。对于咱们的遥控器来说,纷歧样的按键,便是键码和键码反码的区别,用户码是相同的。这么咱们就能够通过单片机的程序,把其时的按键的键码给解出来。

  咱们前边学习接连的时分,学到51单片机有外部接连0和外部接连1这两个外部接连。咱们的红外接纳引脚接到了P3.3引脚上,这个引脚的第二功用便是外部接连1。在存放器TCON中的bit3和bit2这两位,是和外部接连1有关的两位。其间IE1是外部接连象征位,当外部接连发作后,这一位被主动置1,和守时器接连象征位TF类似,进入接连后会主动清零,也能够软件清零。bit2位是设置外部接连类型的,假定bit2位为0,那么只需P3.3为低电平就能够触发接连,假定bit2位为1,那么P3.3从高电平到低电平的降低沿发作才调够触发接连。此外,外部接连1使能位是EX1。那下面咱们就把程序写出来,运用数码管把遥控器的用户码和键码闪现出来。

  Infrared.c文件首要是用来查看红外通讯的,当发作外部接连后,进入外部接连,通过守时器1守时,首要对引导码区别,然后对数据码的每个位逐位获取凹凸电平的时刻,然后得知每一位是0仍是1,终究把数据码解出来。

/***********************infrared.c文件程序源代码*************************/

#include<reg52.h>

sbitIR_INPUT=P3^3;//红外接纳引脚

bitirflag=0;//红外接纳象征,收到一帧准确数据后置1

unsignedcharircode[4];//红外代码接纳缓冲区

voidInitInfrared(void)//红外功用的初始化函数

{

TMOD&=0x0F;//清零T1的操控位

TMOD|=0x十;//装备T1为办法1

TR1=0;//接连T1计数

ET1=0;//阻遏T1接连

IT1=1;//设置INT1为负边际触发

EX1=1;//使能INT1接连

}

unsignedintGetHighTime(void)//获取高电往常刻

{

TH1=0;//清零T1计数初值

TL1=0;

TR1=1;//主张T1计数

while(IR_INPUT)//红外输入引脚为1时循环查看等候,变为0时则结束本循环

{

if(TH1>=0x40)

{//当T1计数值大于0x4000,即高电平继续时刻跨过约18ms时,

break;//强行退出循环,是为了防止信号反常时,程序假死在这儿。

}

}

TR1=0;//接连T1计数

return(TH1*256+TL1);//回来T1的计数值

}

unsignedintGetLowTime(void)//获取低电往常刻

{

TH1=0;//清零T1计数初值

TL1=0;

TR1=1;//主张T1计数

while(!IR_INPUT)//红外输入引脚为0时循环查看等候,变为1时则结束本循环

{

if(TH1>=0x40)

{//当T1计数值大于0x4000,即低电平继续时刻跨过约18ms时,

break;//强行退出循环,是为了防止信号反常时,程序假死在这儿。

}

}

TR1=0;//接连T1计数

return(TH1*256+TL1);//回来T1的计数值

}

voidEXINT1_ISR()interrupt2//INT1接连效能函数,施行红外接纳及解码

{

unsignedchari,j;

unsignedcharbyt;

unsignedinttime;

//接纳并断定引导码的9ms低电平

time=GetLowTime();

if((time<7833)||(time>8755))//时刻断定方案为8.5~9.5ms,

{//跨过此方案则阐明为误码,直接退出

IE1=0;//退出前清零INT1接连象征

return;

}

//接纳并断定引导码的4.5ms高电平

time=GetHighTime();

if((time<3686)||(time>4608))//时刻断定方案为4.0~5.0ms,

{//跨过此方案则阐明为误码,直接退出

IE1=0;

return;

}

//接纳并断定后续的4字节数据

for(i=0;i<4;i++)//循环接纳4个字节

{

for(j=0;j<8;j++)//循环接纳断定每字节的8个bit

{

//接纳断定每bit的560us低电平

time=GetLowTime();

if((time<313)||(time>718))//时刻断定方案为340~780us,

{//跨过此方案则阐明为误码,直接退出

IE1=0;

return;

}

//接纳每bit高电往常刻,断定该bit的值

time=GetHighTime();

if((time>313)&&(time<718))//时刻断定方案为340~780us,

{//在此方案内阐明该bit值为0

byt>>=1;//因低位在先,所以数据左移,高位为0

}

elseif((time>1345)&&(time<1751))//时刻断定方案为1460~1900us,

{//在此方案内阐明该bit值为1

byt>>=1;//因低位在先,所以数据左移,

byt|=0x80;//高方位1

}

else//不在上述方案内则阐明为误码,直接退出

{

IE1=0;

return;

}

}

ircode[i]=byt;//接纳完一个字节后保存到缓冲区

}

irflag=1;//接纳结束后设置象征

IE1=0;//退出前清零INT1接连象征

}

咱们在阅览这个文件里的代码时,会发现咱们在获取凹凸电往常刻的时分做了超时区别if(TH1>=0x40),这个超时区别一方面是应对空间突发的红外搅扰信号,假定咱们不做超时区别,程序有或许会一贯等候下一个跳变才会接连查看,构成程序假死。别的一个方面,遥控器的单按按键和继续按住按键宣告来的信号是纷歧样的。咱们先来比照一下两种按键办法的信号状况,如图3和4所示。

红外单次按键时序图

图3红外单次按键时序图

红外继续按键时序图

图4红外继续按键时序图

  单次按键的效果3和咱们之前的图2是相同的,这个不需求再阐明。而继续按键,首要会宣告一个和单次按键相同的波形出来,通过大约40ms后,会发作一个9ms载波加2.25ms闲暇,再跟一个接连位的波形,然后只需你还在按住按键,每通过大约96ms就会发作9ms载波加2.25ms闲暇加接连位这么的重复波形。咱们人为按下按键的时分,很难操控按下的时刻,因然后边的很简略呈现这种接连波形,咱们加上超时区别也能够有用的防止进入接连波形的死循环中去。

/***********************main.c文件程序源代码*************************/

#include<reg52.h>

sbitADDR3=P1^3;//LED挑选地址线3

sbitENLED=P1^4;//LED总使能引脚

unsignedcharcodeLedChar[]={//数码管闪现字符改换表

0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,

0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E

};

unsignedcharLedBuff[6]={//数码管闪现缓冲区

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF

};

unsignedcharT0RH=0;//T0重载值的高字节

unsignedcharT0RL=0;//T0重载值的低字节

externbitirflag;

externunsignedcharircode[4];

voidConfigTimer0(unsignedintms);

externvoidInitInfrared(void);

voidmain()

{

P0=0xFF;//P0口初始化

ADDR3=1;//挑选数码管

ENLED=0;//LED总使能

InitInfrared();//初始化红外功用

ConfigTimer0(1);//装备T0守时1ms

EA=1;//开总接连

//PT0=1;//装备T0接连为高优先级

while(1)

{

if(irflag)//接纳到红外数据时改写闪现

{

irflag=0;

LedBuff[5]=LedChar[ircode[0]>>4];//用户码闪现

LedBuff[4]=LedChar[ircode[0]&0x0F];

LedBuff[1]=LedChar[ircode[2]>>4];//键码闪现

LedBuff[0]=LedChar[ircode[2]&0x0F];

}

}

}

voidConfigTimer0(unsignedintms)//T0装备函数

{

unsignedlongtmp;

tmp=1十59200/12;//守时器计数频率

tmp=(tmp*ms)/十00;//核算所需的计数值

tmp=65536-tmp;//核算守时器重载值

tmp=tmp+15;//批改接连照顾延时构成的过失

T0RH=(unsignedchar)(tmp>>8);//守时器重载值拆分为凹凸字节

T0RL=(unsignedchar)tmp;

TMOD&=0xF0;//清零T0的操控位

TMOD|=0x01;//装备T0为办法1

TH0=T0RH;//加载T0重载值

TL0=T0RL;

ET0=1;//使能T0接连

TR0=1;//主张T0

}

voidInterruptTimer0()interrupt1//T0接连效能函数

{

staticunsignedchariled=0;

TH0=T0RH;//守时器从头加载重载值

TL0=T0RL;

//LED数码管动态扫描

P0=0xFF;//封闭悉数段选位,闪现消隐

P1=(P1&0xF8)|iled;//位选索引值赋值到P1口低3位

P0=LedBuff[iled];//相应闪现缓冲区的值赋值到P0口

if(iled<5)//位选索引0-5循环,因有6个数码管

iled++;

else

iled=0;

}

  main.c文件程序的首要功用便是把获取到的红外遥控器的用户码和键码信息,传送到数码管上闪现出来,而且通过守时器0的1ms接连进行数码管的动态改写。不知道咱们通过实验发现没有,当咱们按下遥控器按键的时分,数码管闪现的数字会闪耀,这是啥要素呢?单片机的程序都是次第施行的,一旦咱们按下遥控器按键,咱们的程序就会进入遥控器解码段,而这个解码段的时刻比照长,要几十个毫秒,而咱们的数码管动态改写距离跨过了十ms后就会有闪耀的感触了,因而这个闪耀首要是因为咱们程序施行红外解码时,延误了数码管动态改写构成的。

  怎样处理?前边咱们讲过接连优先级疑问,假定设置了接连优先级,就会发作接连嵌套。接连嵌套的原理,咱们在前边讲接连的时分现已讲过一次了,咱们能够回头再温习一下。那么这个程序中,有2个接连程序,一个是外部接连程序,一个是守时器接连程序。假定设置外部接连优先级比照高的话,因为在外部接连中要接纳红外信号,耗时几十毫秒,会耽搁数码管的动态改写。而在守时器接连程序中,施行时刻只需几十个us,即便进入接连,也不会搅扰到红外信号的正常接纳,因而这个本地咱们把守时器0的接连优先级设置为高优先级。在主程序main函数中,咱们把这句注释掉的程序“//PT0=1;”吊销注释,再编译一下,下载到单片机里,然后再试试发送按键,是不是没有任何闪耀了呢?而接连嵌套的含义也有所领会了吧。

上一篇:逻辑函数持平

下一篇:FPAL根柢构造

相关推荐

电工推荐

    电工技术基础_电工基础知识_电工之家-电工学习网
返回顶部