打印

Q C51中printf跟直接用SBUF有什么区别?

[复制链接]
4736|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
a5566255|  楼主 | 2008-12-2 10:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我知道printf是格式化输出,那么我只要传一个8位数,它们是不是就没有区别?

另外有个很重要的,printf只要我用了,就会不停得往串口输出数,哪怕我没把它放在循环语句中是不?比如我这样:
while(1){
 while(RI){
     n=SBUF; 
     RI=0;
     t=read(n);
     delay(10000);
     printf("%d ",t);
          }
        }
我往串口只发一次数据,它就会不停的回复我数据(实测下来好像是的哦,不明白)??? 

相关帖子

沙发
zjw5000| | 2008-12-2 20:08 | 只看该作者

你用了个while(1)

当然为无限循环的printf

使用特权

评论回复
板凳
xiaoyu9466| | 2008-12-2 23:33 | 只看该作者

看库函数

库函数中的printf是不是直接向串口输出数据的
如果用keil编译器,同时库函数没有更改,那就是肯定的

使用特权

评论回复
地板
a5566255|  楼主 | 2008-12-4 13:16 | 只看该作者

顶楼会了,是我看错了,它跟本没有重复发送。。。

但是我仍然很抓狂了。。。。。。。

郁闷的printf:
void main(void) 

uint t,n,i; 
uchar m; 
SCON=0X50; 
TMOD=0X20; 
TH1=0XFD; 
TL1=0XFD; 
TI=0; 
TR1=1; 
i=0; 
while(1){ 
while(RI){ 
    n=SBUF; 
    RI=0; 
    for(m=0;m <80;m=m+1) 
    { 
    TI=1; //这句不写接收端就收不到printf发的数,但把printf换成SBUF=123就可以,WHY?? 
    t=4000; 
    printf("%d ",t);//SBUF=123; 
    P3_2=1;    
    } 
          } 
        } 

如注释部分,学个单片机真难。。。。。。

使用特权

评论回复
5
a5566255|  楼主 | 2008-12-4 13:41 | 只看该作者

偶的猜想:

printf串口输出是采用中断方式,需要TI置位才能进入串口中断,
但这个函数本身被调用时确没有加入置位TI中断标志位的功能,所以需要自己在之前手动中断,
然后它被调用并执行完后却能自动清OTI退出中断。。。。。
请问各位大虾,如果是这样的话KEILC这么做什么意思???

使用特权

评论回复
6
a5566255|  楼主 | 2008-12-4 17:11 | 只看该作者

没人高人给新手解释下么。。。

使用特权

评论回复
7
mohanwei| | 2008-12-4 20:50 | 只看该作者

printf默认采用查询TI的方式进行发送。所以一定要先

把TI置位1次,才能使用printf。具体参考Keil的第一个例程即可(Hello,World!)

使用特权

评论回复
8
mohanwei| | 2008-12-4 20:52 | 只看该作者

printf会调用putchar函数来输出,库目录下有源码

你也可以在你的工程里使用自己写的putchar函数,从而实现一些特殊功能,例如让printf输出到液晶模块上、输出到数码管上、输出到I/O口……等等

使用特权

评论回复
9
walnutcy| | 2008-12-4 20:57 | 只看该作者

去看下printf源码了,别在那瞎猜了

使用特权

评论回复
10
quakegod| | 2008-12-5 03:19 | 只看该作者

我从来不用那个printf

因为printf默认使用的是查询方式,会一直等待串口,直到发送最后一个字符,
白白浪费MCU时间,试想我们现在用的最高的波特率也就是115200bps,很多时候用的是9600bps,然而晶振都是24MHz,甚至用1T的MCU,使用printf,9600bps发送10个字符需要10.4mS的时间,相当于250000个时钟周期,即使用115200bps也需要0.868mS,20833个时钟周期。所以我宁可在内存里面开辟出16个字节的串口缓冲区,然后用中断的方式来处理。
当然了,如果你不停得往串口发数据,或者一次发送了16个字节以上的数据,串口缓冲区满了,那你还是会停下来等待缓冲区,不过即使这样,你也能在两次发送之间获得很多时钟周期的好处。
我现在凡是涉及串口输出的程序都使用自己的串口缓冲程序,
具体性能没有测试,基本上在串口跑到90%流量的时候,其他程序还能得到90%的MCU时间。

使用特权

评论回复
11
xwj| | 2008-12-5 08:44 | 只看该作者

quakegod ,Keil的printf是中断方式的!

只是51的串口收发是同一个中断,所以需要用RI、TI来判断是接收还是发送触发的中断

首次使用必须置位TI,就是为了人为触发中断程序


不过呢... 
偶也更喜欢使用自己的串口缓冲程序

使用特权

评论回复
12
a5566255|  楼主 | 2008-12-5 08:59 | 只看该作者

LS大虾好厉害啊

学习!
不过是汇编的耶~~

使用特权

评论回复
13
mohanwei| | 2008-12-5 09:05 | 只看该作者

楼上各位可能还不明白printf的工作原理……

最终发送的实际是putchar()……改一改putchar,就可以实现查询、中断、队列……所有你喜欢的算法。

使用特权

评论回复
14
xwj| | 2008-12-5 09:33 | 只看该作者

是的,LS正解

发送改putchar(),接收改getchar()即可

问题是偶更喜欢用自己写的数据流处理程序,按需配置,充分利用资源

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

218

帖子

1

粉丝