STM32CubeMX 配置串口通信 HAL库

一、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配置时钟时要格外注意,选好芯片之后再看外部晶振是啥,不然随便设置可能乱码

相关推荐
Jason_zhao_MR5 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
BSD_CGQ6 小时前
FSR传感器STM32 DMA高速采样工程实现(高精度、低CPU占用)
stm32·单片机·嵌入式硬件·压力传感器·源头工厂·柔性薄膜压力传感器·可变电阻压力传感器
芯岭技术郦9 小时前
32 位 ARM® Cortex®-M0+ 内核MCU普冉MS32C001-C
单片机·嵌入式硬件
骑着毛驴数星星9 小时前
STM32 CAN波特率与采样点计算,基于HAL库
stm32·单片机·嵌入式硬件
zhangrelay10 小时前
Arduino-MEGA-ESP单片机理论课笔记02-硬件-2026
笔记·单片机·嵌入式硬件
艾芯微科技10 小时前
钰泰 ETA5055V330DD1E|SOT-223 3.3V LDO,低压差、大电流线性稳压选型分享
网络·单片机·嵌入式硬件·集成测试·51单片机
新晨单片机设计11 小时前
S023A-基于STM32单片机智能插座【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·单片机智能插座
威嵌神州11 小时前
恩智浦 T1022 性能怎么样?QorIQ 架构中端工业嵌入式优势解析
嵌入式硬件
weixin_6906547412 小时前
龙迅#LT9611EX 现MIPI转HDMI1.4功能主推型号,分辨率高达4K30HZ,IC内置I2C无需外部12C控制。
嵌入式硬件·音视频·信号处理
EatFans12 小时前
全栈自造 Status Deck(四):硬件终于到了,从点亮屏幕到跑通第一个 Demo
单片机·物联网