专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

英飞凌单片机XC866-2FR红外接收程序(状态机)

作者:佚名   来源:本站原创   点击数:  更新时间:2010年11月28日   【字体:

     这是本人在外参与的第一个项目,主要负责红外发送与接收部分,本程序为接收部分适用于英飞凌单片机XC866-2FR芯片,在和大家分享分享,稍加删减便可为你所用。

#include "MAIN.H"

#define State_Free   0    //定义的五种状态
#define State_Start  1
#define State_Data   2
#define State_Stop   3
#define State_Error  4
#define Rx_Lg        13   //定义的最大接收数据


uword T2_Counter=0;    //计算进入定时器T2的中断次数
ubyte Bit_Counter=0;     //接收8bit变量
ubyte State=0;               //状态变量
ubyte Date_Rx=0;         //数据接收变量
ubyte Table_Cnt;          //接收数据个数变量
ubyte Send_Flag=0;     //发送标志位
ubyte Free_Error=0;     //在空闲状态下出错标志位
ubyte Stop_Error=0;     //在停止状态下出错标志位

ubyte Get_Cnt=0;         //通过串口发送数据的个数变量
uword Data_Ch1=0,Data_Ch2=0; 

ubyte Table_Rx[14]={0};   //接收数组


 

//****************************************************************************
// @Controller      Infineon XC866-2FR
// @Compiler       Keil
// @Function       T2_vInit(void)
// @Description   通过串口发送数据
// @Input             无
// @Output          无

// @Auth0r           KEVIN
// @Date             2010-11-25
// @Version        1.0
//****************************************************************************
void T2_vInit(void)
{
        T2_RC2L      =  0x20;           // load timer 2 reload/capture register,   
        T2_RC2H      =  0xEF;         // load timer 2 reload/capture register,   
        T2_T2MOD   =  0x10;         // load timer 2 mode register

        ET2 = 1;                              // Enable interrupt

        TR2 = 1;                              //   start timer

} 
//****************************************************************************
// @Controller    Infineon XC866-2FR
// @Compiler      Keil
// @Function      Send_Data() 
// @Description  通过串口发送数据
// @Input            无
// @Output         无

// @Auth0r          KEVIN

// @Date            2010-11-25
// @Version       1.0
//****************************************************************************
void Send_Data()
{
    Data_Ch1=(Table_Rx[1]-0x30)+(Table_Rx[3]-0x30)*16+(Table_Rx[2]-0x30)

                                 +(Table_Rx[7]-0x30)*4096+(Table_Rx[6]-0x30)*256

                                 +(Table_Rx[5]-0x30)*16+(Table_Rx[4]-0x30);
             Data_Ch2=(Table_Rx[11]-0x30)*4096+(Table_Rx[10]-0x30)*256

                                 +(Table_Rx[9]-0x30)*16+(Table_Rx[8]-0x30);
  
             if(Data_Ch1!=Data_Ch2)
             {
                      Table_Rx[13]=1;
             }

             for(Get_Cnt=0;Get_Cnt<14;Get_Cnt++)            //通过串口,发送该16个数据
             {
                          UART_vSendData8(Table_Rx[Get_Cnt]);           //发送缓冲区数据
                          while(!TI);             //等待发送完成
                          TI=0;              //发送完成,清标志位
            }
           Table_Rx[13]=0; 
}

//****************************************************************************
// @Controller    Infineon XC866-2FR
// @Compiler      Keil
// @Function      T2_viTmr(void) 
// @Description  定时器T2中断函数,接收红外发送的数据
// @Input            无
// @Output         无

// @Auth0r          KEVIN
// @Date             2010-11-25
// @Version        1.0
//****************************************************************************
void T2_viTmr(void) interrupt T2INT
{
         if (TF2)
        {
        TF2 = 0;
        T2_Counter++;
        if(T2_Counter>400)   //防止变量溢出
        {
          T2_Counter=400;
       }
                 switch(State)    //状态机
                 {
          case State_Free:    if((HWRx==0)&&(Bit_Counter==0))
               {
                if(T2_Counter>15)    //判断时间是否大于164*16us
                {
                    T2_Counter=0;    //是,清零  
                    State=State_Start;   //将状态转为开始状态
                }
                else       //否则
                {
                   T2_Counter=0;    //清零 
                   Free_Error=1; 
                   State=State_Error;   //将状态转为出错状态
                } 
              }
               break;        //结束
         case State_Start: if((T2_Counter>=2)&&(HWRx==0)

                &&(Bit_Counter==0)) //判断是否满足开始状态
                         {
                            T2_Counter=0;     //满足,清零
                         Bit_Counter=8;     //赋初值
                         State=State_Data;     //将状态转为数据

                                                                                                        接收状态
                          }
                      break;        //结束

         case State_Data:  if((T2_Counter>=5)&&((Bit_Counter>0)

                 &&(Bit_Counter<=8))) //判断数据是否接收完成
                     {
                        T2_Counter=0;     //没有,清零计数变量
                        Date_Rx>>=1;     //左移一位
                        if(HWRx==1)      //判断是否高电平到来
                        {
                           Date_Rx|=0x80;    //是,将对应位置1
                        }
                        Bit_Counter--;     //减一
                        if(Bit_Counter==0)    //判断八位数据是否

                                                                                                         接收完成
                        {
                           State=State_Stop;
                        }
                      }
                                                     break;

         case State_Stop:   if((T2_Counter>=5)&&(Bit_Counter==0)) //判断该                数据的8位是否全部接收完,并且检测到停止位
                    {
                                                              T2_Counter=0;       //清零
                                                              if(HWRx==1)        //判断收完数据是否

                                                                                             HWRx是否被拉高                    {                
                           Table_Rx[Table_Cnt]=Date_Rx;  

                                                                                    //暂存该数据   
                                                                     Date_Rx=0;       //清零,防止影响

                                                                                                  下面的数据
                                                                    Table_Cnt++;      //接收到数据的个数

                                                                                                  自加1
                                                                    if(Table_Rx[0]!=0x40)    //判断第一个

                                                                         接收的数据是否为0x40,不是则丢弃
                                                                    {
                                                                            Table_Cnt=0;
                                                                     }
                                                                     State=State_Free;     //将状态转为

                                                                                                             空闲状态          
                                                                    if(Table_Cnt>=Rx_Lg)    //判断16个

                                                                                                数据是否接收完成
                                                                   {
                                                                           Table_Cnt=0;     //是,则清零
                                                                           Send_Flag=1;     //置发送标志位
                                                                   }
                                                           }
                                                          else         //否则,将进入出错状态
                                                          {
                                                                    State=State_Error;
                                                                    Stop_Error=1;
                                                          }
        
                                               }
                                              break;          //结束

                  case State_Error:  if(Free_Error==1)       

                                                {
                                                        if(T2_Counter>50)
                                                         {
                                                                  Free_Error=0;
                                                                  State=State_Free;
                                                         }   
                                               }
                                               if(Stop_Error==1)
                                              {
                                                      if(T2_Counter>18)
                                                      {
                                                              Stop_Error=0;
                                                              State=State_Free;
                                                       }
                                               }        //是,则将状态转为空闲状态
                                               break; 

                            default :      State=State_Free;       //其它情况均转为空闲状态
                                                break;       
                }
      }

} 
关闭窗口

相关文章