一、printf重定向简介
我们知道C语言中printf函数默认输出设备是显示器,如果要实现在 串口或者LCD上显示,必须重定义标准库函数里调用的与输出设备相关的函数。比如使用printf输出到串口,需要将fputc里面的输出指向串口, 这一过程就叫重定向。 那么如何让STM32使用printf函数呢?
int fputc(int ch,FILE *p) //函数默认的,在使用printf函数时自动调用
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
二、printf函数格式
printf("<格式化字符串>", <参量表>);
//.h文件
1 #ifndef __usart_H 2 #define __usart_H
3
4 #include "system.h"
5 #include "stdio.h"
6
7 void USART1_Init(u32 bound); 8
9
10 #endif
//.c文件
1 #include "usart.h"
2
3 int fputc(int ch,FILE *p) //函数默认的,在使用printf函数时自动调用
4 { 5 USART_SendData(USART1,(u8)ch); 6 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); 7 return ch; 8 } 9
10 /******************************************************************************* 11 * 函 数 名 : USART1_Init 12 * 函数功能 : USART1初始化函数 13 * 输 入 : bound:波特率 14 * 输 出 : 无 15 *******************************************************************************/
16 void USART1_Init(u32 bound) 17 { 18 //GPIO端口设置
19 GPIO_InitTypeDef GPIO_InitStructure; 20 USART_InitTypeDef USART_InitStructure; 21 NVIC_InitTypeDef NVIC_InitStructure; 22
23 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 24 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); 25 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //打开时钟
26
27
28 /* 配置GPIO的模式和IO口 */
29 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX //串口输出PA9
30 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 31 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
32 GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化串口输入IO */
33 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX //串口输入PA10
34 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模拟输入
35 GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */
36
37
38 //USART1 初始化设置
39 USART_InitStructure.USART_BaudRate = bound;//波特率设置
40 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
41 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
42 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
43 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
44 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
45 USART_Init(USART1, &USART_InitStructure); //初始化串口1
46
47 USART_Cmd(USART1, ENABLE); //使能串口1
48
49 USART_ClearFlag(USART1, USART_FLAG_TC); 50
51 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断 52
53 //Usart1 NVIC 配置
54 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
55 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
56 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3
57 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
58 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
59 } 60
61 /******************************************************************************* 62 * 函 数 名 : USART1_IRQHandler 63 * 函数功能 : USART1中断函数 64 * 输 入 : 无 65 * 输 出 : 无 66 *******************************************************************************/
67 void USART1_IRQHandler(void) //串口1中断服务程序
68 { 69 u8 r; 70 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
71 { 72 r =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
73 USART_SendData(USART1,r); 74 while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); 75 } 76 USART_ClearFlag(USART1,USART_FLAG_TC); 77 }
// main文件
1 #include "system.h"
2 #include "SysTick.h"
3 #include "led.h"
4 #include "usart.h"
5
6
7 /******************************************************************************* 8 * 函 数 名 : main 9 * 函数功能 : 主函数 10 * 输 入 : 无 11 * 输 出 : 无 12 *******************************************************************************/
13 int main() 14 { 15 u8 i=0; 16 u16 data=1234; 17 float fdata=12.34; 18 char str[]="Hello World!"; 19 SysTick_Init(72); 20 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
21 LED_Init(); 22 USART1_Init(9600); 23
24 while(1) 25 { 26 i++; 27 if(i%20==0) 28 { 29 led1=!led1; 30
31 printf("输出整型数data=%d\r\n",data); 32 printf("输出浮点型数fdata=%0.2f\r\n",fdata); 33 printf("输出十六进制数data=%X\r\n",data); 34 printf("输出八进制数data=%o\r\n",data); 35 printf("输出字符串str=%s\r\n",str); 36
37 } 38 delay_ms(10); 39 } 40 }