我只有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;
}
}
}
这是我参考别人的代码适当修改后,测试可用。
注意:与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];//取码完成后判断读码是否正确
}
那个N大于30是因为已经超出了0和1代表的时间长度。0和1所代表的高低电平时间不一样。当高电平时长超过n=8时,代表1否则代表0这个是和你红外设置的0,1代表时间长度有关系,请问你有时序图吗??那就一目了然了
以上就是关于谁有msp430红外遥控解码程序 C语言,最好有详细讲解。。谢了全部的内容,包括:谁有msp430红外遥控解码程序 C语言,最好有详细讲解。。谢了、谁能介绍一下红外线解码c51遥控程序、谁能帮我解释一下这个有关51单片机的红外解码的部分程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)