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

自定义函数,替代printf函数

[复制链接]
lusonghua 发布时间:2015-7-13 17:29
大家在调试时一般用了不少printf函数吧,在keil里怎么用printf,以及怎么重定向输出到串口上大家应该都比较熟悉了。- W% l) N4 r# i+ m
但在使用printf函数时大家还是小心一些,前几天在调试程序时碰到了在循环里使用printf函数调试导致程序堵死,折腾了好几天,后来问黑金的版主才知道问题出在printf函数上,注释掉就可以了。6 l/ o) s" b2 X3 {+ \7 q

' _2 ^' Y$ l/ B- O/ r) |这里我贴上一些代码,用自定义的函数替代printf,希望对大家有些帮助。1 I( |9 D# W. k$ @
  |3 q# [, p' b/ a
void cli_puts(char* sz): f! H. @& U% |9 c2 J4 t. H1 M
{3 \# z, F2 U* N8 y. \
/* 这里添加在某串口输出字符串的代码 */
: n8 j8 {* }( C" l/ f1 A    char c;- |' u' O* H5 v  X
    while ((c = *sz++) != 0) {
4 a) ~3 Z: i1 M9 |5 N+ Q         while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
0 Q+ L/ T, b# M) \  N7 ]. }- P5 b) i         USART_SendData(UART5, (uint16_t)c);5 M' ~) Z- F$ C5 {% K
    }" F! @6 R$ t: K+ [, f
}
: p! t0 N5 F. n- r% k  l/ ?9 k3 m: s- R' o5 j% Y! O8 A3 {1 E
void cli_echo(const char* fmt, ...)* `- ^2 }& O) H$ S0 u& [# y3 }9 a; y; u
{
+ H" {: v3 [3 Y6 [static char sz[1024] = { 0, };
, l: q- d7 c: F3 R( j$ @/* 组合使用可变参数以及vsprintf,实现printf */5 z7 `7 k# ~, m! F
va_list ap;- ]# q0 K; D$ F# x0 K* t/ U
6 c6 q+ L* }4 A! [2 G
va_start(ap, fmt);
7 R3 M( z) O, {% j% N vsprintf(sz, fmt, ap);
& Q+ b  B+ ?: U0 |. w cli_puts(sz);
, b/ g9 C$ B0 U3 F1 P va_end(ap);
9 o/ N% @( [; u) ?. ]- L8 Q}( R- v% H% p9 V% y
3 g9 @3 {$ Y, U: I+ j. _
上述cli_echo函数即可以替代printf函数的功能。
; p' Y5 L- j. m& C
3 U5 y) `. C3 L! h& [5 n( U7 n- q" G/ H% N

1 M/ E( y8 |! C
赞 收藏 1 评论20 发布时间:2015-7-13 17:29

举报

20个回答
嘉木香 回答时间:2017-4-5 16:06:10
老师教的串口调试的用法:
+ V4 H7 C3 _7 k  Z- D前提:STDIO.H,自建的发送字符串函数;/ R  B- l+ T& Z' L% o4 k: j
使用方式:
) u4 g4 c0 |) m, [步骤:1.调用sprintf()函数,此函数用法与printf()基本一致,两者输出不同,Printf()函数直接硬件输出,sprintf()输出到其形参字符串中;
* N, n& W6 K( h$ M1 {% B' s0 \9 B2.输出sprintf()中的形参字符串;
. R: e$ d: @" F附STDIO.H中printf(),sprint()的定义,区别之处以加粗倾倒发红* b% R1 J3 T" U, J* Z8 ]' I5 C
extern int printf   (const char *, ...);9 m9 X; K2 I0 [; g7 F; I
extern int sprintf  (char *, const char *, ...);
, B& J7 X& D! O: ~, K
gavinliang 回答时间:2017-4-5 16:32:28
void cli_echo(const char* fmt, ...)& X' J  Q- G; j
{
" a7 y9 n% y7 w# ]static char sz[1024] = { 0, };+ ~# g& |1 j6 s- L8 }4 B  O* W: T, T
/* 组合使用可变参数以及vsprintf,实现printf */
0 `# L& a" g5 O+ N) \, a4 Ova_list ap;2 e/ H+ Q) O; ~( b

5 m' a8 E' `# ]- Wva_start(ap, fmt);! l7 y; Y+ Z9 [/ j
vsprintf(sz, fmt, ap);
2 \4 U- n7 }& F% n6 G0 p8 j2 Jcli_puts(sz);
4 Z/ g: v3 O. v) v2 D4 _4 C! f$ lva_end(ap);% G! R( `' E5 s5 ~
}/ h! l$ X; R# t: ]

* U9 D7 w( s: B; p这个没看明白。知道是格式组合,但具体 每一个函数怎么实现的?
嘉木香 回答时间: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 手机版