用printf来发送字符到串口的方法:
(一) 在MDK中使用MicroLib重定向printf
(二) 在MDK中使用标准库重定向printf
注:(1)重定向printf其实就是重定向fputc。在MicroLib或者标准库中,printf最终都是通过fputc来输出字符串。而由于这些库只是提供了接口给我们调用,并没有提源码,所以我们只需要在程序添加库就能用了。
(2)什么是重定向。重定向就相当于重新再写函数。重定向fputc就是重新再写fputc函数,那为什么可以重新再写,不是库里面都写好了吗?的确,库里面已经写好了,由于已经封装,我们无法从源码上去修改,所以我们在其他文件上进行再次编写。之所以再编写fputc函数不会报错,原因是库里面的fputc函数加了一个修饰符-----__attribute__((weak))。
weak的作用呢就是当有两个相同函数名的函数定义了的时候,其中一个加了weak修饰,编译器就会选择没加weak的函数而忽略带weak的函数。而假如只有一个带weak修饰的函数,则编译器就会选择该函数。简单说就是,带weak的函数,如果只有一个,则编译器就不忽略它,若还有一个普通的同名函数,则编译器优先选择普通而忽略带weak的。
(一) 在MDK中使用MicroLib重定向printf
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
(二) 在MDK中使用标准库重定向printf
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}