你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

自定义函数,替代printf函数

[复制链接]
lusonghua 发布时间:2015-7-13 17:29
大家在调试时一般用了不少printf函数吧,在keil里怎么用printf,以及怎么重定向输出到串口上大家应该都比较熟悉了。* x2 R. b4 \% Q
但在使用printf函数时大家还是小心一些,前几天在调试程序时碰到了在循环里使用printf函数调试导致程序堵死,折腾了好几天,后来问黑金的版主才知道问题出在printf函数上,注释掉就可以了。
. M2 m; o! q. t. P+ d
& _: w, S3 _6 X: }4 W; Y, u这里我贴上一些代码,用自定义的函数替代printf,希望对大家有些帮助。
  a# D  [$ l7 M7 L) ?" Z! h' ~7 C
  ?  F7 c5 l5 Y) e8 _1 j8 `void cli_puts(char* sz)
; G% ^0 b5 T" v/ U3 h  _{, d' N/ O9 X6 j1 b
/* 这里添加在某串口输出字符串的代码 */
  m- E0 V. y$ Q6 K; M1 g& t    char c;
3 _5 d/ N& n* M/ K    while ((c = *sz++) != 0) {4 {. B& s0 @/ g+ y% e- @5 |
         while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);9 Q' T0 v% E% W* c
         USART_SendData(UART5, (uint16_t)c);9 G  \3 t5 h- X9 G
    }, l9 r# e# @- U  i! Z, u5 j
}
/ o1 H, Y, n6 o2 C$ S, ~
$ |" }% Z7 p* ~9 U+ B# o# I- lvoid cli_echo(const char* fmt, ...)
! x2 Y3 O. K2 C* ^) U- Y1 E{
  j  ]* D; g" |1 M5 lstatic char sz[1024] = { 0, };" A8 ^3 e$ i/ m, P; S
/* 组合使用可变参数以及vsprintf,实现printf */
2 M- W3 y3 A1 v' P$ h. F6 X va_list ap;3 h4 j& u) ]0 C, V  d

( F! }2 T/ m6 P. S va_start(ap, fmt);5 ~1 d3 f0 W: L4 v
vsprintf(sz, fmt, ap);   z0 C6 X& _6 b) Z) c- o4 p3 Z
cli_puts(sz);) |* ]- y# o. F  x, W
va_end(ap);  c: X$ Q: r  ~5 j
}: z4 n( M- v) c! D1 q  D3 d% f

$ ]3 }* U$ M* j6 [/ o上述cli_echo函数即可以替代printf函数的功能。+ [1 f2 C' k3 j* G/ F
; q' p, S, y7 |+ m
! [1 Y- S# u2 Y9 f% g' I1 ~

) B5 b2 H! x+ q1 @/ v) l: i; k0 i$ ?3 R
赞 收藏 1 评论20 发布时间:2015-7-13 17:29

举报

20个回答
嘉木香 回答时间:2017-4-5 16:06:10
老师教的串口调试的用法:
8 o( u4 i" }) c( n# h2 G8 V& X/ D前提:STDIO.H,自建的发送字符串函数;
- z6 ^+ f! [" @. `" l使用方式:
( W. g3 i! l3 H  j) K( b5 ^, J步骤:1.调用sprintf()函数,此函数用法与printf()基本一致,两者输出不同,Printf()函数直接硬件输出,sprintf()输出到其形参字符串中;
& D+ |/ K! D  C: a/ S+ Z4 _4 ^" J, C2.输出sprintf()中的形参字符串;
7 o, p: }% L- ~附STDIO.H中printf(),sprint()的定义,区别之处以加粗倾倒发红5 G9 P, r; g1 X. l4 y8 S5 G
extern int printf   (const char *, ...);
( g' g3 A: v8 H1 r) Hextern int sprintf  (char *, const char *, ...);

/ }9 d4 _+ i% Z4 p0 C: A. v
gavinliang 回答时间:2017-4-5 16:32:28
void cli_echo(const char* fmt, ...)
5 L2 P+ ^: x- p% O{. {1 J! h% E. P) M. b* r
static char sz[1024] = { 0, };
8 k- I3 t$ p% c( R" k3 N1 i/* 组合使用可变参数以及vsprintf,实现printf */" x1 Y: T5 {+ n) T" p8 e
va_list ap;& t/ a* H# p( N0 y/ v$ ^+ u

& W5 Q9 [9 C  pva_start(ap, fmt);
& I+ V- E4 G, P; k0 r/ G- Lvsprintf(sz, fmt, ap);
' O8 I  W! l: qcli_puts(sz);
4 p" C. `  J* y. @va_end(ap);
# H8 E3 s& k; [& o$ D6 r}
/ m5 P) d' B. i7 T4 N3 r
0 q! ~# ~6 p7 X, I) S9 {. y4 ]这个没看明白。知道是格式组合,但具体 每一个函数怎么实现的?
嘉木香 回答时间:2017-4-5 16:09:05
补充一下,这个方法比重定向更为方便,而且不受输出数量限制;相比较自己编写而言,又极大化的利用了标准库,个人及其喜欢。
笑鸟007 回答时间:2015-7-13 18:33:30
好厉害!!!
mark0668 回答时间:2015-7-13 19:06:24
某些代码是会和printf有冲口 ,具说是用了内置内存管理发生冲突的.今天我也遇到了.
wyxy163@126.com 回答时间:2015-7-13 19:14:49
提示: 作者被禁止或删除 内容自动屏蔽
jiaswang 回答时间:2015-7-14 08:35:09
一直没用过printf在keil里……
stary666 回答时间:2015-7-14 12:08:29
看看,,,,,,,
HenryChen 回答时间:2015-7-14 17:58:02
学习一下,
天涯水乡 回答时间:2015-7-14 18:04:33
不错,顶一下
Rlews 回答时间:2015-7-14 22:57:01
学习学习~~
moyanming2013 回答时间:2015-7-14 23:26:57
哈哈,变相的好做法,不过可以不用自己再写个cli_puts()函数了,直接把sz用print输出即可吧
Tension 回答时间:2015-7-15 11:59:16
之前用SWD调试时,用printf()得比较多,现在已经转到更快的方式了。
不撸僧 回答时间:2015-7-15 14:13:20
一直用printf 挺好用的 还没发现问题
yanhaijian 回答时间:2015-7-15 15:59:39
只要对fputc、fgetc这两个函数进行重定义就可以了。
gavinliang 回答时间:2017-4-5 13:57:42
一直在使用printf()函数,没发现有什么问题,只是编译时,占比较多空间,这是最不好的。
12下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版