一、STM32CubeMX 配置串口
每个外设生成独立的 '.c/.h'
文件
不勾:所有初始化代码都生成在 main.c
勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。
二、重写fputc函数
cpp
#include <stdio.h>
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__*/
/******************************************************************
*@brief Retargets the C library printf function to the USART.
*@param None
*@retval None
******************************************************************/
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1,0xFFFF);
return ch;
}
三、配置接收中断函数
cpp
#define RXBUFFERSIZE 1 /* 缓存大小 */
uint8_t g_usart_rx_buf[200]; //接收缓冲,最大200个字节
uint16_t g_usart_rx_len; //接收长度
uint8_t g_usart_rx_flag=0; //接收完成标志
uint8_t g_rx_buffer[RXBUFFERSIZE]; /* HAL库USART接收Buffer */
在串口初始化函数中使能接收中断
/* 该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
g_usart_rx_buf[g_usart_rx_len] = g_rx_buffer[0] ;
g_usart_rx_len++;
if(g_rx_buffer[0]==0x0a)
{
g_usart_rx_flag=1;
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
}
}
四、串口空闲中断接收数据
cpp
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//空闲中断
cpp
#define USART1_MAX_RECV_LEN 1000 //最大接收缓存字节数
char USART1_RX_BUF[USART1_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节
unsigned short USART1_RX_STA=0;
/* USER CODE BEGIN 1 */
void USART1_IRQHandler(void)
{
uint8_t res = 0;
//接收中断
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != RESET)
{
HAL_UART_Receive(&huart1,&res,1,1000);
//将数据放入缓冲区
if( (USART1_RX_STA&0x7fff) < USART1_MAX_RECV_LEN)
{
USART1_RX_BUF[USART1_RX_STA] = res;
USART1_RX_STA++;
}
__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);
}
//空闲中断
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET)
{
//一帧数据接收完成
//USART1_IdleCallback(USART1_RX_BUF,USART1_RX_STA&0x7fff);
USART1_RX_BUF[ USART1_RX_STA &0x7fff] = 0;
USART1_RX_STA |= 1 << 15;
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
}
}
cpp
if(USART1_RX_STA& 0x8000)
{
printf("%s\r\n",USART1_RX_BUF);
USART1_RX_STA=0;
}
五、串口乱码原因之一
乱码一般是配置串口波特率和上位机串口波特率不一致所致,如果两者一致,则说明系统时钟有问题,比如下面的外部晶振不匹配
开发板上外部时钟的晶振与代码中的外部时钟的晶振不一致,使用cubemx配置时钟时要格外注意,选好芯片之后再看外部晶振是啥,不然随便设置可能乱码