STM32串口

发布于 2024-06-27  149 次阅读


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

最后更新于 2024-07-21