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) 清除对应的串口空闲中断标志