⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 LCD及键盘、RS232通信控制源代码、采用keil c51环境编译
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************************
*                                                                                *
*	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 + -