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,对于你程序的调试就方便多了。你只需要加上如上代码就行了。你学会了吗?



目录
相关文章
|
5月前
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
71 9
|
5月前
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
185 2
|
5月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
452 0
|
6月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
492 2
|
5月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
842 0
|
7月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
6月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
540 4
|
6月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
819 2
|
6月前
|
存储 数据采集 数据安全/隐私保护
使用STM32F103读取TF卡并模拟U盘:使用标准库实现
通过以上步骤,你可以实现用STM32F103将TF卡内容变成U盘进行读取。这种功能在数据采集、便携式存储设备等应用中非常有用。如果你有更多的需求,可以进一步扩展此项目,例如添加文件管理功能、加密存储等。希望这篇博客能帮到你,如果有任何问题,欢迎在评论区留言讨论!
278 1