STM32使用printf重定向到USART(串口)并打印数据到串口助手

简介: STM32使用printf重定向到USART(串口)并打印数据到串口助手


一.背景知识

我们知道我们在进行编程的时候,遇到问题,经常通过打印信息进行调试,在java中使用的是System.out.println打印到输出窗口。在C语言中使用的是printf打印到输出窗口。而我们用keil进行编程的时候也是使用的C语言所以也可以使用printf,但是我们知道,keil中没有输出窗口。那我们如何使用printf呢?这里我们只需要重定向一下,将printf重定向到USART1(串口1)–这样我们就能通过串口1将信息打印到上位机(串口助手)。这里也有一个小知识点:下载程序也是通过串口1下载到单片机的内存中。

二. 重定向printf到USART1

这里我就直接给出重定向的代码。我们只需要包含这段代码。同时包含<stdio.h>这个头文件就能使用printf,信息将会输出到串口助手上面。

int fputc(int ch, FILE *f)
{      
  while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
  return ch;
}

三.使用printf打印hello,world到串口助手

这里我就做一个小实验,打印hello,world到串口助手。注意串口1的引脚是PA9.PA10我们需要配置一下。代码如下:

3.1 usart.c

#include "usart.h"
#include "stm32f10x.h" 
int fputc(int ch, FILE *f)
{      
  while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
  return ch;
}
void uart_init(u32 bound){
  //GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;   
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟  
//USART1_TX   GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
//USART1_RX   GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
  //Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;    //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE);                    //使能串口1 
}

3.2 usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"  
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
#endif

3.3 main.c

#include "usart.h"
#include "stdio.h"
void main()
{
uart_init(115200); 
printf("hello,world!\n");
printf("hello,world!\n");
printf("hello,world!\n");
}

四. 实验现象

我们这样只需要按一下复位键就能出现了打印信息了(由于我们这里没在while(1)中一直打印,所以程序跑一下就结束了。)为什么不在while(1)中一直打印呢,由于stm32运行速度较快,如果放入while(1)中,打印的数据量太多,串口助手容易死机。你们可以自己实验一下!

五.结语

整个程序到这里就结束了。学会这个printf重定向到串口1,对于你程序的调试就方便多了。你只需要加上如上代码就行了。你学会了吗?

目录
相关文章
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
2127 0
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
420 9
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
1585 2
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
2046 0
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
1851 2
|
缓存 网络协议 算法
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
886 2
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
1445 4