0%

在Keil中重定向printf

遇到问题

今天用STM32CubeMX生成了代码,使用printf函数后单片机程序运行异常,查出是STM32CubeMX生成的代码没有printf的重定向,百度查了两个方法后两个都行不通,最后参考正点原子例程解决。

参考

  • 错误参考:一知半解学CubeMX——UART:Printf实现

  • 正确参考:正点原子例程SYSTEM文件夹下的usart.c

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //加入以下代码,支持printf函数,而不需要选择use MicroLIB
    #if 1
    #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;
    }
    #endif

注意事项

  1. 要注意重定向的函数名是int __io_putchar(int ch)还是int fputc(int ch, FILE *f)
1
2
3
4
5
6
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  1. CubeMX生成的代码没有勾选Use MicroLib,可能需要勾选,可以看Keil中的USE MicroLib说明,MicroLib不支持操作系统函数。

  2. Unix系统里,每行结尾只有“<换行>”,即”\n”;

    Windows系统里面,每行结尾是“<回车><换行>”,即“\r\n”;

    Mac系统里,每行结尾是“<回车>”,即”\r”;

    参考:\r,\n,\r\n的区别:回车与换行