STM32中使用printf函数的方法和注意事项

一、目的

    利用printf函数使得输出打印到串口中。

二、工作原理

    我们在C语言中为什么能够调用printf函数打印数据到控制台中,那是因为printf函数又调用了fputc()函数。那么我们我们可不可以说printf函数之所以能够打印数据到控制台中几乎都是fput()函数的功劳呢?答案是显而易见的。因此,在这我们只需要重写fput函数即可。

三、代码展示

1、重写fput()函数

    在这里我们需要注意的是,在实际的代码运行过程中该函数是自调用的,不需要我们刻意调用它。

/******************************************************************************
*	函数功能 相当于串口发送数据
*	参数 
*	返回值
*	注意 该函数是stdio.h文件中默认函数 当我们使用printf函数时会自调用
*		 这里的printf函数跟C语言的printf用法一样
******************************************************************************/
int fputc(int ch,FILE *p)
{
	USART_SendData(USART1,(u8)ch);	
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
	return ch;
}

2、GPIO初始化

/****************************************************************
*	函数功能	printf的初始化
*	参数	无
*	返回值	无
****************************************************************/
void printf_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef  USART_InitStructure;
	
	/*  打开端口时钟  */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*  配置GPIO的模式和IO口 */
	//选择TX		 串口输出PA9
	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);  
	/* 初始化串口输入IO */
	//选择RX	串口输入PA10
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	  //模拟输入
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;		
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	/*  USART串口初始化  */
	//波特率设置为9600	
	USART_InitStructure.USART_BaudRate=9600;   
	//数据长8位
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;	
	//1位停止位	
	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);	
	
	/* 使能USART1 */
	USART_Cmd(USART1, ENABLE);		   
	//使能或者失能指定的USART中断 接收中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	//清除USARTx的待处理标志位	
	USART_ClearFlag(USART1,USART_FLAG_TC);
}

3、一个简单的hello输出

int main()
{
	printf_init();
	while(1)
	{		
		printf("hello!");
	}
}

四、keil中的配置

    实际上直接使用上述代码是不能够完成我们最初的设计目的的,单单这样它不会输出任何东西到串口中,我们还需要在keil中小小的配置一下。样例如下图:

五、总结

    小编个人认为,在这个项目中,实际上的printf函数就是一个串口输出函数,只不过它相比之前我们直接调用串口发送函数更加方便、更加实用,无非是在GPIO的定义与初始化上有点儿区别。因此,我们完全可以将printf函数看成一个串口发送函数。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32中使用printf函数的方法和注意事项

发表评论