工作生活

【HAL库】STM32上手体验 之 UART 串口应用

2019-07-02  本文已影响0人  dexfire

【HAL库】STM32上手体验 之 UART 串口应用

串口是非常方便的调试工具,如果没有串口很多程序只能根据可见现象盲调,非常不方便。灵活使用串口,甚至能达到超越 JTAG 等调试工具的便捷调试目的。
这里以USART1为例进行描述,PA10 -> RX, PA9 -> TX。

  1. 系统AHB、APB1、APB2的时钟初始化

STM32在初始化后是默认使用HSI频率作为SYSCLK使用,并默认关闭大部分外设,仅保留核心运行所必需的Flash、SRAM、JTAG时钟。这是几乎所有STM32应用所必须的过程,这里不多叙述。

  1. 启用并初始化UART1对应的GPIO

首先启用GPIOA时钟,并初始化对应端口 PA9、PA10为复用推挽输出模式
【PA10 -> RX, PA9 -> TX】

    __HAL_RCC_GPIOA_CLK_ENABLE();    
    GPIO_InitTypeDef GPIO_Init_Struct;
    GPIO_Init_Struct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
    GPIO_Init_Struct.Mode = GPIO_MODE_AF_PP;
    GPIO_Init_Struct.Pull = GPIO_PULLUP;
    GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA,&GPIO_Init_Struct);

然后初始化对应的UART外设


    __HAL_RCC_USART1_CLK_ENABLE();
    // __HAL_UART_ENABLE(&UART_Handler);                    // 调用后单片机会卡死
    UART_Handler.Instance = USART1;
    UART_Handler.Init.BaudRate = 9600;
    UART_Handler.Init.WordLength = USART_WORDLENGTH_8B;
    UART_Handler.Init.StopBits = USART_STOPBITS_1;
    UART_Handler.Init.Mode = USART_MODE_TX_RX;             // 同步收发模式
    UART_Handler.Init.Parity = USART_PARITY_NONE;          // 无奇偶校验
    UART_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;     
    // RTS:Ready to Send; CTS:Clear to Send; NONE:N/A
    HAL_UART_Init(&UART_Handler);
    char* str = "UART Initialzing ... OK!";
    // printf(str);
    HAL_UART_Transmit(&UART_Handler,(uint8_t*)str,strlen(str),0xffff);
使用 printf() 函数通过 UART1 输出字符

到这里其实就能够调用 HAL_UART_Transmit() 函数来输出串口数据了,但实际使用过程中还是随时随地360无死角好用的 printf() 函数更加可口,所以我们再研究一下如何配置为可用 printf() 输出。

根据网上资料和ST给的例程,发现复写 fputc(char ch,FILE *f) 函数就能实现 printf() 但是惨遭忽悠,实际使用并没有得到预期的串口输出。

#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
    #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
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART1 and Loop until the end of transmission */
  HAL_UART_Transmit(&UART_Handler, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

虽然看起来很靠谱,但是实际应用并没有生效。用VS的追踪功能发现,使用的是预处理定义中的 __io_putchar(int ch) 分支,因为我使用的 ARM 编译器是基于 GCC 的。

上一篇下一篇

猜你喜欢

热点阅读