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

📄 serialcomm.c

📁 C8051F02X系列MCU串口通讯底层驱动程序
💻 C
字号:
/***************************************************************************
****************************************************************************
文 件 名:SerialCom.c
简要描述:完成RS-232通信协议的实现:包括初始化、通信握手、数据传输
修改记录:

			接收缓冲区结构:
		_____________________________________________________________________________
		_____________________________________________________________________________
				长度为BufferHeadLen			长度为TranBufLen
			 /-------/\------\	/----------------/\-------------------\
			 0   1  2  3  4  5  6  7  8  ................. TranBufLen+BufferHeadLen-1	
			 -- -- -- -- -- -- -- -- --						   -- -- -- --
			| 	|  |  |  |  |  |  |  |  | ................. |  |  |  |  |
			 -- -- -- -- -- -- -- -- --  						   -- -- -- --
			 |   |  |  |  |  |  |  |  |							 |	 |  |  |	
			\|/ \|/\|/\|/\|/\|/\|/\|/\|/  					   \|/\|/\|/\|/
		 有效数 头 尾 有效       \---------------\/--------------------/
	     据总长       个数							 数据	
		_____________________________________________________________________________
		_____________________________________________________________________________

****************************************************************************
****************************************************************************/

//----------------------------------------------------------------------//
//                                                                      //
//									头文件                              //
//																		//
//----------------------------------------------------------------------//
#include "config.h"
/**********************外部变量**********************************/

EXT bit FlagRecComm;                   //标志RS232接收缓冲区已经没有有效数据,FLASE为已经没有有效数据
EXT bit FlagSendComm;                  //标志RS232发送缓冲区已经没有有效数据,FLASE为已经没有有效数据
EXT bit ReceiveBufferStaIsOK;          //接收缓冲区溢出标志,FALSE表示溢出
EXT bit SendBufferStaIsOK;             //发送缓冲区溢出标志,FALSE表示溢出
EXT bit SendDataOutOK;                 //数据(字符)发送成功标志变量,“1”表示发送成功(完成)	 

EXT bit ReceivePCDataFlag;      
EXT volatile  unsigned char ReceiveDataOut[TranBufLen+BufferHeadLen];
EXT volatile  unsigned char SendDataOut[TranBufLen+BufferHeadLen];


/*************************************************
函数名称:ByteBufferInit
简要描述:缓冲区初始化,CBS-缓冲区指针, datalen-数据缓冲区长度
          // 操作数据定义为unsigned char *CBS
          // CBS[0]=缓冲区有效数据长度
          // CBS[1]=已有数据头地址偏移量,从 0 到 (CBS[0]-1)
          // CBS[2]=已有数据尾地址偏移量,从 0 到 (CBS[0]-1)
          // CBS[3]=已有数据个数
          // CBS[4]和CBS[5]=所有有效数据的代数和,作为通信时的校验和
          // 整个缓冲区总长度=CBS[0]+BufferHeadLen,必须由使用者定义
输		入:无                
输		出:无                
修改日志:
*************************************************/
void ByteBufferInit(unsigned char  *CBS, unsigned char datalen) 
{
	unsigned char i;
	EA = 0;
	CBS[0]=datalen;  // CBS[0]=缓冲区长度
	CBS[1]=0;        // CBS[1]=有效数据头地址(FIFO队列的输入位置),偏移量从 0 到 (CBS[0]-1)
	CBS[2]=0;        // CBS[2]=有效数据尾地址(FIFO队列的输出位置),偏移量从 0 到 (CBS[0]-1)
	CBS[3]=0;        // CBS[3]=等待发送/读取数据个数;
	CBS[4]=0;		 // CBS[4]=RS232接收缓冲区接收到数据包个数
	CBS[5]=0;		 // CBS[5]=保留	
	for(i=6;i<datalen+6;i++)
	{ CBS[i]=0; }	//清零
}
/*************************************************
函数名称:ClearCommRecBuffer0
简要描述:清空接受缓冲区        
输		入:无                
输		出:无                
修改日志:
*************************************************/
void ClearCommRecBuffer(void)
  {
    ReceiveDataOut[1] = 0x00;      // 有效数据头地址(FIFO队列的输入位置),偏移量从 0 到 (CBS[0]-1)
	ReceiveDataOut[2] = 0x00;      // 有效数据尾地址(FIFO队列的输出位置),偏移量从 0 到 (CBS[0]-1)
	ReceiveDataOut[3] = 0x00;	   // 已有数据个数
	ReceiveDataOut[4] = 0x00;	   // 接受到的数据包个数
	FlagRecComm 	  = FALSE;     //标志接收缓冲区已经没有数据
  }
/*************************************************
函数名称:ClearCommRecBuffer0
简要描述:清空接受缓冲区        
输		入:无                
输		出:无                
修改日志:
*************************************************/
void ClearCommSendBuffer(void)
  {
    SendDataOut[1] = 0x00;      // 有效数据头地址(FIFO队列的输入位置),偏移量从 0 到 (CBS[0]-1)
	SendDataOut[2] = 0x00;      // 有效数据尾地址(FIFO队列的输出位置),偏移量从 0 到 (CBS[0]-1)
	SendDataOut[3] = 0x00;	    // 已有数据个数
	FlagSendComm   = FALSE;     //标志发送缓冲区已经没有数据
  }
/*************************************************
函数名称:OpenComm
简要描述:打开并初始化RS232串口        
输		入:无                
输		出:无                
修改日志:
*************************************************/
void OpenComm(void) 
{
	EA = 0;
	UART0_Init ();                              // 调用UART初始化子程序
	ByteBufferInit(ReceiveDataOut,TranBufLen);  // 调用接收缓冲区初始化子程序
	 
	ByteBufferInit(SendDataOut,TranBufLen);     // 调用发送缓冲区初始化子程序
	 
	// 初始化状态标志量
	SendDataOutOK = FALSE;			//	数据(字符)发送成功标志变量,“1”表示发送成功(完成)			  
	SendBufferStaIsOK = TRUE;       //  发送缓冲区溢出标志,FALSE表示溢出
	ReceiveBufferStaIsOK = TRUE;    //  接收缓冲区溢出标志,FALSE表示溢出
	FlagRecComm  = FALSE;           //  标志RS232接收缓冲区已经没有有效数据,FALSE表示存在有效数据
}
/*************************************************
函数名称:SendCommChar
简要描述:串口0发送一个字节子程序       
输		入:char ch -- 所要发送的单字节数据                
输		出:无                
修改日志:
*************************************************/
void SendCommChar(char ch)
{
	SendBufferStaIsOK = TRUE;            
	if(SendDataOut[3]>=SendDataOut[0]-1) //检测已有的数据个数,即检测是否溢出,上限设大一些,防止陷入循环检测溢出死循环!!!!!!!
		{
			SendBufferStaIsOK = FALSE;
			return;
		}
	SendDataOut[SendDataOut[1]+BufferHeadLen] = ch;
	SendDataOut[3]++;    //已有数据个数加1
	_nop_();             //设置一延时
	SendDataOut[1]++;    //数据首地址加1
	if (SendDataOut[1]>=SendDataOut[0]-1)
	{ 	
		SendDataOut[1] = 0;     //指针回绕
	}
	if (SendDataOutOK==FALSE)         //如果在UART0发送中断中检测到已经没有数据了,就置标志SendDataOutOK==FALSE
	                                  //在此处若检测到此标志,则重新继续发送
	{	 
	    SBUF0 = SendDataOut[SendDataOut[2]+BufferHeadLen];
		SendDataOut[3]--;
		_nop_();
		SendDataOut[2]++;
		SendDataOutOK = TRUE;
		SomeNop();
	}
	return ;
}
/********************************************************************
函数名称:SendCommBuffer
简要描述:串口0发送缓冲区内容子程序       
输		入:void *base -- 所要发送的数据块(必须是地址连续的)头指针
			 unsigned char size -- 所要发送数据块的总字节数
										  (注意:必须是字节数)
输		出:无                
修改日志:
*********************************************************************/
void SendCommBuffer(void *base, unsigned char size) // 此处的size表示有多少个字节要传送
																	  // 注意:是字节数!!!!!
{
	unsigned char i=0;

	if (!size) { return; }
	SendBufferStaIsOK = TRUE;             //置发送缓冲区溢出检测标志为1,即未溢出   
	if(SendDataOut[3]>=SendDataOut[0]-size-1)	// 检测是否溢出
		{
			SendBufferStaIsOK = FALSE;
			return;
		}
	while (i<size)  
	{	 
		SendDataOut[SendDataOut[1]+BufferHeadLen] = *((unsigned char *)base+i);
		SendDataOut[3]++; 
		i++;
		SendDataOut[1]++; 
		if (SendDataOut[1]>=SendDataOut[0]-1)
		{ 
			SendDataOut[1] = 0;
		}
	}
	if (SendDataOutOK==FALSE)
	{	 
		SBUF0 = SendDataOut[SendDataOut[2]+BufferHeadLen];
		SendDataOutOK = TRUE;
		SendDataOut[2]++;
		SendDataOut[3]--; 
	}
}
/********************************************************************
函数名称:GetCommChar
简要描述:串口读取一个字节子程序       
输		入:unsigned char idata *ch -- 接收串口字节数据的地址
输		出:bit -- 成功接收返回TRUE,否则返回FALSE                
修改日志:
*********************************************************************/
//Read data from receive buffer,return 0 when no data, otherwise return 1;
bit GetCommChar(unsigned char idata *ch)      
{ 
	if (ReceiveDataOut[2]==ReceiveDataOut[1]) 
	  
		return FALSE;         // 检测是否溢出   
	*ch = ReceiveDataOut[ReceiveDataOut[2]+BufferHeadLen];
	ReceiveDataOut[3]--;       //接收到数据个数减1
	_nop_();                   //设置一等待
	ReceiveDataOut[2]++;       //尾地址加1
	if (ReceiveDataOut[2]>=ReceiveDataOut[0]-1)   //如果尾地址已经到达缓冲区的最后位置,则指针回绕
	{
		ReceiveDataOut[2] = 0;
	}
	if (ReceiveDataOut[2]==ReceiveDataOut[1])   //如果首地址和尾地址相同,则说明接收到没有数据
		FlagRecComm = FALSE;          //标志接收缓冲区已经没有数据
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -