目录

  • 写在前面
  • 半主机模式介绍(可以跳过)
  • 串口接收初始化
  • 串口发送重定向
  • 主程序
  • 连好开发板
  • 运行效果

写在前面

通常工程师在做产品开发和程序调试的时候会通过仿真器进入仿真模式来获得芯片运行的结果,从而判断程序编写的是否正确。但是有些特殊的情况仿真器的作用就不大,例如下面这几种情况:

  • 华大MCU芯片进入深度休眠后,仿真器接口将会关闭,工程在调试状态会因为仿真接口的关闭退出调试状态,芯片唤醒后工作的情况将观察不到;
  • 需要实时观察芯片数据的情况,如采集的电池实时电压情况;
  • 不方便接仿真器的情况,如运动小车项目中对车身状况的监控等;
  • 仿真器管脚已经被占用的情况;
  • 程序执行错误的情况等。

遇到仿真器不方便调试的时候我们一般会利用板子上的某个硬件做为输出,通过观察这个输出来判断程序运行的是否正常。如果程序运行到某一状态可以点亮板子上的LED灯,或翻转下某个IO,如果板子上有屏那就更好,直接可以在屏上显示自己想要知道的内容。还是一种方法就是使用UART把数据传输出去。如果UART接了无线模块还可以进行远距离的观测,就像上面提到的运动小车项目。当然使用UART只做普通方式的传输数据的话,数据是不包涵任何格式内容的,我们要解读的时候会费点力气。那有没有什么好办法,让输出的数据直观明了呢?没错,就是用我们学习C语言时候的老朋友printf来做格式化输出。


半主机模式介绍(可以跳过)

因为MCU本身资源的限制,在MCU上运行的C语言代码和在计算机上还是有区别的。这就涉及到一种叫半主机的机制,它使得在ARM目标上跑的代码,如果主机电脑运行了调试器,那么该代码可以使用该主机电脑的输入输出设备。 这点非常重要,因为开发初期,可能开发者根本不知道该 ARM 器件上有什么输入输出设备,而半主基机制使得你不用知道ARM器件的外设,利用主机电脑的外设就可以实现输入输出调试。 所以要利用目标 ARM器件的输入输出设备,首先要关掉半主机机制。然后再将输入输出重定向到 ARM 器件上,如 printf 。需要重写 fputc。
printf之类的函数,使用了半主机模式。使用标准库会导致程序无法运行 ,以下是解决方法 :
方法 1.使用微库 ,因为使用微库的话 ,不会使用半主机模式 .
如果使用的是 MDK,请在工程属性的 “Target “- >”Code Generation “中勾选 ”Use MicroLIB “这样以后就可以
使用 printf ,sprintf 函数了
方法 2.仍然使用标准库 ,在主程序添加下面代码 :
/*为确保没有从 C 库链接使用半主机的函数,因为不使用半主机,标准 C 库 stdio.h 中有些使用半主机的
函数要重新写 ,您必须为这些函数提供自己的实现 */

#pragma import(__use_no_semihosting)
void _sys_exit(int x)
{x = x;
}
struct __FILE
{int handle;/* Whatever you require here. If the only file you are using is *//* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef?d in stdio.h. */
FILE __stdout;

在独立应用程序中,不可能支持半主机操作。 因此,必须确保应用程序中没有链接 C 库半主机函数。
为确保没有从 C 库链接使用半主机的函数, 必须导入符号 __use_no_semihosting 。可在工程的任何 C 或汇编语言源文件中执行此操作,如下所示:
在 C 模块中,使用 #pragma 指令:
#pragma import(__use_no_semihosting)
在汇编语言模块中,使用 IMPORT 指令:
IMPORT __use_no_semihosting
如果仍然链接了使用半主机的函数,则链接器会报告错误。


串口接收初始化

现在以HC32L136芯片来介绍如何实现printf格式化输出。先做UART的初始化,这里用的是UART0,使用PA09做为TX信号,初始化代码如下:

void AppUartInit(void)
{stc_uart_cfg_t  stcCfg;stc_uart_baud_t stcBaud;    stc_gpio_cfg_t stcGpioCfg;DDL_ZERO_STRUCT(stcGpioCfg);DDL_ZERO_STRUCT(stcCfg);DDL_ZERO_STRUCT(stcBaud);Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);stcGpioCfg.enDir = GpioDirOut;Gpio_Init(GpioPortA,GpioPin9,&stcGpioCfg);Gpio_SetAfMode(GpioPortA,GpioPin9,GpioAf1); //配置PA09 为UART0 TXSysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);//UART0外设模块时钟使能stcCfg.enRunMode        = UartMskMode3;                     //模式3stcCfg.enStopBit        = UartMsk1bit;                      //1位停止位stcCfg.enMmdorCk        = UartMskEven;                      //偶校验stcCfg.stcBaud.u32Baud  = 9600;                             //波特率9600stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;                  //通道采样分频配置stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();            //获得外设时钟(PCLK)频率值Uart_Init(M0P_UART0, &stcCfg);                              //串口初始化}

串口发送重定向

知道半主机是怎么回事以后,把ddl.c里的fputc函数给屏蔽掉,因为它没啥用,我们自己来写一个,自己能动手,不用麻烦别人。屏蔽掉ddl.c文件中的fputc()函数,如下图

自己重写fputc函数,就是下面的代码,看了什么感想?哇塞,怎么这么简单?

///< 串口发送重定向
int fputc(int ch, FILE * file)
{Uart_SendDataPoll(M0P_UART0,ch);         //调用库函数,通过UART0发送一个字母。return ch;
}

主程序

上面工作完成后写个非常简单的主程序我们来验证一下。代码如下:

int32_t main(void)
{   uint8_t i = 0;AppUartInit();                                    //调用串口初始化函数printf("Init Sucessful \r\n");                      //输出Init Sucessfuldelay1ms(1000);while (1){printf(" i = %d \r\n", i);                    //格式化输出i的值i++;delay1ms(1000);}}

连好开发板


运行效果


关注微信公众号『芯缘意码』,查看更多内容,回复“加群”加入技术交流群。
淘宝 店铺 搜索 『芯缘意码』,购买开发学习板仿真器。


华大单片机HC32L136如何做printf串口打印格式化输出相关推荐

  1. 华大单片机、STM32单片机如何做printf串口打印格式化输出

    第一种方法:使用标准C库,但使用标准C库你必须关闭半主机模式 (1)添加下面代码就是关闭半主机模式 /* 告知连接器不从C库链接使用半主机的函数 */ #pragma import(__use_no_ ...

  2. 华大单片机HC32L136定时器时间如何计算

    目录 介绍 定时器的时钟 模式 0 计数定时器功能 与定时器0模式0有关的寄存器及相应位 定时器时间计算 配置流程 定时器0配置初始化代码 定时器0中断服务函数 主程序中调用调用定时器0并运行 简便计 ...

  3. 国产超低功耗华大单片机HC32L136开发板上手入门

    今天介绍下国产超低功耗华大单片机HC32L136开发板上手后的入门操作(开发板可以在华大MCU应用交流群:164973950 免费申请).HC32L136开发板(如下图所示)分为板载调试模块(左半部分 ...

  4. shell printf命令:格式化输出语句

    printf 命令用于格式化输出, 是echo命令的增强版.它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同. 注意:printf 由 POSIX 标准所定义,移植性要比 ech ...

  5. 华大单片机HC32L136笔段式段码LCD显示

    目录 华大单片机LCD简介 LCD 主要特性 LCD 框图 LCD 驱动波形 LCD Bias 产生电路 内部电阻模式 外部电容模式 外部电阻模式 LCD三种驱动方式对比 LCD显示模式 LCD 显示 ...

  6. STM32移植时printf串口打印中文乱码,mark一下

    STM32移植后,使用printf进行串口打印,中文显示乱码: 移植时是先新建.txt文档,复制完代码后改为.c文件,查找相关资料,得知.c文件为"UTF-8"编码,需要将编码格式 ...

  7. C语言printf()格式化输出

    printf()函数 请求printf()函数打印数据的指令要与待打印数据的类型相匹配.例如,打印整数时使用%d,打印字符时使用%c.这些符号被称为转换说明(conversion specificat ...

  8. 51单片机 DHT11温湿度传感器LCD显示+串口打印显示

    第一部分:DHT11详解: DHT11是一款有已校准数字信号输出的温湿度传感器. 精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH, 温度0~50℃. **一.电路连接分析 1.引脚图** ...

  9. 华大单片机如何实现软件复位重启

    工程师朋友在做产品的时候,有些特殊的场合对单片机有重启(复位)的需要,以达到保证产品的功能可以正常的实现.重启可以通过硬件和软件两种方法来实现.对于华大单片机大家都知道硬件的重启,只要把RESET引脚 ...

最新文章

  1. vue 搭建脚手架 的教程
  2. IOS应用之二--sqlite的创建数据库,表,插入查看数据
  3. 10个超级有用、必须收藏的PHP代码样例
  4. 不同页面之间实现参数传递的几种方式
  5. 【SQL】分组数据,过滤分组-group by , having
  6. PXE(preboot execution environment):【网络】预启动执行环节:引导 live光盘 ubuntu livecd 16.4:成功...
  7. 再有人问你为什么MySQL用B+树做索引,就把这篇文章发给她
  8. 2016拜拜,2017我来
  9. React:引入echarts绘制图表
  10. 等保2.0二级通用要求
  11. APP抓包教程 windows + mimtproxy +夜神模拟器 + XposedInstaller + JustTrustMe
  12. 上海航芯|物联网安全芯片ACL16简介
  13. sfpatcher:针对应用商店的apk增量算法
  14. 《Google软件工程》读书笔记
  15. StoneDB完成华为鲲鹏国产处理器适配认证!
  16. 企业级存储发展趋势谈:开源存储的冷思考
  17. 目标检测评价指标(一文看懂)
  18. H3C无线控制器支持的认证方式
  19. Eclipse SVN插件: Subversive 4.0.4(支持dropins安装)
  20. 基于vue+elementui+admin的axios封装

热门文章

  1. 【22SR】Revisiting RCAN: Improved Training for Image Super-Resolution
  2. ROS机器人自主定位导航
  3. ASP简体转繁体函数
  4. Default mode network (默认网络)
  5. 野火学习笔记(4) —— 固件库
  6. 线代——基础解系 vs 特征向量
  7. Electron应用中实现调用外接摄像头并拍照上传
  8. 如何使用“时间机器”备份Mac电脑
  9. 一个小的发现,求各位大佬来解答
  10. Angular官网教程示例知识点总结