数据环形缓冲区:
#define FIFO_BUF_SIZE 512 //必须是2的幂次方
#define FIFO_BUF_SIZE_MASK (FIFO_BUF_SIZE - 1)
typedef struct
{
uint32 head; //头指针
uint32 tail; //尾指针
uint8 buf[FIFO_BUF_SIZE]; //缓冲区
} fifo_buf_t;
缓冲区接口:
status_t fifo_empty(fifo_buf_t* fifo) //判断缓冲区是否为空
{
if (fifo->tail == fifo->head) // empty
{
return OK;
}
return ER;
}
status_t fifo_full(fifo_buf_t* fifo) //判断缓冲区是否为满
{
if (((fifo->tail + 1) & FIFO_BUF_SIZE_MASK) ==
fifo->head) // full
{
return OK;
}
return ER;
}
status_t fifo_put(fifo_buf_t* fifo, uint8 c) //往缓冲区放一个字节
{
if (fifo_full(fifo) == OK) // full
{
return ER;
}
fifo->buf[fifo->tail] = c;
fifo->tail ++;
fifo->tail &= FIFO_BUF_SIZE_MASK;
return OK;
}
status_t fifo_get(fifo_buf_t* fifo, uint8* c) //往缓冲区取一个字节
{
if (fifo_empty(fifo) == OK) // empty
{
return ER;
}
*c = fifo->buf[fifo->head];
fifo->head ++;
fifo->head &= FIFO_BUF_SIZE_MASK;
return OK;
}
串口应用设计原理是:
数据收,接收中断会把数据丢到缓冲区,应用调用读接口,从接收缓冲区里读数据。 数据发,应用调用写接口,写数据到到发送缓冲区里,然后启动发送完成中断,在中断里会判断发送缓冲区是否有数据,有就发送,没有就关闭发送完成中断。
typedef struct //串口结构体
{
USART_TypeDef* USARTx;
fifo_buf_t tx_fifo; //发送缓冲区
fifo_buf_t rx_fifo; //接口缓冲区
} uart_driver_t;
static uart_driver_t uart_driver_list[UART_MAX];
void UART_TxIntCallback(int fd)
{
if ((fd < 0) || (fd >= UART_MAX))
{
return;
}
uart_driver_t* puart = &uart_driver_list[fd];
if (USART_GetITStatus(puart->USARTx, USART_IT_TC) != RESET)
{
uint8 c;
if (fifo_get(&puart->tx_fifo, &c) == OK)
{
USART_SendData(puart->USARTx, c);
}
else
{
USART_ITConfig(puart->USARTx, USART_IT_TC, DISABLE);
}
}
}
void UART_RxIntCallback(int fd)
{
if ((fd < 0) || (fd >= UART_MAX))
{
return;
}
uart_driver_t* puart = &uart_driver_list[fd];
if (USART_GetITStatus(puart->USARTx, USART_IT_RXNE) != RESET)
{
uint8 c;
c = USART_ReceiveData(puart->USARTx);
fifo_put(&puart->rx_fifo, c);
}
//溢出
if (USART_GetFlagStatus(puart->USARTx, USART_FLAG_ORE) == SET)
{
uint8 c;
c = USART_ReceiveData(puart->USARTx);
(void)c;
USART_ClearFlag(puart->USARTx, USART_FLAG_ORE);
}
}
static void UART_TxStartup(int fd)
{
if ((fd < 0) || (fd >= UART_MAX))
{
return;
}
uart_driver_t* puart = &uart_driver_list[fd];
USART_ITConfig(puart->USARTx, USART_IT_TC, ENABLE);
}
int UART_Write(int fd, uint8 *buf, int len)
{
if ((fd < 0) || (fd >= UART_MAX))
{
return ER;
}
int i;
uart_driver_t* puart = &uart_driver_list[fd];
if ((buf == NULL) || (len == 0))
{
return ER;
}
if (fifo_full(&puart->tx_fifo) == OK)
{
return 0;
}
SYS_ENTER_CRITICAL();
for (i = 0;i < len;i ++)
{
if (fifo_put(&puart->tx_fifo, buf[i]) == ER)
{
break;
}
}
SYS_EXIT_CRITICAL();
UART_TxStartup(fd);
return i;
}
int UART_Read(int fd, uint8 *buf, int len)
{
if ((fd < 0) || (fd >= UART_MAX))
{
return ER;
}
int i;
uart_driver_t* puart = &uart_driver_list[fd];
if ((buf == NULL) || (len == 0))
{
return ER;
}
if (fifo_empty(&puart->rx_fifo) == OK)
{
return 0;
}
SYS_ENTER_CRITICAL();
for (i = 0;i < len;i ++)
{
if (fifo_get(&puart->rx_fifo, &buf[i]) == ER)
{
break;
}
}
SYS_EXIT_CRITICAL();
return i;
}
static void UART_MspDeInit(int fd)
{
//硬件释放
}
static void UART_MspInit(int fd)
{
//硬件初始化
}
void UART_DeInit(int fd)
{
UART_MspDeInit(fd);
}
void UART_Init(int fd, uint32 BaudRate, uint16 StopBits,
uint16 Parity)
{
if ((fd < 0) || (fd >= UART_MAX))
{
return;
}
USART_InitTypeDef USART_InitStructure;
uart_driver_t* puart = &uart_driver_list[fd];
/* uart fifo */
memset(&puart->tx_fifo, 0, sizeof(fifo_buf_t));
memset(&puart->rx_fifo, 0, sizeof(fifo_buf_t));
UART_MspInit(fd);
/* USART mode config */
USART_InitStructure.USART_BaudRate = BaudRate; //115200;
USART_InitStructure.USART_WordLength = ((Parity == USART_Parity_No)
? USART_WordLength_8b : USART_WordLength_9b);
USART_InitStructure.USART_StopBits = StopBits; //USART_StopBits_1;
USART_InitStructure.USART_Parity = Parity; //USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(puart->USARTx, &USART_InitStructure);
USART_ITConfig(puart->USARTx, USART_IT_RXNE, ENABLE);
USART_ClearFlag(puart->USARTx, USART_FLAG_TC); //清除发送完成标志
USART_Cmd(puart->USARTx, ENABLE);
}