用中断加定时器的红外解码程序

2020-02-04 09:24发布

下面是个用中断加定时器的红外解码程序,但是精度不高,我试了一下,只有75%。我想把它的精度提供一下,可是调了好久都没有调出来,所以就先把程序贴出来,请高手帮忙解答解答了,,
// P3^2接红外接收头,p2^1接蜂鸣器,用于解码正确时叫一下,竞争为12MHz的,
//定时器用的是T1,先谢谢了!!!
//Crystal Frequency=12.000000M
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar wb=0,irr_b=0,p=0;
uint ds=0,a=0;
long da=0,da1=0;
sbit beep=P2^1;
void delay_ms(uchar k)
{
  uchar i,j;
  for (i=k;i>0;i--)
   for (j=121;j>0;j--);
}
void beep_di()
{
  beep=0;
  delay_ms(100);
  beep=1;
}
void ext_int0_isr(void) interrupt 0
{
  a=TH1*256+TL1;               //读取定时器的值
  if(irr_b==0)        //第一个中断
  {
    irr_b=1;          //状态为:开始接收
    TH1=0x00;      //定时器清零
TL1=0x00;
  }
  else if(irr_b==1)   //第二个以后的中断
  {
      //a=TCNT1L;      
   //判断是引导,还是数据
   if((12000<a)&&(a<14500))       //引导
     {
      wb=0;                   //数据计数清零     
   da=0;                   //数据清零
   TH1=0x00;            //定时器清零
   TL1=0x00;
   }
     else if((900<a)&&(a<1800))     //数据0
     {
     wb++;
     da=(da<<1);
  TH1=0x00;
  TL1=0x00;
     }
     else if((1850<a)&&(a<3000))    //数据1
     {
     wb++;
  da=(da<<1)+1;
  TH1=0x00;
  TL1=0x00;
     }
}
if(wb==32)                    //数据长度够32位
  {
    irr_b=0;                    //状态为停止接收
    wb=0;                       //数据计数清零
    p=da;
P0=da;
beep_di();         
   }
}
//*****************************************************************************
void init()
{
     TMOD=0x10;
     ET1=1;
     TR1=1;
     TH1=0;  //9ms
     TL1=0;
     TF1=0;
  EX0=1;
  IT0=1;
     EA=1;
     
}
//*****************************************************************************
void timeout()
{
    ds=TH1*256+TL1;;
if(ds>32000)     //定时器超时,接收复位
   {
      TH1=0;
   TL1=0;
      irr_b=0;
      da=0;
         wb=0;
   p=0;
   }
}
void main()
{
   init();
   while(1)timeout();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
winfuture
2020-02-04 12:35
看看这个吧,12M晶振,兼容性相当好,程序也很简洁。
从串口输出解码数据。
//#include "reg52.h"
#include "W78E516.h"
#include "51delay.h"

//-----------------------管脚定义-------------------------
sbit                                 IR_IO = P3^2;
sbit                                K1 = P3^5;
bit                                flag_IR = 0;        // 红外脉宽记录完成标志
unsigned char         IR_data[4];                // 红外接收数据


//*********************系统初始化****************************************
void mcu_init(void)
{
        TMOD = 0x20;                           // T1定时方式2
//--------------设定波特率------------------------
        TH1 = 0xfd;                                          // 波特率9600 (11.0592M)
        TL1 = 0xfd;
//------------------------------------------------
        SCON = 0x50;                      // 串口方式1
        TR1 = 1;                          // 启动T1
//----------------int0----------------------------
        IT0 = 1;                                                // 下降沿触发
        EX0 = 1;                                                // 允许int0中断
//------------------------------------------------
        EA = 1;                                                // 总中断允许
}

//***************************外部中断0 红外解码*******************************
void int0(void) interrupt 0
{
        unsigned char i,j;
        use_delay_int();

        T_go_H_retx10T(800,IR_IO);         //9ms低电平引导码
        H_go_T_retx10T(IR_IO,120);

        T_go_L_retx10T(410,IR_IO);         //4.5ms高电平引导码
        L_go_T_retx10T(IR_IO,50);

        for( j=0;j<4;j++ )                         //4个数据码
        {
                for( i=0;i<8;i++ )
                {
                        IR_data[j] <<= 1;          // 装入数据
                        H_go_T_retx10T(IR_IO,60);
                        T_go_L_retx10T(40,IR_IO);
                        L_go_T_dealx10T(IR_IO,100) { IR_data[j]++; break; }
                        L_go_T_retx10T(IR_IO,20);
                }
        }
        flag_IR = 1;                           // 置位红外接收成功标志
}          
//****************************主函数**************************************
void main( void )
{
        unsigned char i;
        mcu_init();
        SBUF = 0xDD;
        while( TI == 0 ); TI = 0;
        IR_data = 0;
        while(1)
        {
                if( flag_IR==1 )
                {
                        flag_IR = 0;
                        for(i=0;i<3;i++)
                        {
                                SBUF = IR_data;
                                  while( TI == 0 ); TI = 0;
                                IR_data = 0;
                        }       
                }       
        }               
}


//51delay.h

#define use_delay_char() unsigned char delay_char
#define use_delay_int()  unsigned int  delay_int

#define delay_2T(t)           delay_char=t; while(--delay_char)   // 延时2*i+1个机器周期
#define delay_6T(t)           delay_char=t; while(delay_char--)   // 延时(j+1)*6+1个机器周期
#define T_go_H_retx6T(t,PIN)  delay_char=t; while(--delay_char) if(PIN==1) return
#define T_go_L_retx6T(t,PIN)  delay_char=t; while(--delay_char) if(PIN==0) return
#define H_go_T_retx4T(PIN,t)  delay_char=t; while(!PIN) if((--delay_char)==0) return     
#define L_go_T_retx4T(PIN,t)  delay_char=t; while( PIN) if((--delay_char)==0) return

#define T_go_H_retx10T(t,PIN) delay_int=t; while(--delay_int) if(PIN==1) return
#define T_go_L_retx10T(t,PIN) delay_int=t; while(--delay_int) if(PIN==0) return
#define H_go_T_retx10T(PIN,t) delay_int=t; while(!PIN) if((--delay_int)==0) return     
#define L_go_T_retx10T(PIN,t) delay_int=t; while( PIN) if((--delay_int)==0) return

#define H_go_T_dealx10T(PIN,t) delay_int=t; while(!PIN) if((--delay_int)==0)
#define L_go_T_dealx10T(PIN,t) delay_int=t; while( PIN) if((--delay_int)==0)
#define T_go_H_dealx10T(t,PIN) delay_int=t; while(--delay_int) if(PIN==1)
#define T_go_L_dealx10T(t,PIN) delay_int=t; while(--delay_int) if(PIN==0)

一周热门 更多>