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

自定义函数,替代printf函数

[复制链接]
lusonghua 发布时间:2015-7-13 17:29
大家在调试时一般用了不少printf函数吧,在keil里怎么用printf,以及怎么重定向输出到串口上大家应该都比较熟悉了。
6 ^4 F1 ~1 \. q: U) o但在使用printf函数时大家还是小心一些,前几天在调试程序时碰到了在循环里使用printf函数调试导致程序堵死,折腾了好几天,后来问黑金的版主才知道问题出在printf函数上,注释掉就可以了。$ F9 {  y4 i+ I' O4 ~% D- M
/ m- `5 B% A, y1 O" P
这里我贴上一些代码,用自定义的函数替代printf,希望对大家有些帮助。
- w, a- x" \. }. H
/ I* E. R% T% N$ C* K5 [void cli_puts(char* sz)0 `1 F) A9 I) `  ?/ i% `! I! g
{& q. z4 [. z/ _9 m5 T
/* 这里添加在某串口输出字符串的代码 */( s: [& h( [& b. ^
    char c;4 n. K' R$ w; t4 \
    while ((c = *sz++) != 0) {
6 |$ p" B; n$ I& f         while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);1 {; l, A' P1 R5 [# h- J- K
         USART_SendData(UART5, (uint16_t)c);# x' i4 l1 e2 i  b5 P
    }
$ J) |. L! M, j9 S9 L}
5 D% K: S+ m% v
$ N8 s+ Z- ?, H, A$ Q$ _void cli_echo(const char* fmt, ...)' a, H$ P" m# X* T$ C
{  D) p) W; l. l
static char sz[1024] = { 0, };
3 B8 \" A/ p! Y! Z: u8 ^' R# l( H, B( K/* 组合使用可变参数以及vsprintf,实现printf */
& Q% ^8 D. l& \, _$ t va_list ap;
! j6 X  x* Z) i . t! @! I, I- ]6 k$ X. o
va_start(ap, fmt);4 [1 V: r3 e7 P2 D" E
vsprintf(sz, fmt, ap); / Z7 Z: o6 i' S3 ~3 ]1 L
cli_puts(sz);
  Q. j* y! q( g) ~8 l; c/ j va_end(ap);
: b. B9 `5 f  x& ?}! m2 N0 ^; m0 `, {- d6 F
5 ?2 N! f: p& }- T/ m: o6 N
上述cli_echo函数即可以替代printf函数的功能。
4 M+ f" W* j. i6 l6 W, P) f- ^! y: b) Q- E4 ]$ i9 R$ e; J+ e' d

+ g6 K# n* Y: [+ q3 x
4 i. |  B. \3 R4 R# E# T7 y) h0 i
收藏 1 评论20 发布时间:2015-7-13 17:29

举报

20个回答
嘉木香 回答时间:2017-4-5 16:06:10
老师教的串口调试的用法:) L% K5 K( W8 d0 s, @- g# ?- {( N
前提:STDIO.H,自建的发送字符串函数;
+ E1 U- g: n4 ?8 s0 ~/ Q使用方式:2 I$ Q7 m7 n0 M. ?+ Z7 {2 T
步骤:1.调用sprintf()函数,此函数用法与printf()基本一致,两者输出不同,Printf()函数直接硬件输出,sprintf()输出到其形参字符串中;
3 [( W$ _) T& s1 [8 y+ e2.输出sprintf()中的形参字符串;0 m8 ?  s  G0 E7 l: D
附STDIO.H中printf(),sprint()的定义,区别之处以加粗倾倒发红
( \- L; s4 c4 V  G& u5 P2 k
extern int printf   (const char *, ...);
; s4 S1 L$ ]/ C! Zextern int sprintf  (char *, const char *, ...);

! j* x9 s; U) c) y6 I. H9 J  r4 n
gavinliang 回答时间:2017-4-5 16:32:28
void cli_echo(const char* fmt, ...)
9 c  r* c; R, C/ @; _& U! [{
5 p) C) h. l% e8 O2 m2 lstatic char sz[1024] = { 0, };3 ?+ I; ^3 [4 _
/* 组合使用可变参数以及vsprintf,实现printf */
! G# i! s! n; ?+ D6 x; W4 Qva_list ap;+ N9 r, {  s# D5 o1 a0 T

6 i1 Z, N5 ~9 \, @( Y' Xva_start(ap, fmt);
8 K! n7 ~8 _3 v* _! Yvsprintf(sz, fmt, ap);
& u! E( ?% j* I, f5 Z$ rcli_puts(sz);' \8 r' F5 `5 c1 N$ P
va_end(ap);
* F+ V9 k+ }6 x}9 m3 K' R  K/ l5 G' V& j: s
" R# c9 @1 [3 \9 V6 ]/ }4 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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版