这里我用的单片机算是中颖的sh79f9401芯片
UART底层驱动相关函数:
//UART相关寄存器初始化
void Uart_Init(void)
{
PCON = 0x00;//选择SSTAT0
SCON = 0x50;//01000000 方式一
SBRTL = (u8int)(_SBRT & 0xFF);
SBRTH= (u8int)((0x80)|((_SBRT >> 8) & 0xFF));
SFINE = _SFINE;
ES0 = 1;//允许EUART0中断
}
//UART中断服务程序
void EUART_0_ISP(void) interrupt 4
{
if(TI)
{
TI = 0;
Drv_Uart_Tx_It_Handle(UART_PORT_0);
}
if(RI)
{
RI = 0;
Drv_Uart_Rx_It_Handle(UART_PORT_0,SBUF);
}
}
//UART发送一Byte数据
void Drv_Hardware_uart_SendByte(UART_PORT_TYPE ePort,char Data)
{
if(ePort == UART_PORT_0)
{
ACC = Data;
SBUF = ACC;载入要发送的数据
}
}
中间层UART相关函数:
#define _DRV_UART_C_
#include "drv.h"
#include "mw_uart.h"
//这里是发送和接受数据的缓冲区
u8int Uart_0_TxBuf[UART_0_TX_SIZE] = {0};//UART_0_TX_SIZE在uart.h头文件里根据需求和硬件资源自定义大小
u8int Uart_0_RxBuf[UART_0_RX_SIZE] = {0};//UART_0_RX_SIZE在uart.h头文件里根据需求和硬件资源自定义大小
//UART相关结构体
typedef struct
{
u8int * pu8TxAdd;//添加数据的地址,该地址数据无效
u8int * pu8TxValid;//有效数据的首
u8int * pu8TxMinAddr;//缓冲区最小地址
u8int * pu8TxMaxAddr;//缓冲区最大地址
u8int u8TxBufDataSize;//缓冲区已使用空间,有效数据大小
BOOL bTxIsStop;//中断是否在发送标记
u8int * pu8RxAdd;
u8int * pu8RxValid;
u8int * pu8RxMinAddr;
u8int * pu8RxMaxAddr;
u8int u8RxBufDataSize;
}DRV_UART_INFO;
DRV_UART_INFO sDrvUartInfo[1];
//初始化UART数据缓冲区
void MW_Uart_Data_Init(void)
{
sDrvUartInfo[UART_PORT_0].pu8TxAdd = &Uart_0_TxBuf[0];
sDrvUartInfo[UART_PORT_0].pu8TxValid = &Uart_0_TxBuf[0];
sDrvUartInfo[UART_PORT_0].pu8TxMinAddr = &Uart_0_TxBuf[0];
sDrvUartInfo[UART_PORT_0].pu8TxMaxAddr = &Uart_0_TxBuf[UART_0_TX_SIZE - 1];
sDrvUartInfo[UART_PORT_0].u8TxBufDataSize = 0;
sDrvUartInfo[UART_PORT_0].bTxIsStop = TRUE;
sDrvUartInfo[UART_PORT_0].pu8RxAdd = &Uart_0_RxBuf[0];
sDrvUartInfo[UART_PORT_0].pu8RxValid = &Uart_0_RxBuf[0];
sDrvUartInfo[UART_PORT_0].pu8RxMinAddr = &Uart_0_RxBuf[0];
sDrvUartInfo[UART_PORT_0].pu8RxMaxAddr = &Uart_0_RxBuf[UART_0_RX_SIZE - 1];
sDrvUartInfo[UART_PORT_0].u8RxBufDataSize = 0;
}
//将需要发送的数据添加到待发送的数据缓冲区,所有数据实际上是再终端里面发送
void MW_Uart_Send_Data_Add(UART_PORT_TYPE ePort,u8int * buf,u16int Size)
{
u8int Len = 0;
//if((UART_0_TX_SIZE - sDrvUartInfo[ePort].u8TxBufDataSize) >= Size)
{剩余空间比要发送的数据大才会发送,否则丢弃要发送的数据
sDrvUartInfo[ePort].u8TxBufDataSize = sDrvUartInfo[ePort].u8TxBufDataSize + Size;更新剩余空间大小
while(Len < Size)
{
*sDrvUartInfo[ePort].pu8TxAdd = buf[Len];
if(sDrvUartInfo[ePort].pu8TxAdd < sDrvUartInfo[ePort].pu8TxMaxAddr)
{
sDrvUartInfo[ePort].pu8TxAdd ++;
}
else
{
sDrvUartInfo[ePort].pu8TxAdd = sDrvUartInfo[ePort].pu8TxMinAddr;
}
Len ++;
}
if(sDrvUartInfo[ePort].bTxIsStop)
{
sDrvUartInfo[ePort].bTxIsStop = FALSE;
Drv_Hardware_uart_SendByte(ePort,*sDrvUartInfo[ePort].pu8TxValid);
}
}
}
//这个是中断发送函数
void MW_Uart_Tx_It_Handle(UART_PORT_TYPE ePort)
{
对上次中断进行指针移动同时更新剩余空间大小
sDrvUartInfo[ePort].u8TxBufDataSize --;
if(sDrvUartInfo[ePort].pu8TxValid < sDrvUartInfo[ePort].pu8TxMaxAddr)
{
sDrvUartInfo[ePort].pu8TxValid ++;
}
else
{
sDrvUartInfo[ePort].pu8TxValid = sDrvUartInfo[ePort].pu8TxMinAddr;
}
如果发送剩余空间小于缓冲区大小说明还有数据等待发送
if(sDrvUartInfo[ePort].u8TxBufDataSize > 0)
{
Drv_Hardware_uart_SendByte(ePort,*sDrvUartInfo[ePort].pu8TxValid);
}
else
{
sDrvUartInfo[ePort].bTxIsStop = TRUE;
}
}
//这个是中断接收函数
void MW_Uart_Rx_It_Handle(UART_PORT_TYPE ePort,u8int Data)
{
//if(sDrvUartInfo[ePort].u8RxBufDataSize < UART_0_RX_SIZE)缓冲区空间没满,填数据,否则丢弃数据
{
直接往缓冲里填接收到的数据
*sDrvUartInfo[ePort].pu8RxAdd = Data;
sDrvUartInfo[ePort].u8RxBufDataSize ++;
if(sDrvUartInfo[ePort].pu8RxAdd == sDrvUartInfo[ePort].pu8RxMaxAddr)
{
sDrvUartInfo[ePort].pu8RxAdd = sDrvUartInfo[ePort].pu8RxMinAddr;
}
else
{
sDrvUartInfo[ePort].pu8RxAdd ++;
}
}
}
//用户获取从串口接收到的数据
void MW_Uart_Get_Rx_Data(UART_PORT_TYPE ePort,UART_UserDataType *psData)
{
u16int u16Count = 0;
u8int* pu8UserBuf;
u8int *pu8GetData;
pu8UserBuf = &psData->u8UserData[0];
pu8GetData = sDrvUartInfo[ePort].pu8RxValid;
while(u16Count < sDrvUartInfo[ePort].u8RxBufDataSize)复制所有数据
{
*pu8UserBuf = *pu8GetData;
if(pu8GetData == sDrvUartInfo[ePort].pu8RxMaxAddr)
{
pu8GetData = sDrvUartInfo[ePort].pu8RxMinAddr;
}
else
{
pu8GetData++;
}
pu8UserBuf++;
u16Count ++;
}
psData->u16Size = sDrvUartInfo[ePort].u8RxBufDataSize;
}
//用户获取从串口接收到的数据后应当释放相应大小的缓冲区数据
void MW_Uart_Free_Rx_Buffer(UART_PORT_TYPE ePort, u8int u8Len)
{
while (u8Len --)
{
if (sDrvUartInfo[ePort].pu8RxValid == sDrvUartInfo[ePort].pu8RxMaxAddr)
{
sDrvUartInfo[ePort].pu8RxValid = sDrvUartInfo[ePort].pu8RxMinAddr;
}
else
{
sDrvUartInfo[ePort].pu8RxValid ++;
}
sDrvUartInfo[ePort].u8RxBufDataSize --;
}
}