STM32使用printf重定向到USART串口实现数据打印

STM32使用sprintf打印数据到串口助手

  • 一.背景知识
  • 二. 重定向printf到USART1
  • 三.使用printf打印hello,world到串口助手
  • 3.1 usart.c
  • 3.2 usart.h
  • 3.3 main.c
  • 四. 实验现象
  • 五.结语
  • 一.背景知识

    我们知道我们在进行编程的时候,遇到问题,经常通过打印信息进行调试,在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,对于你程序的调试就方便多了。你只需要加上如上代码就行了。你学会了吗?

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32使用printf重定向到USART串口实现数据打印

    发表评论