這是本人在外參與的第一個項目,主要負責紅外發(fā)送與接收部分,本程序為接收部分適用于英飛凌單片機XC866-2FR芯片,在和大家分享分享,稍加刪減便可為你所用。#include "MAIN.H"#define State_Free 0 //定義的五種狀態(tài)#define State_Start 1#define State_Data 2#define State_Stop 3#define State_Error 4#define Rx_Lg 13 //定義的最大接收數(shù)據(jù)uword T2_Counter=0; //計算進入定時器T2的中斷次數(shù)ubyte Bit_Counter=0; //接收8bit變量ubyte State=0; //狀態(tài)變量ubyte Date_Rx=0; //數(shù)據(jù)接收變量ubyte Table_Cnt; //接收數(shù)據(jù)個數(shù)變量ubyte Send_Flag=0; //發(fā)送標志位ubyte Free_Error=0; //在空閑狀態(tài)下出錯標志位ubyte Stop_Error=0; //在停止狀態(tài)下出錯標志位ubyte Get_Cnt=0; //通過串口發(fā)送數(shù)據(jù)的個數(shù)變量uword Data_Ch1=0,Data_Ch2=0; ubyte Table_Rx[14]={0}; //接收數(shù)組//****************************************************************************// @Controller Infineon XC866-2FR// @Compiler Keil// @Function T2_vInit(void)// @Description 通過串口發(fā)送數(shù)據(jù)// @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 registerET2 = 1; // Enable interruptTR2 = 1; // start timer} //****************************************************************************// @Controller Infineon XC866-2FR// @Compiler Keil// @Function Send_Data() // @Description 通過串口發(fā)送數(shù)據(jù)// @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_Cnt14;Get_Cnt++) //通過串口,發(fā)送該16個數(shù)據(jù){UART_vSendData8(Table_Rx[Get_Cnt]); //發(fā)送緩沖區(qū)數(shù)據(jù)while(!TI); //等待發(fā)送完成TI=0; //發(fā)送完成,清標志位}Table_Rx[13]=0; }//****************************************************************************// @Controller Infineon XC866-2FR// @Compiler Keil// @Function T2_viTmr(void) // @Description 定時器T2中斷函數(shù),接收紅外發(fā)送的數(shù)據(jù)// @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) //狀態(tài)機{ case State_Free: if((HWRx==0)(Bit_Counter==0)) { if(T2_Counter>15) //判斷時間是否大于164*16us { T2_Counter=0; //是,清零 State=State_Start; //將狀態(tài)轉為開始狀態(tài) } else //否則 { T2_Counter=0; //清零 Free_Error=1; State=State_Error; //將狀態(tài)轉為出錯狀態(tài) } } break; //結束 case State_Start: if((T2_Counter>=2)(HWRx==0) (Bit_Counter==0)) //判斷是否滿足開始狀態(tài) { T2_Counter=0; //滿足,清零 Bit_Counter=8; //賦初值 State=State_Data; //將狀態(tài)轉為數(shù)據(jù)接收狀態(tài) } break; //結束 case State_Data: if((T2_Counter>=5)((Bit_Counter>0) (Bit_Counter=8))) //判斷數(shù)據(jù)是否接收完成 { T2_Counter=0; //沒有,清零計數(shù)變量 Date_Rx>>=1; //左移一位 if(HWRx==1) //判斷是否高電平到來 { Date_Rx|=0x80; //是,將對應位置1 } Bit_Counter--; //減一 if(Bit_Counter==0) //判斷八位數(shù)據(jù)是否接收完成 { State=State_Stop; } }break; case State_Stop: if((T2_Counter>=5)(Bit_Counter==0)) //判斷該 數(shù)據(jù)的8位是否全部接收完,并且檢測到停止位 {T2_Counter=0; //清零if(HWRx==1) //判斷收完數(shù)據(jù)是否HWRx是否被拉高 { Table_Rx[Table_Cnt]=Date_Rx; //暫存該數(shù)據(jù) Date_Rx=0; //清零,防止影響下面的數(shù)據(jù)Table_Cnt++; //接收到數(shù)據(jù)的個數(shù)自加1if(Table_Rx[0]!=0x40) //判斷第一個接收的數(shù)據(jù)是否為0x40,不是則丟棄{Table_Cnt=0;}State=State_Free; //將狀態(tài)轉為空閑狀態(tài) if(Table_Cnt>=Rx_Lg) //判斷16個數(shù)據(jù)是否接收完成{Table_Cnt=0; //是,則清零Send_Flag=1; //置發(fā)送標志位}}else //否則,將進入出錯狀態(tài){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;}} //是,則將狀態(tài)轉為空閑狀態(tài)break; default : State=State_Free; //其它情況均轉為空閑狀態(tài)break; }}}
評論