同时使用上定时器 跟 外中断 的红外程序,只有解码程序。而且该方式,只能解析 使用不同时间长度代表数据“0”、“1” 的波形(如数据‘1’的时间长度 2倍于数据‘0’的时间)。
解析原理:外部中断接 红外输入,当有 红外信号的时候,该引脚会有波形输入(N多下降沿),触发外部中断,通过记录 每2次中断的时间间隔,可以判断此段时间对应的数据(0/1)。一般“数据”长度为32位数据
注意点:
①初次产生外中断的时候,并无 时间记录,不需要进行时间判断;
②第二次中断与第一次中断 之间 的时间,是 红外的引导码,该时间一般多倍于数据时间(一般为ms级时间);
③第三次中断与第二次中断的时间,即为 第一个数据 的时间;
④第34次中断与第33次中断的时间间隔,即为 第32个数据的时间;
⑤后面 可能存在 停止位,是否存在,由遥控器决定;不过,一般都直接忽略该位,除非该位是由自己制作的遥控器 发出 的校验位;
⑥后面 可能存在 连发码,是否存在,由遥控器决定;
另外:一般红外数据的每个字节都是LSB在前,MSB在后的( 低位先发,高位后发)
软件要处理以下情况:
①干扰的处理,有些红外接收头不仅仅对38KHz频率光有反应,可能对人体红外、日光灯红外一样有反应,那就存在干扰。如果它只产生一次干扰,就会使系统卡在引导码接收阶段;
②引导码时间过短、过长 的处理;
③接收数据位数不足的处理;
④完成32位数据接收后,处理接收烂尾:后面不会有中断(如果需接收停止位、连发码,就增加对应数据长度),需要停止计时。
⑤进行数据校对,一般第一字节跟第二字节互为反码,第三字节跟第四字节互为反码,而且第一字节 代表 一个地址、一个密码,只有地址、密码正确,才能算合法的 *** 作。
这是我参考别人的代码适当修改后,测试可用。
注意:与NEC协议中说明的高低电平是反转的
程序采用计时器,当下降沿到来时,进入外部中断程序interrup 2中,计时器装入值清0,即从0计数到下一个下降沿到来,得到的计数值就是一个“低电平+高电平”的时间,对时间进行判断就可以区分是引导码,数据1或0,还是重复码
没有做抗干扰
#include "reg52h"
sbit ir=P3^3; //红外接收IO口
unsigned char duan,wei,flag,jc,jc1;
unsigned int m,Tc; //12M晶振
#define tmin 13220 //协议中高电平560us平分,提高容限
#define tmax 13780 // 9+45=135 + -280:1322~1378
#define thh 2530 //数据1
#define thl 1970 //225ms 不能大于 重复码9+225=1125 1097~1153
#define tlh 1400 //数据0
#define tll 840 // 112ms
unsigned char dat[4]={0,0,0,0};//接收32为地址和命令码
//数码管显示表
unsigned char code tableduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
unsigned char code tablewei[]= {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
void display();
void main()
{
ir=1;//开外部中断INT1
m=0;
EA=1;
EX1=1;
IT1=1;
ET0=0;//启动定时器0,只做计数不开启中断
TMOD=0x01;
TH0=0;
TL0=0;
TR0=1;
while(1)
{//---只显示了命令码,地址码可自行加入----
duan=flag/16;//得到命令码高4位,16进制显示
wei=6;
display();
duan=flag%16;//低4位
wei=7;
display();
duan=jc%16;//显示引导码获得次数、判断是否检测到引导
wei=0; //码,调试用
display();
duan=jc1%16;//显示接收到数据“1”次数,低四位的数据
wei=1;
display();
}
}
void display()
{
unsigned char i=100;
P2=tableduan[duan];//P2口输出数码管段选数据
P1=tablewei[wei]; //P1的P10~P12 3个IO实现8数码管位选控制
while(i--);
}
void int0() interrupt 2
{
Tc=TH0256+TL0;//得到一个低电平+高电平时序计时值
TH0=0;
TL0=0;//继续下一个计时
if((Tc>tmin)&&(Tc<tmax))
{
m=0;//检测到引导码
jc++; //不用管清零,加满后自动归0
}
if(m<32)
{
if((Tc>thl)&&(Tc<thh))//取码
{
dat[m/8]=(dat[m/8]>>1)|0x80;
m++;
jc1++;
}
else if((Tc>tll) && (Tc<tlh))
{
dat[m/8]=(dat[m/8])>>1;
m++;
}
}
else m=0;//在没接收到引导码的情况下清0,调试用
if(dat[2]==~dat[3])//判断数据是否正确,正确就取出
flag=dat[2];//取码完成后判断读码是否正确
}
我只有51单片机的,给你参考下吧,只需稍作修改(定时器时间设定)就可以的:
//注意,虽然红外编码只有32位,但却有33个编码脉冲,需好好理解
#include<at89x52h>
unsigned char irtime;
unsigned char count;
unsigned char receivedat[32];
unsigned char decodeddat;
unsigned char receiveok;
unsigned char decodingok;
//定时器初始化
void timer0init()
{
TMOD=0x02;//自动重装的方式
TH0=6;
TL0=6;//初始化为6,定时器每次溢出的间隔为025ms
ET0=1;
TR0=1;
}
//外部中断初始化
void ext0init()
{
IT0=1;//下降沿触发
EX0=1;
EA=1;
}
//定时器中断服务程序
void timer0() interrupt 1 using 1
{
irtime++;
}
//外部中断服务程序
void ext0() interrupt 0 using 0
{
if(irtime>=20)//这是45ms+056ms一段
{
count=0;
irtime=0;
}
else
{
receivedat[count]=irtime;//将红外遥控的32位编码存储起来
irtime=0;
count++;
if(count==32)//有32位以后就可以解码了
receiveok=1;//置位接收完成标志位
}
}
//红外解码函数
void decoding()
{
unsigned char i;
unsigned char temp;
temp=0x00;
for(i=0;i<8;i++)
{
if(receivedat[i+16]>=7 && receivedat[i+16]<=11)//只提取8位数据码
temp=temp|0x80;
if(i<7)
temp=temp>>1;//必须移位,因为发送时是低位在前高位在后
}
decodeddat=temp;
decodingok=1;//置位解码完成标志位
}
//主函数
void main()
{
P3_2=1;
P2=0x00;
P0=0xbf;//数码管显示一横
irtime=0;
receiveok=0;
decodingok=0;
//初始化定时器中断和外部中断。
timer0init();
ext0init();
//主循环
while(1)
{
if(receiveok==1)//如果接收完毕
{
decoding();
receiveok=0;
}
if(decodingok==1)//如果解码完毕
{
switch(decodeddat)
{
case 0:P0=0xf9;P1=0xfe;break;//1 显示相应的按键值
case 1:P0=0xa4;P1=0xfd;break;//2
case 2:P0=0xb0;P1=0xfb;break;//3
case 3:P0=0x99;P1=0xf7;break;//4
case 4:P0=0x92;P1=0xef;break;//5
case 5:P0=0x82;P1=0xdf;break;//6
case 6:P0=0xf8;P1=0xbf;break;//7
case 7:P0=0x80;P1=0x7f;break;//8
case 8:P0=0x90;P1=0x00;break;//9
}
decodingok=0;
}
}
}
嗯,有这个想法很不错,我提几个我的思路,你参考下:
一般红外发送与红外接收,它们都是配套的,就是发送的频率必须接收的频率相同,否则接收不成功,我们大都使用的是HT6221,它发送的是38KHz的红外信号频率,接收头也只能接收38KHz频率的信号,那么根据这一点,你首先要看看遥控器的参数,它输出的频率是多少,然后选择红外接收头时就只选择这种频率下的,其他频率的接收头都无效。
有了接收头,接下来你要查看该遥控器发送红外信号的波形图,把波形图中的各种信号弄清楚,它是什么信号。
对红外解码有了基本思路之后,你要用单片机设计程序来解码,使用定时器计算接收信号的时间,外部中断捕捉红外信号的数据段,然后把各种信号在一定的时间范围之内译成数字数据,将这个数据用LCD1602显示出来。
大概思路就这样,不懂的地方可以随时回复我。
希望我的回答能帮助到你。
以上就是关于单片机控制红外遥控编码解码中定时器和外部中断的作用是什么红外遥控编码解码的大致步骤是什么全部的内容,包括:单片机控制红外遥控编码解码中定时器和外部中断的作用是什么红外遥控编码解码的大致步骤是什么、谁能介绍一下红外线解码c51遥控程序、谁有msp430红外遥控解码程序 C语言,最好有详细讲解。。谢了等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)