#include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定義頭文件
#define FMBEGIN 0x7e // 幀頭標(biāo)志
unsigned char RecCount; // 串口接收計數(shù)器,全局變量在沒有賦值以前系統(tǒng)默認為0.
unsigned char RecBuf[5]; // 接收緩沖區(qū)(數(shù)據(jù)長度:幀頭+3字節(jié)數(shù)據(jù)+校驗和)
unsigned char SendBuf[5]; // 發(fā)送緩沖區(qū)(數(shù)據(jù)長度:幀頭+3字節(jié)數(shù)據(jù)+校驗和)
/*********************************************/
//描述:串口初始化函數(shù),使用T1方式2自重載方式做波特率發(fā)生器
void UART_init(void)
{
// 下面代碼設(shè)置定時器1
TMOD = 0x20; // 0010 0000 定時器1工作于方式2(8位自動重裝方式)
TH1 = 0xFA; // 波特率:9600 /22.1184MHZ
TL1 = 0xFA; // 波特率:9600 /22.1184MHZ
TR1 = 1;
// 下面代碼設(shè)置定串口
AUXR = 0x00; // 很關(guān)鍵,使用定時器1作為波特率發(fā)生器,S1ST2=0
SCON = 0x50; // 01010 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允許接受)
// 下面代碼設(shè)置中斷
ES = 1; // 關(guān)鍵:開啟了中斷就必須編寫相應(yīng)的中斷函數(shù),哪怕是中斷空函數(shù),
// 但必須有,否則程序進入中斷入口地址后(這里是0023H)不能跳出,必然出錯
EA = 1;
}
/*********************************************/
//發(fā)送一幀完整數(shù)據(jù)
void sendcombytes(unsigned char *ptr, unsigned char len)
{
unsigned char i;
for(i=0;i<len;i++)
{
SBUF=*(ptr+i);
while(TI==0);
TI=0;
}
}
/*********************************************/
// 串口 中斷服務(wù)程序
void UART1(void) interrupt 4
{
if(RI) // 只處理接收中斷
{
if(RecCount==5) RecCount=0; //如果已經(jīng)接收了5個字符,主程序還沒來得及處理又發(fā)來下一幀數(shù)據(jù)
//則RecCount清零,覆蓋上一幀數(shù)據(jù),保證數(shù)據(jù)接收不錯位
RecBuf[RecCount]=SBUF;
RI=0;
if (RecCount==0) // 判斷幀頭是否正確
{
if(RecBuf[RecCount]==FMBEGIN)
{
RecCount++;
}
else
{
RecCount=0;
}
}
else
{
RecCount++;
}
}
}
/*********************************************/
unsigned char CheckSum(unsigned char *ptr, unsigned char len)
{
unsigned char i;
unsigned char a;
unsigned int Value=0;
for(i=0;i<len;i++) // len結(jié)束后第一個字節(jié)為接收到的校驗和
{
Value = Value + ptr;
}
a=Value; // 長送短,傳送完整低字節(jié)
return(a);
}
/*********************************************/
void main(void)
{
unsigned char i;
unsigned char CheckValue; // 校驗結(jié)果
UART_init(); // 串口初始化
while(1)
{
if(RecCount==5) // RecCount是全局變量,表示串口已收到的字節(jié)數(shù)
{
RecCount=0;
CheckValue=CheckSum(RecBuf,4); // 接收緩沖區(qū)4字節(jié)校驗(第5字節(jié)例外)
if(CheckValue==RecBuf[4]) // 如果校驗正確,數(shù)據(jù)加1后發(fā)回。
{
P00=!P00;
SendBuf[0]=FMBEGIN;
for(i=1;i<4;i++) // 1、2、3、4、5字節(jié)中2、3、4為數(shù)據(jù)
{
SendBuf=RecBuf+1;
}
CheckValue=CheckSum(SendBuf,4); // 1、2、3、4 字節(jié)參與校驗
SendBuf[4]=CheckValue;
sendcombytes(SendBuf,5);
}
else // 接收校驗錯誤,發(fā)回幀頭 + 4個aa。
{
SendBuf[0]=FMBEGIN;
for(i=1;i<5;i++) // 1、2、3、4、5字節(jié)中2、3、4、5為數(shù)據(jù)
{
SendBuf=0xaa;
}
sendcombytes(SendBuf,5);
}
}
}
}