这是本人在外参与的第一个项目,主要负责红外发送与接收部分,本程序为接收部分适用于英飞凌单片机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;
}
}
}
