|
本帖最后由 niuniu 于 2015-3-25 00:13 編輯
#include "..\include\AT89X52.H"
#include "..\include\rs232.h"
uchar RS232_Rec;
static bit RS232_Rec_flag=0;
static bit RS232_Trn_flag=1;
//----------------------------------------------------------
// 函數(shù)名稱 RS232_Init()
// 函數(shù)功能 串口初始化,設(shè)置默認(rèn)通信速率為9600bps
// 單片機(jī)主振頻率11.0592MHz,主頻為其它值時(shí)
// 通信速率按比例變化。
// 入口參數(shù):無(wú)
// 函數(shù)返回:無(wú)
// 函數(shù)引用:無(wú)
// 變量引用:無(wú)
// 變量修改:TMOD:設(shè)置T1為串口波特率發(fā)生器
// TH1,TL1:設(shè)置波特率為9600bps(以11.0592MHz晶體為基準(zhǔn))
// TR1,RI,TI:啟動(dòng)T2,清除TI、RI標(biāo)志
// REN,SM0,SM1:使能串口接收,1位起始8位數(shù)據(jù)1位停止模式
// ES,EA:使能串口中斷,使能總中斷
// RS232_Trn_flag:設(shè)置發(fā)送完成標(biāo)志
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
// 10/29/2009:格式規(guī)范
//----------------------------------------------------------
void RS232_Init(void)
{
uchar i;
RS232_Trn_flag = 1;
TMOD &= 0x0f;
TMOD |= 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
REN = 1;
SM0 = 0;
SM1 = 1;
RI = 0;
TI = 0;
EA = 1;
ES = 1;
}
//----------------------------------------------------------
// 函數(shù)名稱:RS232_ISR()
// 函數(shù)功能:串口中斷服務(wù)函數(shù)
// 入口參數(shù):無(wú)
// 函數(shù)返回:無(wú)
// 函數(shù)引用:無(wú)
// 變量引用:RI:串口接收標(biāo)志
// SBUF:串口接收緩沖寄存器
// 變量修改:RI,TI:清除TI、RI標(biāo)志
// RS232_Rec:接收串口收到的字節(jié)
// RS232_Rec_flag:設(shè)置成功接收標(biāo)志
// RS232_Trn_flag:設(shè)置發(fā)送完成標(biāo)志
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
// 10/29/2009:格式規(guī)范
//----------------------------------------------------------
void RS232_ISR(void) interrupt 4
{
if(RI)
{
RS232_Rec = SBUF;
RS232_Rec_flag = 1;
}
else RS232_Trn_flag = 1;
RI = 0;
TI = 0;
}
//----------------------------------------------------------
// 函數(shù)名稱:RS232_Tran_Chr(...)
// 函數(shù)功能:串口單個(gè)字符發(fā)送函數(shù)
// 入口參數(shù):chr:待發(fā)送的字符
// 函數(shù)返回:無(wú)
// 函數(shù)引用:無(wú)
// 變量引用:RS232_Trn_flag,自定義串口發(fā)送成功標(biāo)志
// 變量修改:
// SBUF:賦值串口發(fā)送緩沖寄存器
// RS232_Trn_flag:清除自定義串口發(fā)送成功標(biāo)志
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
// 10/29/2009:格式規(guī)范,解決發(fā)送偶爾死循環(huán)不返回問(wèn)題
//----------------------------------------------------------
void RS232_Tran_Chr(uchar chr)
{
uint tryit = 5000;
while((!RS232_Trn_flag) && (tryit--)) ;
RS232_Trn_flag = 0;
SBUF = chr;
}
//----------------------------------------------------------
// 函數(shù)名稱:RS232_Rec_Xmodem()
// 函數(shù)功能:Xmodem協(xié)議接收部分,128字節(jié)緩沖區(qū)
// 入口參數(shù):無(wú)
// 函數(shù)返回:無(wú)
// 函數(shù)引用:RS232_Tran_Chr(...)
// 變量引用:RS232_Rec_flag:串口收到字符的標(biāo)志
// RS232_Rec:串口收到的字符
// Xmodem_Buffer[]:Xmodem接收緩沖區(qū)
// Xmodem_Buffer_Ptr:Xmodem緩沖區(qū)指針
// 變量修改:RS232_Rec_flag:串口收到字符的標(biāo)志
// Xmodem_Buffer_Ptr:Xmodem緩沖區(qū)指針
// Xmodem_Buffer[]:環(huán)形緩沖區(qū)
// 函數(shù)作者:周大茍
// 創(chuàng)建時(shí)間:10/01/2009
// 修改歷程:10/01/2009:創(chuàng)建本函數(shù)
// 10/29/2009:格式規(guī)范
// 11/09/2009:修改原因:在包頭部分發(fā)現(xiàn)錯(cuò)誤,不應(yīng)該立即發(fā)NAK,而是應(yīng)該等這個(gè)包收完了再發(fā)NAK
// 即將修改:接收過(guò)程中應(yīng)做延時(shí)檢查,防止斷線進(jìn)入死循環(huán)。
//----------------------------------------------------------
// #define SOH 0x01
// #define STX 0x02
// #define EOT 0x04
// #define ACK 0x06
// #define NAK 0x15
// #define CAN 0x18
// #define CTRLZ 0x1A
//enum TXmoden_STate {IDLE, WSTART, START, SEQ, CSEQ, DATA, DEND};
enum TXmoden_STate Xmoden_STate = IDLE;
xdata uchar Xmodem_Buffer[128];
uchar Xmodem_Buffer_Ptr=0;
uchar ChkSum=0;
uchar PSer=1, PT=0;
uchar xerror;
void RS232_Rec_Xmodem(void)
{
if(Xmoden_STate == IDLE) return;
if(RS232_Rec_flag)
{
switch(Xmoden_STate)
{
case WSTART: //當(dāng)前正等待接收主機(jī)發(fā)送起始符號(hào)SOH
if(RS232_Rec == SOH) //收到主機(jī)發(fā)送的SOH符號(hào)
{
Xmoden_STate = START; //進(jìn)入"SOH已經(jīng)收到"狀態(tài)
xerror=0;
}
else
if(RS232_Rec == EOT) //收到主機(jī)發(fā)送的EOT符號(hào)
{
RS232_Tran_Chr(ACK);
Xmoden_STate = IDLE; //進(jìn)入"空閑"狀態(tài)
}
break;
case START://SOH已經(jīng)收到,當(dāng)前正等待接收期望的包序列號(hào)
Xmoden_STate = SEQ; //進(jìn)入"序列號(hào)已經(jīng)收到"狀態(tài)
if(RS232_Rec != PSer) //不是期望的包序列號(hào)
xerror=1; //設(shè)置出錯(cuò)標(biāo)志
break;
case SEQ: //包號(hào)已經(jīng)收到,當(dāng)前正等待接收包號(hào)補(bǔ)碼
Xmoden_STate = CSEQ; //進(jìn)入"包號(hào)補(bǔ)碼已收"狀態(tài)
if(RS232_Rec != (0xff-PSer)) //不是期望的包號(hào)補(bǔ)碼
xerror=1; //設(shè)置出錯(cuò)標(biāo)志
break;
case CSEQ: //包號(hào)補(bǔ)碼已經(jīng)收到,當(dāng)前正等待接收數(shù)據(jù)
Xmodem_Buffer[0] = RS232_Rec;
ChkSum = RS232_Rec;
Xmodem_Buffer_Ptr = 1;
Xmoden_STate = DATA;
break;
case DATA: //當(dāng)前正等待接收數(shù)據(jù)
if(Xmodem_Buffer_Ptr<128)
{
Xmodem_Buffer[Xmodem_Buffer_Ptr++] = RS232_Rec;
ChkSum += RS232_Rec;
if(Xmodem_Buffer_Ptr==128)
Xmoden_STate = DEND;
}
break;
case DEND: //數(shù)據(jù)包接收結(jié)束,當(dāng)前正等待接收校驗(yàn)和
if((ChkSum == RS232_Rec)&&(xerror==0))
{
KS108_Disp_uint_Dec(0,0,PSer,0);
Flash_Write(((ulong)(PSer-1+(PT<<8))<<7), Xmodem_Buffer, 128);
PSer++;
if(PSer==0) PT++;
RS232_Tran_Chr(ACK); //給主機(jī)正確應(yīng)答
Xmoden_STate = WSTART;
}
else
{
RS232_Tran_Chr(NAK); //要求主機(jī)重發(fā)SOH符號(hào)
Xmoden_STate = WSTART;//回到"等待接收SOH"狀態(tài)
}
break;
default:break;
}
RS232_Rec_flag = 0;
}
}
//本函數(shù)的調(diào)用方式如下:
// Xmoden_STate = WSTART;
// RS232_Tran_Chr(NAK);
// while(Xmoden_STate != IDLE) RS232_Rec_Xmodem();
//需要進(jìn)一步完善/優(yōu)化。已經(jīng)成功用于PC--->51單片機(jī)管理下的2M字節(jié)串行Flash芯片AT45DB161D下載16點(diǎn)陣漢字庫(kù)。
//每個(gè)包都人為設(shè)置多個(gè)錯(cuò)誤,測(cè)試通過(guò)
|
|