📄 serial.c
字号:
/*********************************************************************************
* *
* 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]; //串口发送缓冲区(存放要求收发信机应答的数据幀)
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; //应答计时器
unsigned char data ucRcvLen; //幀长度,不包括STX和ETX
unsigned char data ucRcvCheckSum; //用于计算接收到的数据幀的校验和
unsigned char data ucNoAckCount; //重发次数
unsigned char bdata SerialFlag;
sbit STXRcvFlag = SerialFlag^0; //TRUE->已经接收到STX,允许降数据放入接收缓冲区
sbit EnableTran = SerialFlag^1; //TRUE->允许发送数据
sbit StopTran = SerialFlag^2; //TRUE->已经停止发送数据
sbit ConnectFlag= SerialFlag^3; //TRUE->和收发信机连接成功,FALSE->和收发信机连接失败;
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)
{//已经收到STX
*(UARTRcvTail++) = ucByte;
if(UARTRcvTail == UART_RcvBuffer+UARTBUFFERLEN_RX)
{
UARTRcvTail = UART_RcvBuffer;
}
if(ucByte==ETX)
{//收完一个幀
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) )
{//等待收发信机应答.除命令幀(COMM_FRAME)和REQ帧要求收发信机应答外,其它帧不要求收发信机应答
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
{//重发次数超过“最大允许重发次数”
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;
}
/******************************************************************************
* *
* 处理串口数据 *
* *
******************************************************************************/
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)
{//帧起始标志
UARTRcvFrame = UARTRcvHead; //UARTRcvFrame指向STX的下一个字节,即FRAME_TYPE
ucRcvCheckSum = ucTmp;
ucRcvLen = 1;
}
else
{
ucRcvLen++;
ucRcvCheckSum ^= ucTmp;
if( ucTmp == ETX)
{//帧结束标志
#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' )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -