?? serial.c
字號(hào):
/*********************************************************************************
* *
* FileName: Serial.c *
* Function: serial port functions *
* SystemName: NDS18000-BSC *
* CPU: ATMEL AT89C52 *
* Startup: 14/Oct/2002 *
* Author: XuYiBo *
* *
*********************************************************************************/
#include <AT89X52.H>
#include <intrins.h>
#include "NDSBSCUI.H"
#include "Serial.h"
#include "General.h"
#include "display.h"
unsigned char idata UART_TransBuffer[UARTBUFFERLEN_TX]; //串口發(fā)送緩沖區(qū)(存放要求收發(fā)信機(jī)應(yīng)答的數(shù)據(jù)幀)
unsigned char idata UART_RcvBuffer[UARTBUFFERLEN_RX];
unsigned char idata *UARTTransHead;
unsigned char idata *UARTTransTail;
unsigned char idata *UARTTransFrame;
unsigned char idata *UARTRcvHead;
unsigned char idata *UARTRcvTail;
unsigned char idata *UARTRcvFrame;
unsigned char data ucAckTimeout; //應(yīng)答計(jì)時(shí)器
unsigned char data ucRcvLen; //幀長度,不包括STX和ETX
unsigned char data ucRcvCheckSum; //用于計(jì)算接收到的數(shù)據(jù)幀的校驗(yàn)和
unsigned char data ucNoAckCount; //重發(fā)次數(shù)
unsigned char bdata SerialFlag;
sbit STXRcvFlag = SerialFlag^0; //TRUE->已經(jīng)接收到STX,允許降數(shù)據(jù)放入接收緩沖區(qū)
sbit EnableTran = SerialFlag^1; //TRUE->允許發(fā)送數(shù)據(jù)
sbit StopTran = SerialFlag^2; //TRUE->已經(jīng)停止發(fā)送數(shù)據(jù)
sbit ConnectFlag= SerialFlag^3; //TRUE->和收發(fā)信機(jī)連接成功,FALSE->和收發(fā)信機(jī)連接失敗;
extern UISema xdata UISemaphore; //define in NDSBSCUI.C
extern UIMemory xdata UIDataArea; //define in NDSBSCUI.C
unsigned char code ucACK[]= {STX,ACK_FRAME,ETX,0};
unsigned char code ucNAK[]= {STX,NAK_FRAME,ETX,0};
unsigned char code ucREQ[]= {STX,REQ_FRAME,ETX,0};
unsigned char code ucUpfreq[]= {STX,COMM_FRAME,UPFREQ_COMM,0};
unsigned char code ucDwnfreq[]= {STX,COMM_FRAME,DWNFREQ_COMM,0};
/******************************************************************************
* *
* Initialize serial receive&transfer function *
* *
******************************************************************************/
void InitSerial(void)
{
UARTTransHead = UART_TransBuffer;
UARTTransTail = UART_TransBuffer;
UARTTransFrame = UART_TransBuffer;
UARTRcvHead = UART_RcvBuffer;
UARTRcvTail = UART_RcvBuffer;
UARTRcvFrame = UART_RcvBuffer;
ucAckTimeout = 0;
ucRcvLen = 0;
ucRcvCheckSum = 0;
ucNoAckCount = 0;
STXRcvFlag = FALSE;
EnableTran = TRUE;
StopTran = TRUE;
ConnectFlag = FALSE;
}
/******************************************************************************
* *
* serial port interrupt handle *
* *
******************************************************************************/
void UART(void) interrupt UARTINT using 1
{
unsigned char ucByte;
unsigned char idata *TmpPtr;
if(RI)
{
ucByte = SBUF;
RI = 0;
if( ucByte == STX)
{
STXRcvFlag = TRUE;
UARTRcvFrame = UARTRcvTail;
*(UARTRcvTail++) = ucByte;
if(UARTRcvTail == UART_RcvBuffer+UARTBUFFERLEN_RX)
{
UARTRcvTail = UART_RcvBuffer;
}
}
else if( STXRcvFlag == TRUE)
{//已經(jīng)收到STX
*(UARTRcvTail++) = ucByte;
if(UARTRcvTail == UART_RcvBuffer+UARTBUFFERLEN_RX)
{
UARTRcvTail = UART_RcvBuffer;
}
if(ucByte==ETX)
{//收完一個(gè)幀
STXRcvFlag = FALSE; //重新搜索STX
}
}
}
if(TI)
{
TI = 0;
if(EnableTran==TRUE)
{
if(UARTTransHead != UARTTransTail)
{
SBUF = *UARTTransHead;
if( *UARTTransHead == STX)
{
UARTTransFrame = UARTTransHead;
}
else if( *UARTTransHead == ETX)
{
TmpPtr = UARTTransFrame;
if(++TmpPtr == UART_TransBuffer+UARTBUFFERLEN_TX)
{
TmpPtr = UART_TransBuffer;
}
if( (*TmpPtr == COMM_FRAME) || (*TmpPtr == REQ_FRAME) )
{//等待收發(fā)信機(jī)應(yīng)答.除命令幀(COMM_FRAME)和REQ幀要求收發(fā)信機(jī)應(yīng)答外,其它幀不要求收發(fā)信機(jī)應(yīng)答
EnableTran = FALSE;
StopTran = TRUE;
ucAckTimeout= 30;
}
}
if(++UARTTransHead == UART_TransBuffer+UARTBUFFERLEN_TX)
{
UARTTransHead = UART_TransBuffer;
}
}
else
{//transfer buffer empty
StopTran = TRUE;
}
}
}
}
/******************************************************************************
* *
* write data to transfer buffer *
* *
******************************************************************************/
void WriteSerial(unsigned char code *pstr_Sour,unsigned char uclen)
{
unsigned char ucCanWrite;
unsigned char idata *TransPtr;
if(uclen==0) return;
TransPtr = UARTTransTail;
if( UARTTransFrame > TransPtr)
{
ucCanWrite = UARTTransFrame - TransPtr;
}
else
{
ucCanWrite = UARTBUFFERLEN_TX - (TransPtr - UARTTransFrame);
}
if( ucCanWrite != 0)
{
if(ucCanWrite > uclen)
{
ucCanWrite = uclen;
}
if(TransPtr + ucCanWrite > UART_TransBuffer + UARTBUFFERLEN_TX)
{
while( TransPtr != UART_TransBuffer + UARTBUFFERLEN_TX)
{
*(TransPtr++) = *(pstr_Sour++);
ucCanWrite--;
}
TransPtr = UART_TransBuffer;
for(;ucCanWrite!=0;ucCanWrite--)
{
*(TransPtr++) = *(pstr_Sour++);
}
}
else
{
for(;ucCanWrite!=0;ucCanWrite--)
{
*(TransPtr++) = *(pstr_Sour++);
}
}
if(TransPtr == UART_TransBuffer+UARTBUFFERLEN_TX)
{
TransPtr = UART_TransBuffer;
}
UARTTransTail = TransPtr;
}
}
/******************************************************************************
* *
* write a byte to transfer buffer *
* *
******************************************************************************/
void WriteSerialByte(unsigned char ucByte)
{
unsigned char idata *TransPtr;
TransPtr = UARTTransTail;
*TransPtr = ucByte;
if(++TransPtr == UART_TransBuffer+UARTBUFFERLEN_TX)
{
TransPtr = UART_TransBuffer;
}
UARTTransTail = TransPtr;
}
/******************************************************************************
* *
* timer2 interrupt handle *
* *
******************************************************************************/
void Timer2(void) interrupt TIMER2INT using 1
{
unsigned char data ucTmp;
if( ucAckTimeout != 0)
{
if( --ucAckTimeout ==0 )
{//timeout
EnableTran = TRUE;
if( ++ucNoAckCount < MAX_REP)
{
UARTTransHead = UARTTransFrame;
StopTran = FALSE;
TI = 1;
}
else
{//重發(fā)次數(shù)超過“最大允許重發(fā)次數(shù)”
ucTmp = 255;
while( --ucTmp )
{
UISemaphore.ucExamAreaSem = 0x00; //request semaphore
if( UISemaphore.ucExamAreaSem == 0x00)
{
UIDataArea.Exam_Buffer.ConnectFlag = FALSE;
UIDataArea.Exam_Buffer.ExamDirtyFlag = 1;
UISemaphore.ucExamAreaSem = 0xff; //release semaphore
break;
}
UISemaphore.ucExamAreaSem = 0xff; //release semaphore
DelayCycle(16);
}
UISemaphore.ucExamAreaSem = 0xff; //release semaphore
ConnectFlag = FALSE;
UARTTransFrame = UARTTransHead;
ucNoAckCount = 0;
if( UARTTransHead != UARTTransTail )
{
StopTran = FALSE;
TI = 1;
}
else
{
StopTran = TRUE;
}
}
}
}
else if( ( EnableTran==TRUE ) && (StopTran == TRUE) )
{
#ifdef NDS_UI_DEBUG
P3_5 = ~P3_5;
#endif
if (UARTTransHead != UARTTransTail)
{
StopTran = FALSE;
TI = 1;
}
}
TF2 = 0;
}
/******************************************************************************
* *
* 處理串口數(shù)據(jù) *
* *
******************************************************************************/
void ProcSerial(void)
{
unsigned char idata *ip_Tmp;
unsigned char data ucTmp;
#ifdef NDS_UI_DEBUG
P3_2 = ~P3_2;
#endif
if( UARTRcvHead != UARTRcvTail)
{//Receive buffer not empty
#ifdef NDS_UI_DEBUG
P3_3 = ~P3_3;
#endif
ucTmp = *UARTRcvHead;
if(++UARTRcvHead == UART_RcvBuffer+UARTBUFFERLEN_RX)
{
UARTRcvHead = UART_RcvBuffer;
}
if( ucTmp == STX)
{//幀起始標(biāo)志
UARTRcvFrame = UARTRcvHead; //UARTRcvFrame指向STX的下一個(gè)字節(jié),即FRAME_TYPE
ucRcvCheckSum = ucTmp;
ucRcvLen = 1;
}
else
{
ucRcvLen++;
ucRcvCheckSum ^= ucTmp;
if( ucTmp == ETX)
{//幀結(jié)束標(biāo)志
#ifdef NDS_UI_DEBUG
P3_4 = ~P3_4;
#endif
switch(*UARTRcvFrame)
{
case MSG_FRAME:
if(++UARTRcvFrame == UART_RcvBuffer+UARTBUFFERLEN_RX)
{
UARTRcvFrame = UART_RcvBuffer;
}
switch(*UARTRcvFrame)
{
case EXAM_COMM:
#ifdef NDS_UI_DEBUG
P3_4 = ~P3_4;
#endif
if(ucRcvLen != EXAM_COMM_LEN)
{//長度不正確
#ifdef NDS_UI_DEBUG
#ifdef NDS_UI_DEBUG_ENABLEDIS
SetCursorPos(20);
DisplayChar( ((ucRcvLen)>>4)+0x30 );
DisplayChar( ((ucRcvLen)&0x0f)+0x30 );
#endif
#endif
break;
}
ip_Tmp = UARTRcvHead - 3;
if( ip_Tmp < UART_RcvBuffer) ip_Tmp += UARTBUFFERLEN_RX; //指向CHECKSUM
ucTmp = *ip_Tmp;
if( ++ip_Tmp == UART_RcvBuffer+UARTBUFFERLEN_RX)
{
ip_Tmp = UART_RcvBuffer;
}
ucRcvCheckSum ^= ETX^ucTmp^*ip_Tmp;
if(ucTmp>'a')
{
ucTmp -= 'a' +10;
}
else if( ucTmp>'A')
{
ucTmp -= 'A' +10;
}
else
{
ucTmp -= '0';
}
ucTmp <<= 4;
if( *ip_Tmp >= 'a' )
{
ucTmp += *ip_Tmp - 'a' +10;
}
else if( *ip_Tmp >= 'A' )
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -