重定向C库中stdio文件中的printf()函数,文件流-->串口USART1

1、printf()函数:

我们以前在VC6.0中编程时,包含include<stdio.h>头文件之后,调用printf()函数后可以向控制台传输(打印)一连串字符等。

若要在STM32上也想用printf()函数向指定的设备上传输(打印)一串数据的话,可以“重定向这个C库(stdio)printf()函数”来实现。

比如将其重定向到USART1上,即:printf()函数要输出的数据通过串口USART1发送出去,通过串口助手可以查看。

重定向后的优点:可以像在VC6.0里面使用printf()函数在控制台输出数据和控制符之类的一样,通过串口将其发送,对以后调试程序带来很大的便利。

2、对文件stdio的printf()函数的“重定向”的函数如下:



3、程序例举:

/**************************************************************************************************
 *	硬件平台:STM32F103VC
 *	学习重点:调用库函数来实现对USART的操作
 *	实现功能:软件仿真,实现STM32通过USART1发送数据
 *	作    者:赵小龙
 **************************************************************************************************/


/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"
#include <stdio.h>


/*----------------函数声明部分---------------*/
void delay1ms(int t) ;
void RCC_Configuration(void) ;
void GPIO_Configuration(void) ;
void USART_Configuration(u32 BaudRate) ;

/*******************************************************************************
* Function Name  : int fputc(int ch , FILE *f)
* Description    : 重定向这个C库(stdio)中printf函数 : 文件流-->串口USART1
* Input          : int ch , FILE *f
* Output         : 将printf函数要打印的字符不是显示在屏幕上,而是将其通过USART1发送出去
* Return         : int ch
*******************************************************************************/ 
int fputc(int ch , FILE *f)
{
/*---------------在调用本函数对printf函数重定向前,先要对USART1进行配置------------------*/
	//1、将ch送给USART1
	USART_SendData(USART1 , ch) ;

	//2、等待发送完毕
	while( USART_GetFlagStatus(USART1 , USART_FLAG_TC) == RESET ) { ; }
	
	//3、返回ch
	return(ch) ;
}


/* Private functions -----------------------------------------------------------------------------*/ 
/**************************************************************************************************
* Function Name  : main
* Description    : 软件仿真,从USART1发送26个大写的英文字母
* Input          : None
* Output         : None
* Return         : None
****************************************************************************************************/
int main(void)
{

	u8 i,data;	
/*--------配置开启系统时钟、配置USART1发送/接收使用的两个I/O口、配置USART1---------------------------------------------*/
	RCC_Configuration();
	GPIO_Configuration();
	USART_Configuration(19600);

/*--------发送一串字符‘A’--‘Z’到USART1的DR-----------------------------------------------------------------------------*/
	data='A';
	for(i=0;i<26;i++)
	{
		printf(" %d:",i+1);
		USART_SendData(USART1, data) ;
		data++ ;
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) ;//发送完成标志位为1时便是数据发送完毕,若为0时则应让程序等待(等待数据发送发送完成)
		/*注意:这里最好不要按照以下形式书写,否则会出错,具体原因我暂且还不知道
			u8 status ; 
			status = USART_GetFlagStatus(USART1, USART_FLAG_TC) ;  //将查看状态寄存器的函数的返回值赋值给变量status 
			while(status == RESET) ;
		*/
	}

	printf("\n赵小龙好人好运!\n") ; 

}

/*******************************************************************************
* Function Name  : Delay_Ms
* Description    : delay 1 ms.
* Input          : dly (ms)
* Output         : None
* Return         : None
*******************************************************************************/
void delay1ms(int t)
{
	//机器周期T = 1/(72000000/12)s = 1/6000000 s = 1/6 us
	int temp = 6000/4 ;
	while(t--)
	{
		while(temp--)
		{ ; }	
	}

}


/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{
	//----------使用外部RC晶振-----------
	RCC_DeInit();			//初始化为缺省值
	RCC_HSEConfig(RCC_HSE_ON);	//使能外部的高速时钟 
	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);	//等待外部高速时钟使能就绪
	
	//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);	//Enable Prefetch Buffer
	//FLASH_SetLatency(FLASH_Latency_2);		//Flash 2 wait state
	
	RCC_HCLKConfig(RCC_SYSCLK_Div1);		//HCLK = SYSCLK
	RCC_PCLK2Config(RCC_HCLK_Div1);			//PCLK2 =  HCLK
	RCC_PCLK1Config(RCC_HCLK_Div2);			//PCLK1 = HCLK/2
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);	//PLLCLK = 8MHZ * 9 =72MHZ
	RCC_PLLCmd(ENABLE);			//Enable PLLCLK

	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);	//Wait till PLLCLK is ready
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//Select PLL as system clock
	while(RCC_GetSYSCLKSource()!=0x08);		//Wait till PLL is used as system clock source
	
	//---------打开相应外设时钟--------------------
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能APB2外设的GPIOA的时钟	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	//使能APB2外设的GPIOC的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);	 
		 
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : 初始化GPIO外设
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/ 
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure USARTx_Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure USARTx_Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/*******************************************************************************
* Function Name  : USART_Configuration
* Description    : 初始化串口USART1(异步收发模式)
* Input          : BaudRate (要设置的波特率)
* Output         : None
* Return         : None
*******************************************************************************/ 
void USART_Configuration(u32 BaudRate)
{
//1、定义一个用于初始化USART的结构体
	USART_InitTypeDef USART_InitStructure;
	 
//2、给结构体元素赋值,设置 波特率、数据帧的位数、停止位的位数、奇偶校验位、硬件流控制位、USART模式(发送、接收)
	USART_InitStructure.USART_BaudRate = BaudRate; 
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
	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_Tx | USART_Mode_Rx;  

//3、调用函数USART_Init();用上面的结构体值作为参数对USART1进行初始化
	USART_Init(USART1, &USART_InitStructure);

//4、调用函数USART_Cmd();对USART1进行使能
	USART_Cmd(USART1, ENABLE);

}



程序运行前:



程序运行后:





  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用stm32单片机,如果想要将printf函数重定向USART1,可以通过重定向fputc函数来实现。具体步骤如下: 1. 首先,需要包含头文件stdio.h,以便使用printf函数和FILE类型。\[3\] 2. 在代码定义一个函数,例如USART1_printf,用于重定向fputc函数。这个函数的实现可以根据需求自定义,但需要包含头文件stdio.h、string.h和stdarg.h。\[2\] 3. 在重定向函数USART1_printf,使用USART_SendChar函数将字符发送到USART1。可以根据需要使用其他USART发送函数,如USART_SendString等。\[2\] 4. 在main函数,调用USART_Configuration函数进行USART1的配置。然后,可以使用printf函数来打印调试信息,这些信息将被重定向USART1。\[1\] 下面是一个示例代码: ```c #include <stdio.h> #include <string.h> #include <stdarg.h> // 重定向fputc函数USART1 int USART1_printf(const char* format, ...) { va_list args; va_start(args, format); char buffer\[100\]; vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); int len = strlen(buffer); for (int i = 0; i < len; i++) { USART_SendChar(USART1, buffer\[i\]); } return len; } int main(void) { USART_Configuration(); // USART1的配置函数 // 使用printf函数打印调试信息,信息将被重定向USART1 printf("\r\nstm32f103rct6\r\n"); printf("\r\nCortex-M3\r\n"); while (1); return 0; } ``` 通过以上步骤,就可以将printf函数重定向USART1,实现在stm32单片机通过USART1打印调试信息。 #### 引用[.reference_title] - *1* *3* [STM32printf函数重定向](https://blog.csdn.net/qq_29344757/article/details/75363639)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32实现将printf重定向串口的3种方法](https://blog.csdn.net/studyingdda/article/details/127388762)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值