⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 红外接收程序.c

📁 红外线—数码管显示数值
💻 C
字号:
/*********************************************
12Mhz 	晶振

**本程序适合32位码遥控器,即16位系统码,16位

数据码,如:57L5,55K2,54B4,KD-29,55K8,5Z26A,

等型号的遥控器,转贴请保持代码的完整性

当有按键时就会产一个9.12ms低电平和4.5ms高电平的起始码,紧接着是16位系统码,
此系统码能区别不同的电器设备,防止不同机种遥控码互相干扰,接下来是8位数据码
和8位数据反码,间隔23ms的高电平后,再发一个与启始码完全一样的结束码 。

以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;
以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”

定时器约定采用方式2自动重载形式。最小定时周期50us,为一个计数单位。
因此:
引导信号:13.5ms相当于270个单位
0: 为22.6个
1: 为45.2个
为了增强抗干扰能力,可以用一个范围来确定某个信号

有效信号一定超过半个脉冲周期即11.3个单位
所以

合法信号范围  【10,280】
引导信号范围  【200,280】
0   信号范围  【10,30】
1   信号范围  【30,60】

利用HS0038B解码。1脚out接20K上拉电阻,2脚接地,3脚串联100欧姆电阻接VCC,3脚对地接4.7us电容。
*********************************************/

#include  "reg51.h"


#define uint unsigned int
#define uchar unsigned char


sbit    IR=P3^3;//红外端口
sbit    lock=P3^2;  

 
unsigned char code zxm[]={0x03,0xf3,0x26,0x62,0xd2,0x4a,0x0a,0xe3,0x02,0x42};
uchar num,n;
uchar key_code=0;//遥控键值
uchar new_code=0;//有无新按键
uchar buf[4];//暂存地址码、 地址反码 、用户码 、用户反码
uchar key_bit_count=0;//键编码脉冲计数
uint  count=0;//定时中断次数计数
uint  buf_count=0;//定时中断计数暂存
uchar common_code_count=0;//前导码脉冲计数
bit   IR_status=0;//脉冲接收器所处的状态,0:无信号,1:系统码接收区
 
char  cnt;

void delay_10us(unsigned char y)///延时子程序10us
  {
    unsigned char x;
    for(x=y;x>0;x--);
  }

void init(void)/////初始化
  {
  IR=1;                //红外端口写1
  
  EA=1;                  //开总中断
  TMOD=0x02;            //定时器0,模式2,8位自动装载模式
  TH0=0Xce;              //定时50us
  TL0=0Xce;

  IT1=1;                //INT1下降沿触发
  ET0=1;                //允许定时器中断
  EX1=1;                //允许外部中断
  }


/***********************************************
  定时器中断

***********************************************/
void time0() interrupt 1///定时器中断
{
    count++;//定时器中断次数累加
}


/**********************************************
  外部中断,红外解码程序
**********************************************/
void int1() interrupt 2///外部中断
{

    TR0=1;//开定时器中断

    if(count>12&&count<280)//信息持续时间超过最小脉宽0.565ms且不大于引导信号9+4.5=13.5ms  如果信号合法,则放入buf_count,count清0,对下一个脉冲信号计时
    {
        buf_count=count;
        count=0;
    }
    delay_10us(10);//延时100us以消除下降沿跳变抖动

    if(IR==0)//INT1引脚稳定为低电平,则表法确实是信号,count重新计时,因上面延时了50us,故要补偿1次TO中断
    {
        count=2;
    }

    if(buf_count>=0&&buf_count<280)//若收到的信号合法,则再进行信号分析
      {

        if(IR_status==0)//如果之前未收到引导码
        {
	        if(buf_count>100&&buf_count<280)//判断是否引导码13.5ms
            {
               IR_status=1;//系统标记
               buf_count=0;//
	           n=0;//buf的角标从0开始
            }
        }
        else if(IR_status==1)///收到引导码
        {
	         if(key_bit_count<32)//收到数据少于32位,则将收到的数据写入buf[]
            {
		        if(buf_count>30&&buf_count<60)
                {
                    buf_count=0;
                    buf[n]>>=1;
                    buf[n]|=0x80;//收到1
                    key_bit_count++;//数据脉冲累加
                }
                else if(buf_count>10&&buf_count<30)//收到0
                {
                    buf_count=0;
                    buf[n]>>=1;//收到0
                    key_bit_count++;

                }

                if(key_bit_count==32)//若收完8位数据则做以下处理
                {
          	    IR_status=0;//接收状态返回到空闲
                    key_bit_count=0;
                    buf_count=0;
                    TR0=0;
                    EX1=0;   //停止外中断
                    new_code=1;
                }
		         n=key_bit_count/8;
             }
         }
     }
}

void disp(unsigned long n)
{
  unsigned  char i=0,t[6]={0};

   while(n)
   {
      t[i++]=n%10;
	  n/=10;
	  if(i>5)
	    break;
   }
   
   for(i=0;i<6;i++)
   {
      SBUF=zxm[t[i]];
	  while(!TI);
	  TI=0;	  
   }

   lock=0;
   lock=1;
}
/*************************************
  主程序
*************************************/
void main()
{
  init();        ///初始化  
   
  disp(0);   
  while(1)
  {

      if(new_code)//判断是否有新按键,如果有则执行下面程序,没有则一直循环
  	  {
 	     new_code=0;
	     //buf[0] 地址码 buf[1] 地址反码 buf[2] 用户码 buf[3] 用户反码

         if(buf[0]==~buf[1] && buf[2]==~buf[3])
	     {
	          
			  if(buf[0]==56)
			  {
			     disp(buf[2]);
			  }
			  
   	     }
	      	 
          EX1=1;   //重新开启外中断
	  }
 }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -