串口通信

STM3贰串口通信有三种样式:轮询(阻塞式)、中断、DMA。小编不亮堂搁浅方式的串口通讯有怎么样适合的利用场景:每接收/发送多个字节,就要发生一回暂停,那对CPU反而是1种浪费。使用Cube
HAL,轮询式的串口通信最简便了,发送和接收数据分别有1个函数:

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

Timeout
参数给 HAL_MAX_DELAY
常量,则极端超时,函数一贯不通,直到产生/接收数据落成。

STM3二F30三RE
有二个 USARAV4T 和 三个 UACRUISERT,而 USA奇骏T 也得以干活在异步形式,相当于二个UA奥德赛T。Nucleo 的 ST-LINK 部分也还要落到实处了 USB-TTL 转换,与 MCU 的 USACRUISERT二连接。由此,将 C 的正式输入输出(<stdio.h>)重定向到 USAMuranoT二就如是一个挺不错的调剂选项。

A奥迪Q三MGCC 使用的是 newlib-nano 标准 C 库。要选取 newlib-nano,并将 stdio
重定向到串口,gcc 选项和重定向的完毕可参看 A奥迪Q3M GCC 附带的 retarget
示例,其路径为 share\gcc-arm-none-eabi\samples\src\retarget。归纳起来:

  • 钦赐 C 编写翻译器选项:
    -fno-builtin
  • 指定 linker(ld.exe)选项:
    –specs=nano.specs、–specs=nosys.specs
  • 达成函数 _read()、_write()
    ,其原型如下。_read() 函数从串口读取数据,_write()
    将数据写到串口。stdio 函数如 printf()、getchar()
    等将最后调用那五个函数完成输入输出

 

int _read (int fd, char *ptr, int len);
int _write (int fd, char *ptr, int len);

 

在 main()
函数中,首先打字与印刷多少个字符串,然后进入主循环,将收到到的字符原样重临。如下:

 

    ...
    puts("Good judgments come from experiences. ");

    uint8_t buf[32];

    while (1) { 
        HAL_UART_Receive(&huart2, buf, 1, HAL_MAX_DELAY);
        putchar(buf[0]);
        fflush(stdout);
    }

 

本人意识,在写出多少(字符/字符串)时,直到 \n
字符时,数据才真的写到串口。那应当是 stdio 的缓冲机制。puts()
自动在字符串末尾扩张了多个 \n,由此都回立时写出到串口。而 putchar()
则须求显式 flush 一下。

_write()
重定向完毕很简短,直接调用 HAL_UART_Transmit():

 

#include "main.h"
#include "stm32f3xx_hal.h"
#include "usart.h"

int _write (int fd, char *ptr, int len)
{
  /* Write "len" of char from "ptr" to file id "fd"
   * Return number of char written.
   * Need implementing with UART here. */

    HAL_UART_Transmit(&huart2, (uint8_t *) ptr, len, HAL_MAX_DELAY);

  return len;
}