分享一段M16解红外码的代码

    技术2022-05-12  6

    /*单片机:M16;外部晶体:8M;红外接收采用定时器0和外部中断0配合方式.定时器0用系统时钟256分频.红外协议:引导码-4.5ms低,4.5ms高;长信号为'1',短信号为'0';*/

    #include "iom16v.h"#include "macros.h"

    //***************  位操作宏定义  ********************* #define set_bit(x,y)   (x|=(1<<y))  //将x中的y位置1 #define clr_bit(x,y)    (x&=~(1<<y))  //将x中的y位清0 #define xor_bit(x,y)   (x^=(1<<y))  //将x中的y位取反 #define bit(x)   (1<<x)   //将1左移x位 #define get_bit(x,y)   (x&(1<<y))       //取x中的第y位 //****************************************************

     

    /*---------------------*/ /*  红外接收全局变量   */ /*---------------------*/ unsigned char ray_singal_num=0;                                             //接受信号 unsigned char ray_byte_num=0;                                  unsigned char ray_data_in=0;                                                //ray_data_in为接收的数据 unsigned char ray_symbol=0; unsigned char ray_count_array[8]={0,0,0,0,0,0,0,0};//Bit位数组               unsigned char ray_timer=0;                                                  // unsigned char irda_data[4];            //irda receive buffer unsigned char irda_finish=0;

     

    /******************************************************************** *  函数说明:定时器0初始化程序                                      * ********************************************************************/ void Timer0_init(void)                                                {                                                                          //初始化计时器 TCCR0=0x04;//系统时钟256分频 TCNT0=0x00;//tcnt清零 TIMSK=0x00;//关闭T/C中断屏蔽寄存器                                                              }

    /******************************************************************** *  函数说明:外中断0初始化程序                                      * ********************************************************************/ void int0_init(void)                                                  {                                                                         MCUCR=0x02;//开中断0、下降沿触发脉冲                                  GIFR=0xff;                                                        }

    #pragma interrupt_handler int0_isr:2/******************************************************************** *  函数说明:外中断0中断处理程序                                    * ********************************************************************/void int0_isr(void){ //external interupt on INT0 char temp =0;      ray_timer=TCNT0; //读出计时器的值并重置,为了减小误差,故第一时间读出定时值. TCNT0=0;         temp = TIMSK;  //现场保护                                                          TIMSK = 0;            if (ray_symbol==3)    //头码已接收完成,正接收数据                                                              {         if(TCNT0 < 125)                                   {             ray_count_array[ray_singal_num]=ray_timer;                              ray_singal_num++;                                                     if (ray_singal_num==8)                                              {                                                                          ray_singal_num=0;                                                     ray_judger();     irda_data[ray_byte_num-1]=ray_data_in; //save one byte data.     if (ray_byte_num==4)       //receive finished     {     irda_finish=1;     ray_byte_num=0;     ray_symbol=0;     }                                                     }                                                                                                      }                                                                   else                                                                   {                                                                                                                                               ray_singal_num = 0;      ray_symbol=0;         }                                                                                                                                                    MCUCR = 0X02;              //INT0下降沿触发                                                                           }//end if ray_symbol=3     else if(ray_symbol==0)     //判断头码低电平                                              {                                                                         ray_singal_num = 0;                                                                                                                           MCUCR = 0x03;                        //INT0上升沿触发                            ray_symbol = 1;                                                    }      else if (ray_symbol==1) //判断头码高电平  {   if (ray_timer>125)  //>4ms   {    ray_singal_num = 0;    ray_symbol=2;   }   else    ray_symbol=0;   MCUCR = 0X02;              //INT0下降沿触发      }  else if (ray_symbol==2) //头码判断完成  {   if (ray_timer>125)  //>4ms   {    ray_singal_num = 0;    ray_symbol=3;   }   else     ray_symbol=0;   MCUCR = 0X02;              //INT0下降沿触发  }//else ray_symbol

         TIMSK = temp; }

     

    /******************************************************************** *   函数说明:红外信号处理程序                                      * ********************************************************************/ void ray_judger(void) {          char i=0;      ray_data_in=0;                                  for(i=0;i<8;i++)                                               //加入适当的冗错处理      {          if(ray_count_array[i] < 53)                                //<1.6ms为低电平          {    clr_bit(ray_data_in,i);         }          if(ray_count_array[i] >=53)                                //>1.6ms为高电平          {    set_bit(ray_data_in,i);         }      }             ray_byte_num++;   }

     

    /****************自定义函数********************//*函数名:irda_data_processing                 *//*功能:对接收到的红外数据解包分析             *//*参数:                                       *//*输入:                                       *//*输出:                                       *//**********************************************/void irda_data_processing(){//&&(irda_data[1]==0x0c)  int k;  char irda_flag=0;  if ((irda_data[0]==0x0b)&&(irda_data[1]==0x0c))    //Leader code  {   irda_flag=1;   switch(irda_data[2])   {    case ...     default:      ...   }//end switch  }//end if}

    /*主函数*/void main(void) { int temp,i;     CLI(); //disable all interrupts   port_init(); Uart_Init(); int0_init();                Timer0_init();    // MCUCR = 0x00; SEI(); //re-enable interruptss GICR  = 0x40; //Open external INT0// TIMSK = 0x00; //timer interrupt sources

    /

     while (1)  {

      if (irda_finish==1)  {   irda_finish=0;   irda_data_processing();  }//end if-(irda data process)

     }//end while}//end main


    最新回复(0)