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