[APM32F4] 【极海APM32F407 Tiny Board】1. 用Printf打印输出

[复制链接]
 楼主| caizhiwei 发表于 2023-7-14 21:43 | 显示全部楼层 |阅读模式
本帖最后由 caizhiwei 于 2023-7-14 21:43 编辑

#申请原创# #申请开发板#   @21小跑堂 @21ic小喇叭
一,板卡简介:
        APM32F407  Tiny Board搭载一颗基于Arm® Cortex®-M4F内核的32位工业级高性能APM32F407 MCU,工作主频168MHz,Flash 1MB,SRAM 192+4KB;该Tiny板配备使用说明书、原理图、SDK等,可协助开发者快速上手,支持实时系统Free RTOS和RT-Thread,可使用的开发工具包含Keil MDK-ARM、IAR Embedded Workbench、Visual Studio Code、Eclipse。

    二, 背景
     printf和scanf是学习C语言是首先会接触的内容。在单片机上也可以使用这两个函数实现打印功能,需要结合串口实现,也需要IDE支持,不同的IDE实现scanf接收和printf打印的方法是不一样的。本文将讲解如何使用KEIL实现printf和scanf。
首先是确定串口连接,下载APM407的数据手册,可以看到USART1连接到了PA9(TX)和PA10(RX)上,正好官方提供的例程也是使用的USART1,所以将官方例程直接拿过来修改完成我们需要的功能即可。

     三,问题原因
     在 IAR 9.30.xx 的 IAR 对 printf 重定向有了新的要求,导致 IAR 9.30.xx 及以上的版本无法运行含有 printf 功能的例程。
IAR 9.30.xx 的 printf 重定向重定向的详细内容我这里给出参考操作。

    四,操作步骤
在源码目录下,新建 write.c 文件用于存放我们重定向的代码;
打开需要重定向的工程,在工程中添加我们刚刚新建的 write.c ;编辑“write.c”文件,添加重定向代码。代码内容如下,需要根据 UART 设置修改相关函数。

  1. #include "printf.h"


  2. #if defined (__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))

  3. /*!
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]       Redirect C Library function printf to serial port.
  5. *              After Redirection, you can use printf function.
  6. * @param       ch:  The characters that need to be send.
  7. * @param       *f:  pointer to a FILE that can recording all information
  8. *              needed to control a stream
  9. * @retval      The characters that need to be send.
  10. * @note
  11. */
  12. int fputc(int ch, FILE* f)
  13. {
  14.     /* send a byte of data to the serial port */
  15.     UartX_Put_Char(DEBUG_USART, (uint8_t)ch);  
  16.     return (ch);
  17. }

  18. #elif defined (__GNUC__)

  19. /*!
  20. * [url=home.php?mod=space&uid=247401]@brief[/url]       Redirect C Library function printf to serial port.
  21. *              After Redirection, you can use printf function.
  22. *
  23. * @param       ch:  The characters that need to be send.
  24. *
  25. * @retval      The characters that need to be send.
  26. *
  27. * @note
  28. */
  29. int __io_putchar(int ch)
  30. {
  31.     /* send a byte of data to the serial port */
  32.     UartX_Put_Char(DEBUG_USART, ch);
  33.     return ch;
  34. }


  35. int _write(int file, char* ptr, int len)
  36. {
  37.     int i;
  38.     for (i = 0; i < len; i++)
  39.     {
  40.         __io_putchar(*ptr++);
  41.     }
  42.     return len;
  43. }

  44. #elif defined (__ICCARM__)   /*For IAR */

  45. #include <LowLevelIOInterface.h>

  46. #pragma module_name = "?__write"

  47. int MyLowLevelPutchar(int x)
  48. {
  49.         UartX_Put_Char(DEBUG_USART, (uint8_t)x);
  50.     return x;
  51. }


  52. /*
  53. * If the __write implementation uses internal buffering, uncomment
  54. * the following line to ensure that we are called with "buffer" as 0
  55. * (i.e. flush) when the application terminates.
  56. */

  57. size_t __write(int handle, const unsigned char *buffer, size_t size)
  58. {
  59.   /* Remove the #if #endif pair to enable the implementation */
  60. #if 1

  61.   size_t nChars = 0;

  62.   if (buffer == 0)
  63.   {
  64.     /*
  65.      * This means that we should flush internal buffers.  Since we
  66.      * don't we just return.  (Remember, "handle" == -1 means that all
  67.      * handles should be flushed.)
  68.      */
  69.     return 0;
  70.   }

  71.   /* This template only writes to "standard out" and "standard err",
  72.    * for all other file handles it returns failure. */
  73.   if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
  74.   {
  75.     return _LLIO_ERROR;
  76.   }

  77.   for (/* Empty */; size != 0; --size)
  78.   {
  79.     if (MyLowLevelPutchar(*buffer++) < 0)
  80.     {
  81.       return _LLIO_ERROR;
  82.     }

  83.     ++nChars;
  84.   }

  85.   return nChars;

  86. #else

  87.   /* Always return error code when implementation is disabled. */
  88.   return _LLIO_ERROR;

  89. #endif

  90. }

  91. #else

  92. #warning Not supported compiler type

  93. #endif

最后,看一下演示效果吧:

 楼主| caizhiwei 发表于 2023-7-14 21:43 | 显示全部楼层
赞一个
 楼主| caizhiwei 发表于 2023-7-14 21:45 | 显示全部楼层
很奇怪,图附不上去,来来回回折腾我5次了,哎
 楼主| caizhiwei 发表于 2023-7-14 21:46 | 显示全部楼层
再试试看: 微信图片_20230714214541.jpg
 楼主| caizhiwei 发表于 2023-7-14 21:48 | 显示全部楼层
试试看: 微信图片_20230714214823.png
 楼主| caizhiwei 发表于 2023-7-14 21:49 | 显示全部楼层
右键粘贴的图,导致发帖失败,BUG
 楼主| caizhiwei 发表于 2023-7-15 09:03 | 显示全部楼层
printf.rar (1.36 KB, 下载次数: 3)
tpgf 发表于 2023-8-9 18:20 | 显示全部楼层
这种数据输出的速度收到通讯方式的限制吗
nawu 发表于 2023-8-10 09:19 | 显示全部楼层
打印的时候可以将时间戳打印出来吗
aoyi 发表于 2023-8-10 09:52 | 显示全部楼层
printf 重定向的新的要求的具体内容是什么呢
 楼主| caizhiwei 发表于 2023-8-10 09:55 | 显示全部楼层
nawu 发表于 2023-8-10 09:19
打印的时候可以将时间戳打印出来吗

可以,但是需要移植一个开源库easylogger
tfqi 发表于 2023-8-10 11:49 | 显示全部楼层
如果附图上不去的话  可以打包发送附件吧
磨砂 发表于 2023-8-10 12:10 | 显示全部楼层
for循环中变量的自减会不会出问题  数据类型是什么
晓伍 发表于 2023-8-10 13:46 | 显示全部楼层
这个型号的单片机和st的f407可以兼容吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

856

帖子

16

粉丝
快速回复 在线客服 返回列表 返回顶部

100

主题

856

帖子

16

粉丝
快速回复 在线客服 返回列表 返回顶部