MCU:STM32L475RGT6
Toolchain:STM32Cube
轮询
中断
DMA不定长收发
1、在CubeMX中开启USART1
2、在DMA Settings中新增RX和TX的DMA Request
3、在NVIC中开启USART1 global interrupt(DMA interrupt已经自动开启)
4、生成代码,添加代码
/* USER CODE BEGIN PV */
uint8_t rx_buffer[50] = {0};
extern DMA_HandleTypeDef hdma_usart1_rx; //如勾选了.c/.h
/* USER CODE END PV */
/* 初始化后添加 */
/* USER CODE BEGIN 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, sizeof(rx_buffer));
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); //关闭DMA半完成中断
/* USER CODE END 2 */
/* 回调函数 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart == &huart1) {
HAL_UART_Transmit_DMA(&huart1, rx_buffer, Size); //发送接收的数据
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, sizeof(rx_buffer));
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
}
说明:使用ReceiveToIdle函数后,不再调用RxCpltCallback回调,而是使用了RxEventCallback回调函数。
重定向
在main.c中的Private Includes中添加
#include "stdio.h"
在main.c中的Private Function Prototypes section中添加
情况1:仅重定向scanf()
#ifdef __GNUC__
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif
GETCHAR_PROTOTYPE
{
uint8_t ch = 0;
/* Clear the Overrun flag just before receiving the first character */
__HAL_UART_CLEAR_OREFLAG(&huart?);
/* Wait for reception of a character on the USART RX line and echo this
* character on console */
HAL_UART_Receive(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
情况2:重定向scanf()和printf()
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
GETCHAR_PROTOTYPE
{
uint8_t ch = 0;
/* Clear the Overrun flag just before receiving the first character */
__HAL_UART_CLEAR_OREFLAG(&huart?);
/* Wait for reception of a character on the USART RX line and echo this
* character on console */
HAL_UART_Receive(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
为使scanf()函数正常运行,在main()函数的开始部分添加代码,禁用输入流内部缓存
setvbuf(stdin, NULL, _IONBF, 0);
启用浮点支持(可选)
Properties > C/C++ Build > Settings > Tool Settings > MCU Settings >
✔ Use float
参考网址:
https://www.digikey.cn/zh/forum/t/topic/2853
https://www.bilibili.com/video/BV1do4y1F7wt/?spm_id_from=333.788&vd_source=f50ea02365df511425eb7471842208b8