NEC编译码器的设计.docx
《NEC编译码器的设计.docx》由会员分享,可在线阅读,更多相关《NEC编译码器的设计.docx(13页珍藏版)》请在冰豆网上搜索。
NEC编译码器的设计
NEC编译码器的设计
一、摘要
本电路主要运用STC89C52RC单片机、UPD6121G编码集成芯片、VS1838B红外接收集成芯片、共阳极数码管、发光二极管灯等元件。
在发送端用程序已固化好的UPD6121G编码集成芯片来实现NEC的编码并采用38khz红外线发送,在接收端通过STC89C52RC单片机与红外接收集成芯片来实现对NEC的解码过程。
通过不同指令来实现数码管和发光二极管亮与灭的变化。
四、NEC编译码的基本原理及系统功能模块结构图
1、NEC编译码的基本原理:
NEC编码是采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”。
上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。
然后再通过红外发射二极管产生红外线向空间发射。
(1)、发送器及NEC编码
UPD6121G产生的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰。
该芯片的用户识别码固定为十六进制01H;后16位为8位操作码(功能码)及其反码。
UPD6121G最多额128种不同组合的编码。
遥控器在按键按下后,周期性地发出同一种32位二进制码,周期约为108ms。
一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大约在45~63ms之间。
代码格式(以接收代码为准,接收代码与发射代码反向)
①位定义
②单发代码格式:
根据码的格式,应该等待9ms的起始码和4.5ms的结果码完成后才能读码。
(2)、接收器及NEC解码
一体化红外线接收器是一种集红外线接收和放大于一体,不需要任何外接
元件,将其和STC89C52RC单片机的P3.2端口的外部中断0相连将接收到的红外信号通过计数器来计算其脉宽的宽度来分别是接收的数字信号“0”。
还是数字信号“1”,其具体操作过程在C程序中解释,在按下一个键时,单片机会发送一个32位的二进制数,此时我们用unsignedchar型的变量a[4]存储在四个字节的存储空间作为命令来进行设计者的自动控制。
(3)、NEC码波形图
数字信号“0”和数字信号“1”波形图
起始码用户识别码指令码指令反码
一帧数据波形图
2、系统功能模块结构框图
(1)、NEC编码模块结构框图:
(2)、NEC解码模块结构框图:
五、系统电路图及工作原理分析
1、外线接收NEC译码电路模块
此模块由红外接收电路、复位电路、基准时钟电路、单片机单片机数据处理电路和数码管与发光二极管显示电路五大部分组成:
(a)、基准时钟电路:
是采用12MHZ的晶振来提高其稳定性。
在此情况下,单片机的一个机器周期就为1us,也就是说在计数时,1ms时间计数器要计数1000次,这在单片机译码的时候要根据TH0和TL0的值来计算脉宽是否为有效值;
(b)、复位电路:
是在程序跑飞时或者使用者想单片机从第一条指令重新运行时的功能。
其原理就是根据电容的充放电使RST引脚在上电时电容充电使RST处于低电平让单片机复位或者是当按键按下时单片机复位;
(c)、红外接收电路:
是将接收到的红外信号经过整形、放大、滤波送给单片机进行译码;
(d)、单片机数据处理电路:
是译码电路的核心,它将红外接收送来的信号进行识别、处理并存储。
识别过程是通过启动外部中断0和计数器0来辨别脉冲宽度及二进制数据“0”和”1”的。
(e)、数码管与发光二极管显示电路:
此电路是将单片机接收到的数据指令用它来显示查表后的数据。
2、红外线发送NEC编码电路模块
此模块主要是由键盘输入电路、单片机控制编码电路、基准时钟电路、
复位电路和红外二极管发送电路组成
(a)、时钟基准电路:
和接收端一样为单片机提供稳定的工作频率,一般采用12MH的晶振来提高其稳定性。
(b)、单片机控制编码电路:
利用单片机将接收来的键盘输入信号进行识别,通过编写程序使发送端按不同的延时时间取反发送端,从而达到NEC编码的过程。
(c)、键盘输入电路:
是通过6x5的矩阵通过键盘扫描来确定输入值的理论上可以发送30个不同的指令,用来执行不同任务。
(d)、复位电路:
和接收端一样,用于让单片机程序从第一条执行。
(e)、红外二极管发送电路:
是通过控制二极管电压的高低来实现红外发送的,发送的频率为38KHZ的方波,由于发送功率不强所以接收端接收距离在10M左右范围内。
六、NEC编译码程序流程图
1、NEC编码流程图:
2、NEC译码流程图:
七、C程序代码及注释
#include
#defineucharunsignedchar
#defineuintunsignedint
Uintcodetable[21]=
{
0x77,0x7c,0x39,0x5e,0x79,0x71,0x5e,0x79,0x71,0x3f,0x39,
0x5e,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};//共阳极数码管相对应的十六进制值
uchara[4]={0,0,0,0},j,i,k,num;//定义变量
sbitjs=P3^2;//红外接收端
sbithd=P2^3;//红色二极管控制端
sbityd=P2^4;//蓝色二极管控制端
delay(uintz)//延时子程序
{
uintx;
for(x=z;x>0;x--);
}
voidmain()
{
EA=1;//初始化
ET0=1;//开计数中断0
EX0=1;//开外部中断0
TMOD=1;//设置工作方式
IT0=1;//启动计时器
while
(1)
{
if((a[2]+a[3])==0xff)//判断接收到数据是否正确
switch(a[2])//将接受到的数据与所建表一一对应
{
case0x00:
num=1;break;
case0x01:
num=2;break;
case0x02:
num=3;break;
case0x04:
num=4;break;
case0x05:
num=5;break;
case0x06:
num=6;break;
case0x08:
num=7;break;
case0x09:
num=8;break;
case0x0a:
num=9;break;
case0x0c:
num=10;break;
case0x0d:
num=11;break;
case0x0e:
num=12;break;
case0x10:
num=13;break;
case0x11:
num=14;break;
case0x12:
num=15;break;
case0x14:
num=16;break;
case0x15:
num=17;break;
case0x16:
num=18;break;
case0x18:
num=19;break;
case0x19:
num=20;break;
case0x1a:
num=21;break;
}
P0=table[num-1];//输出显示值
if(num==1)//判断按键值是否为第一个按键如果是就熄灭蓝灯
hd=1;
if(num==2)//判断按键值是否为第二个按键如果是就点亮蓝灯
hd=0;
if(num==4)//判断按键值是否为第四个按键如果是就熄灭红灯
yd=1;
if(num==5)//判断按键值是否为第五个按键如果是就点亮红灯
yd=0;
}
}
voidzhd(void)interrupt0//外部中断子程序(译码过程)
{
TH0=0;//计数器清零
TL0=0;
TR0=1;//启动计数器
while(!
js)//等待低电平结束
{
delay(5);
if(TH0>45)//判断低电平是否高于11.52ms如果高于则跳出等待和中断
return;
}
TR0=0;
if(TH0<30)//判断低电平是否低于7.68ms如果低于跳出中断
return;
TH0=0;
TR0=1;
while(js)//等待高电平结束
{
delay(5);
if(TH0>28)//判断高电平是否高于7.168ms如果高于则跳出等待和中断
return;
}
//至此为起始信号检测
TR0=0;
TH0=0;
for(i=0;i<4;i++)//一次锁存红外接收的四个十六进制数到a[4]中
{
for(j=0;j<8;j++)
{
TR0=1;
while(!
js)//判断低电平宽度是否大于3..40ms
{
delay(5);
if(TH0>15)
return;
}
TH0=0;
while(js)//判断高电平是否大于1.012ms如果高于则为接受到1,否则为0
{
delay(5);
if(TH0>15)
return;
}
TR0=0;
CY=0;
k=(k>>1);
if(TH0>4)
k=k+0x80;
TH0=0;
}
a[i]=k;
}
}