#define _IN_SERIAL_C #include "serial.h" #include "cpuid.h" /*------------------------------------------------------------------------------------------*/ #ifndef MAX_STBUF1_SIZE #define MAX_STBUF1_SIZE (128) #endif #ifndef MAX_SRBUF1_SIZE #define MAX_SRBUF1_SIZE (128) #endif #ifndef MAX_STBUF2_SIZE #define MAX_STBUF2_SIZE (128) #endif #ifndef MAX_SRBUF2_SIZE #define MAX_SRBUF2_SIZE (128) #endif #ifndef MAX_STBUF3_SIZE #define MAX_STBUF3_SIZE (128) #endif #ifndef MAX_SRBUF3_SIZE #define MAX_SRBUF3_SIZE (128) #endif #ifndef MAX_STBUF4_SIZE #define MAX_STBUF4_SIZE (128) #endif #ifndef MAX_SRBUF4_SIZE #define MAX_SRBUF4_SIZE (128) #endif #ifndef MAX_STBUF5_SIZE #define MAX_STBUF5_SIZE (128) #endif #ifndef MAX_SRBUF5_SIZE #define MAX_SRBUF5_SIZE (128) #endif #ifndef MAX_STBUF6_SIZE #define MAX_STBUF6_SIZE (128) #endif #ifndef MAX_SRBUF6_SIZE #define MAX_SRBUF6_SIZE (128) #endif typedef struct { // 串口 u16 sEnFlag; // 有效标志 = 0x55aa,结构有效 USART_TypeDef * USARTx; BAUD_TypeDef baud; // 缓冲区 int squeueLen; // 发送缓冲区长度 u8 * sendQueue; // 发送缓冲区 u8 * pSdQueueHead; // 发送队列头指针 u8 * pSdQueueTail; // 发送队列尾指针 u16 lenSdQueue; // 发送队列有效长度 u16 ctrlSdFlag; // 发送标志, TRUE, 串口正在发送; FALSE, 串口没有发送 int rqueueLen; // 接收缓冲区长度 u8 * rsevQueue; // 接收缓冲区 u8 * pRsQueueHead; // 接收队列头指针 u8 * pRsQueueTail; // 接收队列尾指针 u16 lenRsQueue; // 接收队列有效长度 u16 ctrlRsFlag; // 接收允许标志, TRUE, 允许串口接收; FALSE, 不允许串口接收 ResvExProc resvexproc; // 接收外部处理函数指针 }UsartCtrl; #define FLAG_ENABLE 0x55AA /*------------------------------------------------------------------------------------------*/ #define IsUsartRxneFlag(usart) LL_USART_IsActiveFlag_RXNE(usart) #define IsUsartTxeFlag(usart) LL_USART_IsActiveFlag_TXE(usart) #define IsUsartTcFlag(usart) LL_USART_IsActiveFlag_TC(usart) #define EnableItReceive(usart) LL_USART_EnableIT_RXNE(usart) #define DisableItReceive(usart) LL_USART_DisableIT_RXNE(usart) #define EnableItTrans(usart) LL_USART_EnableIT_TXE(usart) #define DisableItTrans(usart) LL_USART_DisableIT_TXE(usart) #define ReceiveData LL_USART_ReceiveData8 #define TransmitData LL_USART_TransmitData8 /*------------------------------------------------------------------------------------------*/ // 中断处理宏,所有处理过程相同 #define INITUSART(usart) do \ {\ /* 使能接收中断 */ \ LL_USART_ReceiveData8(USART##usart); \ LL_USART_EnableIT_RXNE(USART##usart); \ \ /* 打开串口 */ \ LL_USART_Enable(USART##usart); \ } while (0) /*------------------------------------------------------------------------------------------*/ #define USART_PROC(usart) \ \ u8 g_usart##usart##TBuff[MAX_STBUF##usart##_SIZE];\ u8 g_usart##usart##RBuff[MAX_SRBUF##usart##_SIZE];\ UsartCtrl g_uCtrl##usart; \ \ int InitUsart##usart(BAUD_TypeDef baud, char dat, char parity, char stop) \ { \ /* 收发队列配置 */ \ memset(&g_uCtrl##usart, 0, sizeof(UsartCtrl)); \ g_uCtrl##usart.sendQueue = g_usart##usart##TBuff; \ g_uCtrl##usart.squeueLen = MAX_STBUF##usart##_SIZE; \ g_uCtrl##usart.rsevQueue = g_usart##usart##RBuff; \ g_uCtrl##usart.rqueueLen = MAX_SRBUF##usart##_SIZE; \ g_uCtrl##usart.USARTx = USART##usart; \ g_uCtrl##usart.baud = baud; \ \ g_uCtrl##usart.pSdQueueHead = &(g_uCtrl##usart.sendQueue[0]); \ g_uCtrl##usart.pSdQueueTail = g_uCtrl##usart.pSdQueueHead; \ g_uCtrl##usart.lenSdQueue = 0; \ g_uCtrl##usart.ctrlSdFlag = FALSE; \ \ g_uCtrl##usart.pRsQueueHead = &(g_uCtrl##usart.rsevQueue[0]); \ g_uCtrl##usart.pRsQueueTail = g_uCtrl##usart.pRsQueueHead; \ g_uCtrl##usart.lenRsQueue = 0; \ g_uCtrl##usart.ctrlRsFlag = TRUE; \ \ g_uCtrl##usart.sEnFlag = FLAG_ENABLE; \ g_uCtrl##usart.resvexproc = NULL; \ \ INITUSART(usart); \ return 0; \ } \ \ /*------------------------------------------------------------------------------------------*/ \ /* 功能:发送数据,将数据添加到发送队列中 */ \ /* 参数: pDatBuf,发送数据缓冲区 */ \ /* len, 发送数据长度 */ \ /* 返回: >= 0, 实际发送数据 */ \ /* 返回: -1, 输入参数错误 */ \ /* -2, 串口没有初始化*/ \ /* -3, 接收缓冲区控制错误*/ \ int Usart##usart##SendData(u8 * pDatBuf, int len) \ { \ int i; \ u8 * pSDat; \ \ if (pDatBuf == NULL || len < 0) \ { \ return -1; \ } \ if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \ { \ return -2; \ } \ \ /* 数据长度 */ \ EnterCritical(); \ if (g_uCtrl##usart.lenSdQueue+len > g_uCtrl##usart.squeueLen) \ { \ len = 0; /*g_uCtrl##usart.squeueLen - g_uCtrl##usart.lenSdQueue;*/ \ } \ pSDat = g_uCtrl##usart.pSdQueueTail; \ ExitCritical(); \ \ if (len < 0) \ { \ return -3; \ } \ /* 拷贝数据 */ \ for (i = 0; i < len; i++) \ { \ *pSDat++ = *pDatBuf++; \ if (pSDat > &(g_uCtrl##usart.sendQueue[g_uCtrl##usart.squeueLen-1])) \ { \ pSDat = &(g_uCtrl##usart.sendQueue[0]); \ } \ } \ /* 发送数据 */ \ if (len != 0) \ { \ EnterCritical(); \ g_uCtrl##usart.pSdQueueTail = pSDat; \ g_uCtrl##usart.lenSdQueue += len; \ if (g_uCtrl##usart.ctrlSdFlag != TRUE && g_uCtrl##usart.lenSdQueue != 0) \ { \ g_uCtrl##usart.ctrlSdFlag = TRUE; /* 设置标志 */ \ EnableItTrans(g_uCtrl##usart.USARTx); /* 打开中断,相当于启动传输 */ \ } \ ExitCritical(); \ } \ return len; \ } \ /*------------------------------------------------------------------------------------------*/ \ /* 功能:接收数据,将数据从接收队列中取出 */ \ /* 参数: pDat,存放缓冲区*/ \ /* expectLen,希望得到数据的大小 */ \ /* 返回: >= 0,实际得到数据的大小 */ \ /* -1, 输入参数错误*/ \ /* -2, 串口没有初始化*/ \ /* -3, 接收缓冲区控制错误*/ \ \ int Usart##usart##GetData(u8 * pDat, int expectLen) \ { \ int i, len; \ u8 * pSDat; \ \ if (pDat == NULL || expectLen < 0) \ { \ return -1; \ } \ \ if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \ { \ return -2; \ } \ \ EnterCritical(); \ pSDat = g_uCtrl##usart.pRsQueueHead; \ len = g_uCtrl##usart.lenRsQueue; \ ExitCritical(); \ \ if (len < 0) \ { \ return -3; \ } \ \ if (expectLen > len) /* 需要的数据大于串口中的数据 */ \ { \ return 0; \ } \ \ /* 读取数据 */ \ for (i = 0; i < expectLen; i++) \ { \ *pDat++ = *pSDat; \ pSDat++; \ if (pSDat > &(g_uCtrl##usart.rsevQueue[g_uCtrl##usart.rqueueLen-1])) \ { \ pSDat = &(g_uCtrl##usart.rsevQueue[0]); \ } \ } \ \ EnterCritical(); \ g_uCtrl##usart.pRsQueueHead = pSDat; \ g_uCtrl##usart.lenRsQueue -= expectLen; \ ExitCritical(); \ \ return expectLen; \ } \ /*------------------------------------------------------------------------------------------*/ \ /* 清空接收缓冲区 */ \ int Usart##usart##CleanRsBuf(void) \ { \ int len; \ EnterCritical(); \ g_uCtrl##usart.pRsQueueHead = g_uCtrl##usart.pRsQueueTail; \ len = g_uCtrl##usart.lenRsQueue; \ g_uCtrl##usart.lenRsQueue = 0; \ ExitCritical(); \ return len; \ } \ /*------------------------------------------------------------------------------------------*/ \ /* 得到接收数据的长度 */ \ int Usart##usart##GetRsLen(void) \ { \ int len; \ EnterCritical(); \ len = g_uCtrl##usart.lenRsQueue; \ ExitCritical(); \ return len; \ } \ /*------------------------------------------------------------------------------------------*/ \ /* 清空发送缓冲区 */ \ int Usart##usart##CleanSdBuf(void) \ { \ int len; \ EnterCritical(); \ g_uCtrl##usart.pSdQueueHead = g_uCtrl##usart.pSdQueueTail; \ len = g_uCtrl##usart.lenSdQueue; \ g_uCtrl##usart.lenSdQueue = 0; \ ExitCritical(); \ return len; \ } \ \ /*------------------------------------------------------------------------------------------*/ \ /* 得到发送缓冲区空闲长度 */ \ int Usart##usart##GetSdFreeLen(void) \ { \ int len; \ EnterCritical(); \ len = g_uCtrl##usart.squeueLen - g_uCtrl##usart.lenSdQueue; \ ExitCritical(); \ return len; \ } \ \ /*------------------------------------------------------------------------------------------*/ \ /* 判断发送缓冲区是否为空 */ \ int IsUsart##usart##SendBufEmpty(void) \ { \ int len; \ EnterCritical(); \ len = g_uCtrl##usart.lenSdQueue; \ ExitCritical(); \ if (len != 0) \ { \ return FALSE; \ } \ else \ { \ return TRUE; \ } \ } \ /* 发送是否完成 */ \ int IsUsart##usart##SendOver(void) \ { \ int flag; \ EnterCritical(); \ flag = g_uCtrl##usart.ctrlSdFlag; \ ExitCritical(); \ if (flag == TRUE) \ { \ return FALSE; \ } \ else \ { \ return TRUE; \ } \ } \ /*------------------------------------------------------------------------------------------*/ \ /* 中断处理 */ \ void USART##usart##IntProc(void) \ { \ u8 dat; \ if (IsUsartRxneFlag(g_uCtrl##usart.USARTx) != RESET) /* USART 接收中断 */ \ { \ dat = ReceiveData(g_uCtrl##usart.USARTx); \ if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \ { \ return; \ } \ if (g_uCtrl##usart.lenRsQueue < g_uCtrl##usart.rqueueLen) \ { \ *(g_uCtrl##usart.pRsQueueTail) = dat; /* 放入队列中 */ \ g_uCtrl##usart.pRsQueueTail++; \ if (g_uCtrl##usart.pRsQueueTail > &(g_uCtrl##usart.rsevQueue[g_uCtrl##usart.rqueueLen-1])) \ { \ g_uCtrl##usart.pRsQueueTail = &(g_uCtrl##usart.rsevQueue[0]); \ } \ g_uCtrl##usart.lenRsQueue++; /* 长度增加 */ \ } \ if (g_uCtrl##usart.resvexproc != NULL) \ { \ g_uCtrl##usart.resvexproc(dat); \ } \ } \ if (IsUsartTxeFlag(g_uCtrl##usart.USARTx) != RESET) /* USART 发送中断 */ \ { \ if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \ { \ DisableItTrans(g_uCtrl##usart.USARTx); /* 关闭中断 */ \ return; \ } \ if (g_uCtrl##usart.lenSdQueue != 0) \ { \ TransmitData(g_uCtrl##usart.USARTx, *(g_uCtrl##usart.pSdQueueHead)); /* 传输数据 */ \ g_uCtrl##usart.pSdQueueHead++; /* 指针后移 */ \ if (g_uCtrl##usart.pSdQueueHead > &(g_uCtrl##usart.sendQueue[g_uCtrl##usart.squeueLen-1])) \ { \ g_uCtrl##usart.pSdQueueHead = &(g_uCtrl##usart.sendQueue[0]); \ } \ g_uCtrl##usart.lenSdQueue--; /* 长度减小 */ \ g_uCtrl##usart.ctrlSdFlag = TRUE; /* 设置标志 */ \ } \ else \ { \ g_uCtrl##usart.ctrlSdFlag = FALSE; /* 设置标志 */ \ DisableItTrans(g_uCtrl##usart.USARTx); /* 关闭中断 */ \ } \ } \ } \ /*------------------------------------------------------------------------------------------*/ \ /* 注册接收数据外部处理函数 */ \ void RegUsart##usart##ResvExFunc(ResvExProc proc) \ { \ g_uCtrl##usart.resvexproc = proc; \ } \ \ /*------------------------------------------------------------------------------------------*/ \ /* USARTx同步发送数据 */ \ int Usart##usart##SendDataSync(u8 * pDatBuf, int len) \ { \ DisableItTrans(g_uCtrl##usart.USARTx); /* 关闭中断 */ \ while(len != 0) \ { \ while(IsUsartTcFlag(g_uCtrl##usart.USARTx) == RESET); \ TransmitData(g_uCtrl##usart.USARTx, *pDatBuf); \ pDatBuf++; \ len--; \ } \ return len; \ } \ \ /* USARTx同步接收数据 */ \ int Usart##usart##GetDataSync(u8 * pDat, int expectLen) \ { \ int count = 0; \ DisableItReceive(g_uCtrl##usart.USARTx); /* 关闭中断 */ \ while(expectLen != 0) \ { \ while(IsUsartTcFlag(g_uCtrl##usart.USARTx) == RESET); \ *pDat = ReceiveData(g_uCtrl##usart.USARTx); \ pDat++; \ expectLen--; \ count++; \ } \ return count; \ }\ /*------------------------------------------------------------------------------------------*/ #ifdef COMM_USART1 USART_PROC(1); #endif #ifdef COMM_USART2 USART_PROC(2); #endif #ifdef COMM_USART3 USART_PROC(3); #endif #ifdef COMM_USART4 USART_PROC(4); #endif #ifdef COMM_USART5 USART_PROC(5); #endif #ifdef COMM_USART6 USART_PROC(6); #endif