前言
为了方便后面USB调试,所以先实现串口通讯接口,前面进行了串口测试,但是接口不方便使用,需要实现方便应用层使用的串口收发接口。通过实现FIFO方式来实现串口的中断接收,发送为了简单使用查询发送方式。
过程
Bsp层
先实现bsp层的串口接口
Bsp_uart.c/h
初始化
void bsp_uart_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* IO Cfg
* PD9 USART3_RX
* PD8 USART3_TX
*/
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Enable USART3 clock */
__HAL_RCC_USART3_CLK_ENABLE();
/* USART3 Cfg */
UartHandle.Instance = USART3;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&UartHandle);
/* NVIC */
HAL_NVIC_EnableIRQ(USART3_IRQn);
HAL_NVIC_SetPriority(USART3_IRQn,0,1);
LL_USART_EnableIT_RXNE(USART3);
}
发送
void uart_sendbyte(uint8_t ch)
{
uint8_t tmp =ch;
HAL_UART_Transmit(&UartHandle,&ch,1,0xFFFFFFFF);
//LL_USART_TransmitData8(USART3,ch);
}
void bsp_uart_send(uint8_t* p, uint32_t len)
{
HAL_UART_Transmit(&UartHandle,p,len,0xFFFFFFFF);
}
串口接收中断处理
extern void uart_rx_handler(const uint8_t *buffer, uint32_t length);
void USART3_IRQHandler(void)
{
uint8_t ch;
if(LL_USART_IsActiveFlag_RXNE(USART3) && LL_USART_IsEnabledIT_RXNE(USART3))
{
/* RXNE flag will be cleared by reading of RDR register (done in call) */
ch = LL_USART_ReceiveData8(USART3);
//LL_USART_TransmitData8(USART3,ch);
//while(LL_USART_IsActiveFlag_TC(USART3) == 0);
uart_rx_handler(&ch, 1);
}
}
代码详见
bap_uart.c
#include "stm32f7xx_hal.h"
#include "stm32f7xx_ll_usart.h"
UART_HandleTypeDef UartHandle;
extern void uart_rx_handler(const uint8_t *buffer, uint32_t length);
void USART3_IRQHandler(void)
{
uint8_t ch;
if(LL_USART_IsActiveFlag_RXNE(USART3) && LL_USART_IsEnabledIT_RXNE(USART3))
{
/* RXNE flag will be cleared by reading of RDR register (done in call) */
ch = LL_USART_ReceiveData8(USART3);
//LL_USART_TransmitData8(USART3,ch);
//while(LL_USART_IsActiveFlag_TC(USART3) == 0);
uart_rx_handler(&ch, 1);
}
}
void uart_sendbyte(uint8_t ch)
{
uint8_t tmp =ch;
HAL_UART_Transmit(&UartHandle,&ch,1,0xFFFFFFFF);
//LL_USART_TransmitData8(USART3,ch);
}
void bsp_uart_send(uint8_t* p, uint32_t len)
{
HAL_UART_Transmit(&UartHandle,p,len,0xFFFFFFFF);
}
void bsp_uart_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* IO Cfg
* PD9 USART3_RX
* PD8 USART3_TX
*/
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Enable USART3 clock */
__HAL_RCC_USART3_CLK_ENABLE();
/* USART3 Cfg */
UartHandle.Instance = USART3;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&UartHandle);
/* NVIC */
HAL_NVIC_EnableIRQ(USART3_IRQn);
HAL_NVIC_SetPriority(USART3_IRQn,0,1);
LL_USART_EnableIT_RXNE(USART3);
}
bap_uart.h
#ifndef BSP_UART_H
#define BSP_UART_H
void bsp_uart_init(void);
void bsp_uart_send(uint8_t* p, uint32_t len);
#endif
驱动层
实现FIFO数据结构
typedef struct
{
uint32_t datalen_u32;
uint32_t maxlen_u32;
uint32_t in_u32;
uint32_t out_u32;
uint8_t* buffer_pu8;
}ring_buffer_t;
uint8_t uart_ring_buffer[128];
ring_buffer_t s_ring_buffer_t=
{
.datalen_u32 = 0,
.maxlen_u32 = sizeof(uart_ring_buffer),
.in_u32 = 0,
.out_u32 = 0,
.buffer_pu8 = uart_ring_buffer,
};
临界段处理
#define Alloc_Critical()
#define Enter_Critical() __disable_irq()
#define Exit_Critical() __enable_irq
接收处理,接收中断服务函数中调用
void uart_rx_handler(const uint8_t *buffer, uint32_t length)
{
uint32_t i;
for(i=0;i<length; i++)
{
if(s_ring_buffer_t.datalen_u32 < s_ring_buffer_t.maxlen_u32)
{
s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.in_u32] = buffer[i];
s_ring_buffer_t.datalen_u32++;
s_ring_buffer_t.in_u32++;
s_ring_buffer_t.in_u32 %= s_ring_buffer_t.maxlen_u32;
}
else
{
/* full */
break;
}
}
}
接收API
uint32_t uart_read(uint8_t *buff, uint32_t len)
{
uint32_t readlen = 0;
//uint32_t mask;
if(s_ring_buffer_t.datalen_u32 == 0)
{
return 0;
}
Alloc_Critical();
Enter_Critical();
uint32_t i;
for(i=0;i<len;i++)
{
if(s_ring_buffer_t.datalen_u32 > 0)
{
buff[i] = s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.out_u32];
s_ring_buffer_t.datalen_u32--;
s_ring_buffer_t.out_u32++;
s_ring_buffer_t.out_u32 %= s_ring_buffer_t.maxlen_u32;
readlen++;
}
else
{
break;
}
}
Exit_Critical();
return readlen;
}
发送API
int uart_write(uint8_t *buff, uint32_t len)
{
uint32_t i;
for(i=0; i<len ;i++)
{
uart_sendbyte(buff[i]);
}
return 0;
}
代码详见
uart.c
#include "uart.h"
#include "bsp_uart.h"
#include "stm32f7xx.h"
#define Alloc_Critical()
#define Enter_Critical() __disable_irq()
#define Exit_Critical() __enable_irq()
typedef struct
{
uint32_t datalen_u32;
uint32_t maxlen_u32;
uint32_t in_u32;
uint32_t out_u32;
uint8_t* buffer_pu8;
}ring_buffer_t;
uint8_t uart_ring_buffer[128];
ring_buffer_t s_ring_buffer_t=
{
.datalen_u32 = 0,
.maxlen_u32 = sizeof(uart_ring_buffer),
.in_u32 = 0,
.out_u32 = 0,
.buffer_pu8 = uart_ring_buffer,
};
void uart_rx_handler(const uint8_t *buffer, uint32_t length)
{
uint32_t i;
for(i=0;i<length; i++)
{
if(s_ring_buffer_t.datalen_u32 < s_ring_buffer_t.maxlen_u32)
{
s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.in_u32] = buffer[i];
s_ring_buffer_t.datalen_u32++;
s_ring_buffer_t.in_u32++;
s_ring_buffer_t.in_u32 %= s_ring_buffer_t.maxlen_u32;
}
else
{
/* full */
break;
}
}
}
uint32_t uart_read(uint8_t *buff, uint32_t len)
{
uint32_t readlen = 0;
//uint32_t mask;
if(s_ring_buffer_t.datalen_u32 == 0)
{
return 0;
}
Alloc_Critical();
Enter_Critical();
uint32_t i;
for(i=0;i<len;i++)
{
if(s_ring_buffer_t.datalen_u32 > 0)
{
buff[i] = s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.out_u32];
s_ring_buffer_t.datalen_u32--;
s_ring_buffer_t.out_u32++;
s_ring_buffer_t.out_u32 %= s_ring_buffer_t.maxlen_u32;
readlen++;
}
else
{
break;
}
}
Exit_Critical();
return readlen;
}
int uart_write(uint8_t *buff, uint32_t len)
{
uint32_t i;
for(i=0; i<len ;i++)
{
uart_sendbyte(buff[i]);
}
return 0;
}
uart.h
#ifndef UART_H
#define UART_H
#include <stdint.h>
void uart_rx_handler(const uint8_t *buffer, uint32_t length);
uint32_t uart_read(uint8_t *buff, uint32_t len);
int uart_write(uint8_t *buff, uint32_t len);
extern void uart_sendbyte(uint8_t ch);
#endif
测试
main.c中
#include "bsp_uart.h"
#include "uart.h"
bsp_uart_init();
uint8_t tx_buffer[2]={0xAA,0x55};
/* Infinite loop */
while (1)
{
uint8_t buffer[128];
for(;;)
{
uint32_t len=0;
if((len = uart_read(buffer, sizeof(buffer))) >0)
{
uart_write(buffer, len);
}
}
}
使用串口调试助手发送数据,开发板收到原样返回
总结
基于bsp层的串口收发,实现了基于FIFO的串口驱动,给应用层提供串口收发接口,uart.c和uart.h具备可移植性,方便移植到不同平台。方便后面的调试使用。