stm32 USART
1 USART基础知识
三种模式:轮询模式、中断模式、DMA模式
轮询模式属于阻塞模式
中断模式和DMA模式属于非阻塞模式
1.1 Polling mode IO operation
- Send an amount of data in blocking mode using HAL_UART_Transmit()
- Receive an amount of data in blocking mode using HAL_UART_Receive()
1.2 Interrupt mode IO operation
- Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
- At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxCpltCallback
- Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
- At reception end of transfer HAL_UART_RxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_RxCpltCallback
- In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can add his own code by customization of function pointer HAL_UART_ErrorCallback
1.3 DMA mode IO operation
- Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
- At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
- At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxCpltCallback
- Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
- At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
- At reception end of transfer HAL_UART_RxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_RxCpltCallback
- In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can add his own code by customization of function pointer HAL_UART_ErrorCallback
- Pause the DMA Transfer using HAL_UART_DMAPause()
- Resume the DMA Transfer using HAL_UART_DMAResume()
- Stop the DMA Transfer using HAL_UART_DMAStop()
2 重定向USART的输入与输出
参考1:
//* printf重定向 //!配置好printf重定向的源文件。(有一处需要结合实际替换) //!开启usart中断时:需要在主循环之前手动开启接收中断:HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 1); #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif //! 直接printf("HelloWorld");会导致打印不出来,自觉加/r/n PUTCHAR_PROTOTYPE { //具体哪个串口可以更改huart1为其它串口 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1 , 0xffff); return ch; }
/*# 7- Retarget printf to UART (std library and toolchain dependent) #########*/ #if defined(__GNUC__) int _write(int fd, char * ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY); return len; } #elif defined (__ICCARM__) #include "LowLevelIOInterface.h" size_t __write(int handle, const unsigned char * buffer, size_t size) { HAL_UART_Transmit(&huart1, (uint8_t *) buffer, size, HAL_MAX_DELAY); return size; } #elif defined (__CC_ARM) int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } #endif // OR: // Add syscalls.c with GCC #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, HAL_MAX_DELAY); return ch; }
3 USART中断
- 使用USART接收中断(根据接收数据的个数判断接收是否完成)连续接收数据时注意使用HAL_UART_Receive_IT(&huart1,buff,buffsize);重复使能中断。需要在中断回调函数的最后再使用HAL_UART_Receive_IT(&huart1,buff,buffsize);使能一次。
//The specific UART interrupts (Transmission complete interrupt, RXNE interrupt //and Error Interrupts) will be managed using the macros //__HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the //transmit and receive process. //【注】:实际上使能中断的(宏)函数是__HAL_UART_ENABLE_IT只不过该函数在HAL_UART_Receive_IT和HAL_UART_Transmit_IT中被调用了。 #define buffsize 5 uint8_t buff[10]; HAL_UART_Receive_IT(&huart1,buff,buffsize);//可以接收指定长度的字符。任意长度需要使用DMA void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if(huart->Instance==USART1){ } HAL_UART_Receive_IT(&huart1,buff,buffsize); }
- 进入中断回调函数需要对USART的句柄进行判断。
if(huart->Instance==USART1){ }
4 其他
-
可以使用string.h对字符串进行处理、比较。
-
串口通信有多种模式:
- 普通模式:HAL_UART_Transmit、HAL_UART_Receive
- 中断模式:HAL_UART_Transmit_IT、HAL_UART_Receive_IT
- DMA模式:
注意:在传输数据量较大,且通信波特率较高(大于38400)时,如果采用中断方式,每收发一个字节的数据
(CPU都会被打断,造成(PU无法处理其他事务。因此在批量数据传输,通信波特率较高时,建议采用DMA方式。 -
其他重要函数:
__HAL_UART_ENABLE_IT(HANDLE,INTERRUPT) 使能串口中断
__HAL_UART_GET_FLAG(HANDLE,INTERRUPT) 查询串口中断标志
__HAL_UART_CLEAR_IDLEFLAG(HANDLE) 清除对应的串口空闲中断标志
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律