?? serial.c
字號:
#include "Serial.h"
Packet comm;
//******************數據通訊初始化函數**********************//
//輸入:無
//輸出:無
//說明:初始化包括定時器和中斷的初始化
// 配置為使用定時器1,開串口中斷,允許接收
// 波特率等參數在serial.h中設置,無需改動此函數
//********************************************************//
void Serial_Init()
{
TMOD=0x20;
SCON=0x50;
#ifdef BOUND_RATE_DOUBLE //波特率加倍時的參數
TL1=0;
TH1=256.5-CLK_FRE/(BOUND_RATE*16.0*CLK_DIV);
PCON=0x80;
#else //波特率不加倍時的參數
TL1=0;
TH1=256.5-CLK_FRE/(BOUND_RATE*32.0*CLK_DIV);
PCON=0x00;
#endif
TR1=1;
ES=1;
EA=1;
comm.rflag=COMM_IDLE;
comm.tflag=COMM_IDLE;
comm.time=COMM_TIME;
comm.rcount=0;
comm.tcount=0;
}
//******************數據接收中斷函數**********************//
//輸入:無
//輸出:無
//說明:此函數完成數據的接收和發送功能,無需調用
// 要獲取通訊接收狀態可監視comm.rflag
// COMM_IDLE 0 時為空閑等待狀態
// COMM_ACK 1 時為接收完成
// COMM_REING 2 時為正在接收
// 接收數據將在接收完成后更新,讀取comm,dat[]即可獲取數據
// 要獲取通訊接收狀態可監視comm.tflag
// COMM_IDLE 0 時為空閑等待狀態
// COMM_ACK 1 時為發送完成
// COMM_TEING 2 時為正在發送
// 要發送數據調用Serial_Send()函數
//********************************************************//
void Serial_Int() interrupt 4
{
if (RI)
{
RI=0;
if (comm.rcount>=PACKET_LEN-1) //本次數據包接收完畢
{
uchar i;
comm.dat[PACKET_LEN-1]=SBUF; //保存最后一個接收到的數據
for (i=0;i<PACKET_LEN-1;i++)
{
comm.dat[i]=comm.temp[i]; //轉存以前的接收數據
}
comm.rflag=COMM_ACK; //接收完畢標志
comm.rcount=0; //下次重新開始接收
}
else
{
comm.temp[comm.rcount]=SBUF; //保存接收數據
comm.rcount++;
comm.rflag=COMM_REING; //正在接收標志
comm.time=COMM_TIME; //重置接收計時
}
}
if (TI)
{
TI=0;
if (comm.tcount>=comm.len) //發送完畢
{
comm.tflag=COMM_IDLE;
}
else
{
SBUF=*comm.pdat;
comm.pdat++;
comm.tcount++;
}
}
}
//******************數據接收計時函數**********************//
//輸入:無
//輸出:無
//說明:此函數負責監視一個數據包中各數據的接收,若數據包接收
// 超時則重新啟動數據接收
// 若要使用數據接收監視功能,需在主函數中循環調用此函數
//********************************************************//
void Serial_Timer()
{
if (comm.rflag==COMM_REING)
{
if (comm.time)
{
comm.time--;
}
else
{
comm.rflag=COMM_IDLE;
comm.time=COMM_TIME;
comm.rcount=0;
}
}
}
//******************數據接收狀態函數**********************//
//輸入:無
//輸出:COMM_DATA_NOTRDY 0 數據未準備好,未接收到數據或正在接收
// COMM_DATA_ACK 1 數據接收完成,效驗正確
// COMM_DATA_ERROR 2 數據接收完成,效驗錯誤或無效驗位
//說明:調用此函數后,接收狀態被自動清為空閑(僅對接收完成的狀態)
//********************************************************//
uchar Serial_GetDataState()
{
uchar i,a=0;
if (comm.rflag==COMM_IDLE || comm.rflag==COMM_REING)
return COMM_DATA_NOTRDY;
for (i=0;i<PACKET_LEN-1;i++) //數據效驗,數據包中最后一字節為效驗位,應等于包中其他數據之和(不計溢出)
{
a+=comm.dat[i];
}
if (a==comm.dat[PACKET_LEN-1])
{
comm.rflag=COMM_IDLE;
return COMM_DATA_ACK;
}
else
{
comm.rflag=COMM_IDLE;
return COMM_DATA_ERROR;
}
}
//******************數據發送函數**************************//
//輸入:發送數據緩沖區指針 *pdat
// 發送數據長度 len
//輸出:COMM_SENT_OK 0 數據發送正常
// COMM_SENT_BUSY 1 發送忙,需稍后重發
//說明:此函數將緩沖區內len長度的數據發送出去
//********************************************************//
uchar Serial_Sent(uchar *pdat,uchar len)
{
if (comm.tflag==COMM_TEING)
return COMM_SENT_BUSY;
comm.tflag=COMM_TEING; //開始發送,置標志
comm.len=len;
SBUF=*pdat; //發送第一個數據啟動發送
comm.pdat=pdat+1;
comm.tcount=1;
return COMM_SENT_OK;
}
//*****************帶效驗位生成的數據發送函數*******************//
//輸入:發送數據緩沖區指針 *pdat
// 發送數據長度 len
//輸出:COMM_SENT_OK 0 數據發送正常
// COMM_SENT_BUSY 1 發送忙,需稍后重發
//說明:此函數自動計算效驗位,將其放在緩沖區末端再將數據發送出去
// 總共發送數據長度為len+1
//注: 緩沖區的有效長度應至少為len+1,否則會產生不可知后果
//********************************************************//
uchar Serial_ValidateSent(uchar *pdat,uchar len)
{
uchar i,a=0;
if (comm.tflag==COMM_TEING)
return COMM_SENT_BUSY;
comm.pdat=pdat;
comm.tflag=COMM_TEING; //開始發送,置標志
comm.len=len+1;
for (i=0;i<len;i++)
{
a+=*pdat;
pdat++;
}
*pdat=a;
SBUF=*comm.pdat; //發送第一個數據啟動發送
comm.pdat++;
comm.tcount=1;
return COMM_SENT_OK;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -