简介
使用Buffer来避免数据的丢失, 或许你自己在使用串口进行收发时会丢失数据,
现在我们就来简单使用一下RingBuffer创建Rx、Tx的Buffer来避免发送接收丢包或数据丢失问题。
扩展知识
RingBuffer的介绍, 看完大概也就知道了,实在不知道就看看下面的代码
线路连接
粗略描述
USART1 接 USB转TTL线到PC
USART3 接 ESP8266
实物
步骤
使用到的库
WKJay 的 RingBuffer
使用STM32CubeMX创建项目
参考 普中STM32-PZ6806L开发板(STM32CubeMX创建项目并点亮LED灯)
初始化串口1 和 串口3
USART1 和 USART3初始化一样
添加用户代码
/* 定义ringbuffer全局变量, rb_usart1_rx/rb_usart3_rx 是USART1和3的接收Buffer, tx则是发送Buffer*/
ringbuffer_t rb_usart1_rx, rb_usart3_rx, rb_usart1_tx, rb_usart3_tx;
uint8_t buffer_usart1_rx[512], buffer_usart3_rx[512], buffer_usart1_tx[512], buffer_usart3_tx[512];
/* 串口中断代理 */
void USART_isr(UART_HandleTypeDef *huart, ringbuffer_t *ringBuffer_rx, ringbuffer_t *ringBuffer_tx)
{
uint32_t isrflags = READ_REG(huart->Instance->SR);
uint32_t cr1its = READ_REG(huart->Instance->CR1);
if ((isrflags & USART_SR_RXNE) && (cr1its & USART_CR1_RXNEIE))
{
huart->Instance->SR;
ringbuffer_putchar(ringBuffer_rx, huart->Instance->DR);
return;
}
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
{
uint8_t ch;
if (ringbuffer_getchar(ringBuffer_tx, &ch) == 0)
{
huart->Instance->SR;
huart->Instance->DR = ch;
}
else
{
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
}
return;
}
}
/* USART1中断处理函数 */
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UART_HandleTypeDef *huart = &huart1;
USART_isr(huart, &rb_usart1_rx, &rb_usart1_tx);
/* USER CODE END USART1_IRQn 0 */
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/* USART3中断处理函数 */
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
UART_HandleTypeDef *huart = &huart3;
USART_isr(huart, &rb_usart3_rx, &rb_usart3_tx);
/* USER CODE END USART1_IRQn 0 */
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
int main(void)
{
...
ringbuffer_init(&rb_usart1_rx, buffer_usart1_rx, sizeof(buffer_usart1_rx));
ringbuffer_init(&rb_usart3_rx, buffer_usart3_rx, sizeof(buffer_usart3_rx));
ringbuffer_init(&rb_usart1_tx, buffer_usart1_tx, sizeof(buffer_usart1_tx));
ringbuffer_init(&rb_usart3_tx, buffer_usart3_tx, sizeof(buffer_usart3_tx));
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // USART1接收中断打开
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);// USART3接收中断打开
while(1)
{
uint8_t ch;
/* 从 usart1的接收buffer中取数据, 放到usart3的发送buffer中, 并开启usart1的发送中断 */
if (ringbuffer_getchar(&rb_usart1_rx, &ch) == 0) {
ringbuffer_putchar(&rb_usart3_tx, ch);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_TXE);
}
/* 从 usart3的接收buffer中取数据, 放到usart1的发送buffer中, 并开启usart1的发送中断 */
if (ringbuffer_getchar(&rb_usart3_rx, &ch) == 0) {
ringbuffer_putchar(&rb_usart1_tx, ch);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
}
}
...
}
共赏
Note:
某些地方可以做些优化,部分数据传递可以使用指针!