分享

单片机红外接受解码程序成功版

 共同成长888 2015-07-18

 1、效果图
    2、发射码格式
    3、
38KH载波发射(完整的发射图)
    4、 
0 与 1的区别
    5、
 载 波
    6、小结
    7、代码 

    


   发射码格式


                            
  38KH载波发射(完整的发射) 



                                                

  0与1的区别




   载 波
                         




                                                小  结
1、发射端发射出来的是高电平。但是接收到的是低电平。(接收到的数据与发射的相反) 

2、我这里用的外部下降沿触发的中断                                                
3、使用12M的晶振完
4、整源码下载地址:http://www./f/hongc.rar

            


                            代码

#include <reg51.h>
sbit IR=P3^2;  //红外接口标志
sbit dm = P2^2; //段码
sbit wm = P2^3; //位码


unsigned char hc[8]; //数码管显示缓存
unsigned char DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
unsigned char WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位码。显示的位置
unsigned char sj[33]; //接收脉冲时间数组
char w=0; //数码管显示缓存指针(0~7)
unsigned char i; //脉冲个数记录
unsigned char mcsj; //脉冲时间(大于0.56ms小于1.125ms为0,大于1.125ms小于2.25ms)
bit MC=0; //接收红外脉冲开始标志(0:脉冲已经结束,1:脉冲刚开始)
bit JS=0; //脉冲接收结束标志位(1标志接收结束)
bit JM=0; //解码完成标志位(1:解码完成)
void Delay(unsigned char f);
void dsq_0() interrupt 1 using 1 //定时器T0中断服务函数
{
mcsj++; //256
}
void wbzd_0() interrupt 0  //外部中断服务函数
{

if(MC)
{
if(mcsj>32) //判断是不是引导码。(如果是i=0)
i=0;
sj[i]=mcsj; //把脉冲时间存入sj这个数组里
mcsj=0; //清空脉冲时间准备接收下一个脉冲时间
i++;
if(i==33) //判断是否接收完脉冲时间
{
i=0;
JS = 1; //接收完成标志位置1
MC=0; //红外脉冲结束
}
}
else
{
MC=1; //红外脉冲开始
mcsj=0; //清空脉冲时间
}
}
void csh_dsq_0() //初始化定时器0
{
TMOD = 0x02;
TH0=0x00; //定时器0的重装数据
TL0=0x00; //初始化
ET0=1; //打开定时器0中断
TR0=1; //启用定时器0
}

void csh_wbzd_0() //初始化外部中断0
{
IT0=1; //外部中断0下降沿触发
EX0=1; //启用外部中断0
EA=1; //打开总中断
}
void hwjm(unsigned char *p) //红外解码函数
{
unsigned char i,j,k=1;
for(i=0;i<4;i++) //4组数据的计数
{
for(j=0;j<8;j++) //每组数据中的8位数据计算
{
p[i] >>= 1; //数据右移一位
if(sj[k]>7) //脉冲时间大于7的就是1
p[i] |= 0x80;
k++;
}
}
JS = 0; //分析完成清零JS
JM = 1; //解码完成JM置1

}
unsigned char xhc(unsigned char *p) //红外按键匹配函数
{
/*
hc[0]=DM[p[1]/16]; //客户码
hc[1]=DM[p[1]%16]; //客户码
hc[2]=0x40;
hc[3]=DM[p[2]/16]; //数据
hc[4]=DM[p[2]%16]; //数据
hc[5]=0x40;
hc[6]=DM[p[3]/16]; //数据反码
hc[7]=DM[p[3]%16]; //数据反码
以上注释的代码是显示
红外解码后的原始数据
*/

switch(p[2]) //匹配按键
{
case 0x16:hc[w]=DM[0];break; //按键0
case 0x0c:hc[w]=DM[1];break; //按键1
case 0x18:hc[w]=DM[2];break; //按键2
case 0x5e:hc[w]=DM[3];break; //按键3
case 0x08:hc[w]=DM[4];break; //按键4
case 0x1c:hc[w]=DM[5];break; //按键5
case 0x5a:hc[w]=DM[6];break; //按键6
case 0x42:hc[w]=DM[7];break; //按键7
case 0x52:hc[w]=DM[8];break; //按键8
case 0x4a:hc[w]=DM[9];break; //按键9
case 0x09: //熄灭所有数码管(清零)
{
hc[0]=0x00; //熄灭所有数码管
w=7; //准备清空数码管显示缓存(不是真的清空)
break;
}
default: return 0; //如果没有匹配的按键就结束函数
}
if(w<7) //数码管显示缓存写入指针不能大于7
{
w++; //显示缓存指针加一
hc[w]=0x00; //设置数码管扫描结束标志
}
else
w=0;//显示缓存指针清零
   JM=0;

}
void Delay(unsigned char f) //延时
{
while(f--);
}
void main()
{
unsigned char k=0; //数码管扫描的位置
unsigned char jmsj[4]; //红外接收解码后的所有数据
csh_dsq_0(); //初始化定时器0
csh_wbzd_0(); //初始化外部中断0
while(1)
{
if(JS) //脉冲接收结束后调用解码函数解码
{hwjm(jmsj);}
if(JM) //解码完成后调用按键匹配函数
{xhc(jmsj);} 
//下面的代码是数码管扫描
P1 = 0; //消影
dm = 1;
dm = 0;

P1 = WM[k]; //写入位码
wm = 1;
wm = 0;

P1 = hc[k]; //写入段码
dm = 1;
dm = 0;
if( k<7 && hc[k]!=0 ) //控制数码管显示的位数
k++;
else
k=0;
Delay(50);
}
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多