基于STM32 HAL库的串口(USART)使用详解

一、USART通信概述

USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是STM32微控制器中常用的串行通信接口,支持同步和异步通信模式。在实际应用中,USART常用于:

  • 与PC或其他设备进行调试信息输出

  • 与各种传感器模块通信

  • 与其他微控制器或嵌入式系统交换数据

  • 工业控制中的Modbus等协议实现

STM32 HAL库为USART提供了完整的API接口,大大简化了开发流程。HAL库采用面向对象的设计思想,将USART的所有功能封装在USART_HandleTypeDef结构体中,开发者只需配置相应参数并调用相关函数即可实现通信功能。

二、USART硬件配置

1. 引脚配置

USART通信通常需要以下引脚:

  • TX:数据发送引脚

  • RX:数据接收引脚

  • 可选:RTS/CTS(硬件流控制)、CK(同步时钟)

在STM32CubeMX中配置USART引脚非常简单:

  1. 打开Pinout视图

  2. 找到需要的USART/USART接口

  3. 选择模式为"Asynchronous"(异步)或"Synchronous"(同步)

  4. 根据需要启用或禁用硬件流控制

2. 时钟配置

USART外设需要正确的时钟源才能工作:

  1. 在Clock Configuration中确认USART时钟源已使能

  2. 确保USART时钟频率与APB总线时钟一致

  3. 注意不同USART实例可能挂载在不同的APB总线上

三、HAL库USART初始化

1. 数据结构介绍

HAL库使用USART_HandleTypeDef结构体管理USART配置和状态:

2. 初始化步骤

完整的USART初始化流程如下:

四、USART通信模式

HAL库提供了多种USART通信方式,开发者可根据需求选择。

1. 轮询模式

最简单的通信方式,适用于简单的数据传输:

优点:实现简单,无需额外配置
缺点:阻塞式调用,效率低

2. 中断模式

提高系统效率的非阻塞通信方式:

3. DMA模式

最高效的通信方式,适合大数据量传输:

优点:几乎不占用CPU资源,适合高速大数据量传输
缺点:配置复杂,需要额外的DMA资源

五、高级功能实现

1. 串口重定向printf

方便调试的重定向方法:

2. 接收不定长数据

利用空闲中断实现不定长数据接收:

3. 硬件流控制

当通信速率较高或线路较长时,建议启用硬件流控制

七、实际应用案例

1. Modbus RTU实现

八、总结

本文详细介绍了基于STM32 HAL库的USART使用方法,从基础配置到高级应用,涵盖了轮询、中断和DMA三种通信模式。通过HAL库,开发者可以快速实现稳定可靠的串口通信功能。在实际项目中,应根据具体需求选择合适的通信方式,并注意错误处理和性能优化。

随着STM32系列不断更新,HAL库也在持续完善,建议开发者定期关注ST官方发布的更新和示例代码,以获得最佳开发体验。通过合理利用USART接口,可以满足绝大多数嵌入式系统的通信需求。

如果大家有什么不懂的可以评论区留言私信!!!

当然可以!这里是一个使用STM32HAL进行串口通信的简单实例: 首先,需要在CubeMX中配置串口。打开CubeMX并选择你的微控制器型号,然后点击"Peripherals"选项卡,在左侧的"USART"菜单下选择一个可用的串口。根据你的需求,配置串口的参数,例如波特率、数据位、停止位等。最后点击"Pinout & Configuration"选项卡,将串口的引脚分配给正确的GPIO引脚。 生成代码后,在你的工程中打开`main.c`文件,并添加以下代码: ```c #include "stm32fxxx_hal.h" UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t txData[] = "Hello, world!\r\n"; uint8_t rxData[20]; while (1) { HAL_UART_Transmit(&huart2, txData, sizeof(txData), HAL_MAX_DELAY); HAL_UART_Receive(&huart2, rxData, sizeof(rxData), HAL_MAX_DELAY); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { while(1); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { while(1); } HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { while(1); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 这段代码初始化了系统时钟、GPIO和USART2串口。在主循环中,我们通过串口发送"Hello, world!\r\n",然后通过串口接收数据。 请注意,在上述代码中,我们使用USART2串口和GPIOA的引脚2和3。如果你选择了不同的串口和引脚,请相应地修改代码。 希望这个例子能帮助到你!如有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值