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

来源:互联网 发布:网络咨询医生对话分析 编辑:程序博客网 时间:2024/04/28 20:03

/*
单片机: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

原创粉丝点击