51单片机红外解码C程序

51单片机红外解码C程序,第1张

单片机采用外部中断P3.3管脚和红外接收头的搜袜信号线相连,中断方式为边沿触发方式。并用定时器0计算中断的间隔时间,来区分前导码、二进制的“1”、“0”码。并将8位 *** 作码提取出来在数码管上显示。

// 解码值在Im[2]中,当IrOK=1时解码有效。 

/* 51单片机红外遥控解码程序 */

//用遥控器对准红外接收头,按下遥控器按键,在数码管前两位上就会显示对应按键的编码

#include <reg52.h>

#define uchar unsigned char 

sbit dula=P2^6

sbit wela=P2^7

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}

uchar f

#define Imax 14000    //此处为晶振为11.0592时的取值, 

#define Imin 8000    //如用其它频率的晶振时,

#define Inum1 1450    //要改变相应的取乱漏态值。

#define Inum2 700 

#define Inum3 3000

unsigned char Im[4]={0x00,0x00,0x00,0x00}

uchar show[2]={0,0}

unsigned long m,Tc

unsigned char IrOK

void delay(uchar i)

{

  uchar j,k 

  for(j=ij>0j--)

  哗源  for(k=125k>0k--)

}

void display()

{

   dula=0

   P0=table[show[0]]

   dula=1

   dula=0

   wela=0

   P0=0xfe

   wela=1

   wela=0

   delay(5)

   P0=table[show[1]]

   dula=1

   dula=0

   P0=0xfd

   wela=1

   wela=0

   delay(5)

} //外部中断解码程序

void intersvr1(void) interrupt 2 using 1

{

 Tc=TH0*256+TL0                                               //提取中断时间间隔时长

 TH0=0 

    TL0=0              //定时中断重新置零

 if((Tc>Imin)&&(Tc<Imax))

      { 

  m=0

        f=1

  return

      }       //找到启始码

   if(f==1)

      {

        if(Tc>Inum1&&Tc<Inum3) 

    {

   Im[m/8]=Im[m/8]>>1|0x80m++ 

       }

      if(Tc>Inum2&&Tc<Inum1) 

        {

         Im[m/8]=Im[m/8]>>1m++//取码

  }

  if(m==32) 

   {

         m=0  

         f=0

         if(Im[2]==~Im[3]) 

      {

           IrOK=1 

   }

        else IrOK=0   //取码完成后判断读码是否正确

     }

               //准备读下一码

   }

}

/*演示主程序*/

void main(void)

{

    unsigned int  a

 m=0

    f=0

 EA=1

 IT1=1EX1=1

 TMOD=0x11  

 TH0=0TL0=0

 TR0=1//ET0=1

 while(1)

 {

       if(IrOK==1) 

  {

      show[1]=Im[2] &0x0F     //取键码的低四位

           show[0]=Im[2] >>4 

           IrOK=0

  }

           for(a=100a>0a--)

          {

    display()

   }

 }

}

解码程序这个就能实现

这是我参考别人的代码适当修改后,测试可用。

注意:与NEC协议中说明的高低电平是反转的

程序采用计时器,当下降沿到来时,进入外部中断程序interrup 2中,计时器装入值清0,即从0计数到下一个下降沿到来,得到的计数值就是一个“低电平裤谈+高电平”的时间,对时间进行判断就可以区分是引导码,数据1或0,还是重复码

没有做抗干扰

#include "reg52.h"

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+4.5=13.5 + -280:13.22~13.78

#define thh 2530 //数据1

#define thl 1970 //2.25ms 不能大于 重复码9+2.25=11.25 10.97~11.53

#define tlh 1400 //数据0

#define tll 840 // 1.12ms

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=TH0*256+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]//取码完成后判断读码是否正确

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12567117.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存