完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
对于 printf() 函数我们并不陌生,初学C语言使用的第一个函数,其作用是在终端打印显示格式化字符串。 但是如果我们使用的是单片机运行C语言代码,如果不经任何修改直接使用 printf() 函数,结果是什么现象都没有。要想使用这个函数,常规方法是重定向 printf() 函数,结合串口来打印到串口助手上位机。这里的重定向就非常复杂了,你需要懂 printf() 函数内部实现机制。。。。。(参考正点原子的例程,本人表示看不懂太多太复杂了) 接下来我介绍一种特别简单的方法,让你不需要重定向 printf() 函数也可以实现相似的功能,就是那种%d,%f,%c。。。各种格式控制符的功能,我们想用这个函数大半原因就是为了这些功能。只要在合适的地方添加以下语句即可: #define _DEBUG_ 1 //串口打印宏函数开关,1是开,0是关,调试的时候开,调式完毕就可以一键关闭 uint8_t USART_TX_BUF[200]; //发送缓冲,最大200字节,不能太小,如果你的内容太长会访问非法内存 #if _DEBUG_ #define ps(...) HAL_UART_Transmit(&huart1,USART_TX_BUF,sprintf((char *)USART_TX_BUF,__VA_ARGS__),1000)//可修改到其他串口 #else #define ps(...) #endif 以上代码表示用 ps() 这个宏函数代替HAL库的串口发送函数,并且可以使用格式控制符%c,%d,%f,r,n等可变参数控制符。 ps()宏函数使用方法如下: while (1) { num++; ps("串口打印宏函数 rn");//无参数打印,rn表示换行 ps("num = %d rn",num);//含参数%d HAL_Delay(500); } 串口打印助手情况 如果上面看不懂我再解释一下原理: 核心内容:变参宏 “__VA_ARGS__” 与 “...” 1.首先三个点 "..." 在C语言中代表“参数个数可变的参数”,我们可以看一下printf()函数的原型: int printf(const char* format,...);//printf()函数声明原型 //使用printf函数的方法 int num1; printf("num1 = %d rn",num1);//一个参数时,参数是整型 float num2; printf("num2 = %f rn",num2);//参数是浮点型 printf("num1 = %d,num2 = %f rn",num1,num2);//两个不同类型的参数时 printf("Hello World rn");//无参数时 由上述代码可以知道,"fomat"表示只读类型的字符串,而三个点 “...” 表示个数未确定的参数,可以没有参数,也可以有多个。 2.__VA_ARGS__是三个点"..."的宏定义形式。也就是说宏定义中的__VA_ARGS__会被替换成"..." #define ps(format,...) printf(format,__VA_ARGS__)//第1种方法,有些C标准不支持要加## #define ps(format,...) printf(format,##__VA_ARGS__)//第2种方法,##可以防止无参数时编译出错 #define ps(...) printf(format,__VA_ARGS__)//第3种方法 #define ps(...) printf(format,##__VA_ARGS__)//第4种方法 #define ps(...) printf(__VA_ARGS__)//第5种方法 #define ps(...) printf(##__VA_ARGS__)//第6种方法 以上六种都可以用 ps() 代替 printf() 函数,功能以及用法一模一样。C标准不一样的时候可能会有差别,总之编译出错时在以上6种之中更换即可。我只用第1、2、5这三种方法。 3.其实在单片机之中如果不重定向 printf() 函数。我们只要使用 sprintf() 函数即可: int printf(const char* format,...);//printf()函数声明原型 int sprintf(char *buffer,const char* format,...);//sprintf()函数声明原型 sprintf() 只是比 printf() 多一个参数,即第一个字符数组,他们两功能也相似,只是有以下区别: sprintf()----------》把内容转成字符串,并输出到一个字符数组中,返回字符串的字符个数; printf()------------》把内容转成字符串,并输出到显示终端,返回字符串的字符个数; 我们可以利用sprintf()的特点把要显示的内容转换成字符串,存到一个预先定义好的字符数组中,然后再用HAL库串口发送函数,把该字符数组内的信息发出去,发送的个数就是sprintf()的返回值: uint8_t USART_TX_BUF[200]; //发送缓冲数组,最大200字节 #define ps(...) HAL_UART_Transmit(&huart1,USART_TX_BUF,sprintf((char *)USART_TX_BUF, |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1932 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1705 浏览 1 评论
1185 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
785 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1750 浏览 2 评论
1992浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
826浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
279浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
637浏览 3评论
643浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-2 08:47 , Processed in 0.694970 second(s), Total 45, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号