【WB32库开发】第8章 UART串口通信之printf重定向

本章讲解一下URAT(Universal Asynchronous Receiver/Transmitter)通用异步收发器的串口打印功能。WB32共有三个UART串口,其中UART1挂载在APB1总线上,UART2和UART3挂载在APB2总线上。

UART在WB32中最多的应用就是printf输出调试信息,当我们需要了解程序内一些变量数据信息时,可以通过printf函数将信息打印在串口调试助手上显示,极大的方便我们调试程序。

本节课主要通过固件库UART例程中的UART_Printf工程,讲解如何配置UART使之能够使用printf函数,理解后,UART2与UART3的设置类似。

8.1 UART串口通信配置步骤

下面我们以UART1配置为例,首先根据WB32数据手册查找到UART1的收发引脚为PA9、PA10,应开启GPIOA的时钟和UART1的时钟。第二步配置PA9与PA10为复用输出模式。第三步,配置UART。

在第三步配置中,首先使用函数恢复UART默认配置,接着根据需求向UART初始化结构体成员赋值,最后初始化URAT初始化结构体并使能UART1的FIFO功能。

下面是一个简单的UART1配置函数,请大家结合注释仔细阅读。

  //使能UART1时钟和UART1对应引脚时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_GPIOA |RCC_APB1Periph_UART1, ENABLE);
  //初始化UART1收发引脚为复用推挽上拉输出模式(配置UART时AF配置与上GPIO_AF7即可)
  GPIO_Init(GPIOA, GPIO_Pin_9 |GPIO_Pin_10, GPIO_MODE_AF |GPIO_OTYPE_PP |GPIO_PUPD_UP |GPIO_SPEED_HIGH |GPIO_AF7);

  /* UART1 配置 */
  UART_DeInit(UART1);                                                   //恢复UART默认配置
  UART_InitStructure.UART_BaudRate = 115200;                            //配置波特率为115200,在使用串口助手上位机时设置为对应波特率
  UART_InitStructure.UART_WordLength = UART_WordLength_8b;              //配置帧数据字长为8bit
  UART_InitStructure.UART_StopBits = UART_StopBits_One;                 //配置停止位为1位
  UART_InitStructure.UART_Parity = UART_Parity_None;                    //配置校验位为无校验
  UART_InitStructure.UART_AutoFlowControl = UART_AutoFlowControl_None;  //配置硬件控制流
  UART_Init(UART1, &UART_InitStructure);                                //初始化UART初始化结构体
  UART_FIFOCmd(UART1, ENABLE);                                          //使能UART的FIFO功能

8.2 printf函数重定向

8.1节给大家展示了如何配置UART,但STM32与51单片机不同,现在还不能调用printf函数输出信息,需要告诉WB32往哪里printf。

如何实现?只需添加如下代码,将printf()的底层函数中的fputc()的输出指向WB32串口即可。

//默认函数,在使用printf函数时自动调用
int fputc(int ch, FILE *f) 
{
  //将输出指向UART1。若使用UART2或UART3对应修改标号即可。
  while(!(UART1->LSR & UART_LSR_THRE));     
  UART1->THR = ch;
  while(!(UART1->LSR & UART_LSR_TEMT));
  return ch;
}

注意:
1)若使用printf()函数,头文件中必须包含<stdio.h>
2)若使用scanf()函数,亦需要进行重定向,本节使用固件库例程中已展示,与printf重定向类似,不再赘述。(重定向代码在Retarget_uart1.c文件中)
3)若想正确使用printf()函数输出,还需要使用微库(MicroLIB),只要在Keil的“Options for Target -> Target ->Use MicroLIB”上打钩即可。

8.3 实验现象

观察主函数部分,

int main(void)
{
  uint32_t value;
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_GPIOA |RCC_APB1Periph_UART1, ENABLE);
  
  GPIO_Init(GPIOA, GPIO_Pin_9 |GPIO_Pin_10, GPIO_MODE_AF |GPIO_OTYPE_PP |GPIO_PUPD_UP |GPIO_SPEED_HIGH |GPIO_AF7);

  UART_DeInit(UART1);
  UART_InitStructure.UART_BaudRate = 115200;
  UART_InitStructure.UART_WordLength = UART_WordLength_8b;
  UART_InitStructure.UART_StopBits = UART_StopBits_One;
  UART_InitStructure.UART_Parity = UART_Parity_None;
  UART_InitStructure.UART_AutoFlowControl = UART_AutoFlowControl_None;
  UART_Init(UART1, &UART_InitStructure);
  UART_FIFOCmd(UART1, ENABLE);

  puts("Please enter a value, end of new line.\r\n");

  while (1)
  {
    scanf("%d", &value);
    printf("You enter is %d\r\n", value);
  }
}

除去UART配置部分,进入循环前串口会打印"Please enter a value, end of new line."。
按提示输入数字后,例如:“1”。通过scanf()将输入的值“1”存入“value”中,然后再通过printf()将存入“value”中的值读出。

实验结果如图所示
在这里插入图片描述

注意:
1)注意puts("Please enter a value, end of new line.\r\n");,在输入“1”后需按下回车键进入新行,再点击发送。
2) 串口调试工具下载地址:链接:https://pan.baidu.com/s/1w6IxMNmhhLfN9IemtKry3A 提取码:CSDN

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用STM32 HAL的时候,我们可以使用DMA方式进行串口数据发送,同时也可以通过定向printf输出到串口。下面给出一种实现方式: 首先,在初始化串口时,需要开启DMA传输模式。例如: ```c // 初始化串口 huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } // 开启DMA传输模式 __HAL_UART_ENABLE_DMA(&huart2, UART_DMA_TX); ``` 接着,我们需要在代码中实现定向printf输出到串口的功能。可以通过写标准输出流中的`_write`函数来实现。例如: ```c int _write(int file, char *ptr, int len) { if (file == STDOUT_FILENO || file == STDERR_FILENO) { // 确保DMA传输完成 while (HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX) ; // 启动DMA传输 HAL_UART_Transmit_DMA(&huart2, (uint8_t *)ptr, len); return len; } errno = EIO; return -1; } ``` 这里我们判断输出流是标准输出流或标准错误输出流时,才进行串口DMA传输。同时,为了避免复启动DMA传输,需要等待之前的传输完成。 最后,我们就可以在代码中使用printf输出到串口了,例如: ```c printf("Hello, world!\r\n"); ``` 这样,我们就实现了STM32 HAL串口DMA发送并与printf定向的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值