1.禁用半主机模式
方法一:禁用半主机模式,禁用了半主机模式才能使用标准库函数printf()打印信息到串口,在程序中加入以下代码即可。那么什么是半主机模式?为什么不用它?半主机模式是ARM单片机的一种调试机制,跟串口调试不一样的是,它需要通过仿真器来连接电脑和ARM单片机,并调用相应的指令来实现单片机向电脑显示器打印信息(或者从电脑键盘读取输入)。简而言之,这种方法比串口调试更复杂(需要进行更多的配置操作),也更不灵活(一定要用仿真器)。
/********** 禁用半主机模式 **********/
#pragma import(__use_no_semihosting)
struct __FILE
{
int a;
};
FILE __stdout;
void _sys_exit(int x)
{
x=x;
}
方法二:使用微库(MicroLIB),只要在Keil的“Options for Target -> Target ->Use MicroLIB”上打钩,即可使用串口打印。微库是区别于C标准库的另一个库,当使用微库时,就默认关闭了半主机模式,也就不用添加上面的代码。这样虽然方便,但微库相对于C标准库而言,支持的功能更少,主要体现在对操作系统的支持上。所以能不用就不用。
2.重定向fputc
由于printf 最终会调用 fputc 进行字符串输出,但是这些函数是标准库提供的,而标准库没有提供源码给你,当你需要用的时候添加 <stdio.h> 即可。在PC端时,printf会将需要打印的信息打印到控制台上,但是单片机没有控制台,fputc 输出的位置可能需要改变,比如输出到 LCD、串口1、串口2,所以需要重定向fputc函数。
/*****************************************************
*function: 写字符文件函数
*param1: 输出的字符
*param2: 文件指针
*return: 输出字符的ASCII码
******************************************************/
int fputc(int ch, FILE *f)
{
USART_SendData(USARTx, (unsigned char)ch); //发送数据到串口
while(USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET); //等待上次发送结束
return ch;
}