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()

   }

 }

}

解码程序这个就能实现

那个N大灶困耐于30是尺败因为已经超出了0和1代表的时间长度。0和1所代表的高低电平时间不一样。当高电平时长超过n=8时,代表1否则代表0.这个是和你红外设置的0,1代表时间长度有关系,请隐春问你有时序图吗??那就一目了然了

#include <reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit IRIN = P3^2 //遥控输入脚

sbit BEEP = P3^7 //蜂鸣器

sbit RELAY= P3^6 //继电器

uchar IR_buf[4]={0x00,0x00,0x00,0x00}//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区

// IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区

uchar disp_buf[2]={0x10,0x10} //显示缓冲单元,初值为0x10(即16),指向显示码的第16个"-"

uchar code seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf}

//0~F和"-"符的显示码(字形码)

/********以下是0.14ms的x倍延时函数********/

void delay(uchar x) //延时x*0.14ms

{

uchar i

while(x--)

for (i = 0i<13i++)

}

/********以下是延饥培时函数********/

void Delay_ms(uint xms)

{

uint i,j

for(i=xmsi>0i--) //i=xms即延时约xms毫秒

for(j=110j>0j--)

}

/*********以下是蜂鸣器响一声函数********/

void beep()

{

BEEP=0 //蜂鸣器响

Delay_ms(100)

BEEP=1 //关闭蜂鸣器

Delay_ms(100)

}

/********以下是显示函数********/

void Display()

{

P0=(seg_data[disp_buf[0]])

P2=0x7f

Delay_ms(1)

P0=(seg_data[disp_buf[1]])

P2=0xbf

Delay_ms(1)

}

/前源********以下是主函数********/

main()

{

EA=1EX0=1//允许总中断中断,使能 INT0 外部中断

IT0 = 1 //触发方式为脉冲负边沿触发

IRIN=1 //遥控输入脚置1

BEEP=1RELAY=1 //关闭蜂鸣器和继电器

P0=0xffP2=0xff //P0和P2口置1

Display() //调显示函数

while(1)

{

if(IR_buf[2]==0x02) //02H键(键值码为02H)

RELAY=0 //继电器吸合

if(IR_buf[2]==0x01) // 01H键(键值码为01H)

RELAY=1 //继电器关闭

Display()

}

}

/********以下是外中断0函数********/

void IR_decode() interrupt 0

{

uchar j,k,count=0

EX0 = 0 //暂时关闭外中断0中断请求

delay(20) //延时20*0.14=2.8ms

if (IRIN==1) //等待 IRIN低电平出现

{

EX0 =1 //开外中断0

return //中断返回

}

while (!IRIN) delay(1) //等待IRIN变为高电平,跳过9ms的慧肢态低电平引导码

for (j=0j<4j++) //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码

{

for (k=0k<8k++) //每组数据有8位

{

while (IRIN)//等待IRIN变为低电平,跳过4.5ms的高电平引导码信号。

delay(1)

while (!IRIN) //等待IRIN变为高电平

delay(1)

while (IRIN) //对IRIN高电平时间进行计数

{

delay(1) //延时0.14ms

count++ //对0.14ms延时时间进行计数

if (count>=30)

{

EX0=1 //开外中断0

return //0.14ms计数过长则返回

}

}

IR_buf[j]=IR_buf[j] >>1 //若计数小于6,数据最高位补"0",说明收到的是"0"

if (count>=6) {IR_buf[j] = IR_buf[j] | 0x80} //若计数大于等于6,数据最高位补"1",说明收到的是"1"

count=0 //计数器清0

}

}

if (IR_buf[2]!=~IR_buf[3]) //将键数据反码取反后与键数据码码比较,若不等,表示接收数据错误,放弃

{

EX0=1

return

}

disp_buf[0]=IR_buf[2] &0x0f//取键码的低四位送显示缓冲

disp_buf[1]=IR_buf[2] >>4 //右移4次,高四位变为低四位送显示缓冲

Display() //调显示函数

beep() //蜂鸣器响一声

EX0 = 1 //开外中断0

}


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

原文地址: http://outofmemory.cn/yw/12516569.html

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

发表评论

登录后才能评论

评论列表(0条)

保存