搜索
bottom↓
回复: 39

关于printf函数转重定向到串口我在此讲一下!!!

  [复制链接]

出0入0汤圆

发表于 2012-5-31 20:58:17 | 显示全部楼层 |阅读模式
   玩过STM32的应该都是知道的关于把串口重定向到printf函数那边,但是发现单片机的比较少的,但是我还是想用一下。当然printf函数的用处和好处就不必多说了!!他可以输出任意的字符,16进制数,浮点数,包括各式的定义等等。
  好了!废话不多说了下面我就以实际例子讲一下。但是还得告诉大家我的设备。单片机是STC12C5204AD。用的是keil2虽然老了点但是本人用着可以。
  先上一张图片吧!!
     这张图片包含了一下数据要仔细看清楚啦!!上面有AD的转换数据,P1口的状态值,波特率设置值,EEPROM读取的数值。上面的所有数据都是通过printf函数打印到串口助手上面如果不用printf函数就会是很麻烦的事情。用的话就会简单多了。
   接下来我们讲程序的实现。首先就是串口的实现,AD转换的实现,波特率的设置,再次我就不在啰嗦,不懂的去网上自己去找吧!!很多很多。。比我讲的都好!!
    单片机的串口重定向比较简单就是不容易想到。来一张图片看一下。这是重定向函数是吧很简单。就是在你配置完串口的时候首先写一个数到SBUF寄存器中然后在用printf函数打印就可以,当让这个顺序是不可以变的,如果你想在追问细节为什么,我只能告诉你这应该是开发环境决定的,这一点我就理解这么多,如果有大侠给出更好的解释我也一起共勉。
   现在我们来看一下这个程序结构。
   首先是串口配置完成。调用重定向函数。就把串口定向到了printf函数了。我在printf函数里面加上了“串口初始化完毕”。
    好了现在我们看一下我的串口数据打印情况。仔细看第一行数据就能看到我打印出的字符。并且还能看到程序走的步骤,走到哪一步了,都能得到而且很方便。
   所有的一切都搞定了就可以进行AD转换了。就会看到最长的哪一个字符串,就是我在开始讲的那一串字符数据,程序如下完全是C语言的printf风格。
   printf("\rEMD电子科技 AD_Data: %f V P1: %X Boud_Rate: %d Eeprom: %d\n",(float)(AD_Data),(uint)(P1),(uint)(Boud_Value),(uint)(temp1));
   经过以上讲解大家就可以随意使用串口打印自己想要的东西啦!!!!
   如有更好的望高手提出共同学习!!!
   最后上程序吧!!!
   
  说明一下本程序只是文本文档不是工程,当然源码不会少的,建立工程立马可用。。。。。欢迎大家交流学习。
   

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2012-5-31 21:36:42 | 显示全部楼层
自己先顶一下!!!

出0入0汤圆

发表于 2012-5-31 21:51:03 | 显示全部楼层
shi_90 发表于 2012-5-31 21:36
自己先顶一下!!!

无符号长整型数据怎么显示

unsigned long n;

n = 123456789;

printf("%d",n);  或者  printf("%d",(unsigned long)(n));       

结果都显示:18838

出0入0汤圆

发表于 2012-5-31 22:41:50 | 显示全部楼层
printf("%ld",n);试试这个 不同编译器好像有点点差别!

出0入0汤圆

发表于 2012-6-1 00:04:49 | 显示全部楼层
这个是调用stdio的库函数吗?如果程序任务中本身就有串口中断,这样用会不会有冲突呢?

出0入0汤圆

发表于 2012-6-1 00:15:31 | 显示全部楼层
51都可以用printf啊,学习了~~

出0入0汤圆

 楼主| 发表于 2012-6-1 00:46:49 | 显示全部楼层
BXAK 发表于 2012-5-31 21:51
无符号长整型数据怎么显示

unsigned long n;

无符号长整型数据一般不能强制转换类型一般printf只是无符号整形数据(具体我倒没测试,测试完了再告诉你吧!!),再说单片机处理无符号长整型数据有点吃力啊!!!

出0入0汤圆

 楼主| 发表于 2012-6-1 00:49:27 | 显示全部楼层
danju 发表于 2012-6-1 00:04
这个是调用stdio的库函数吗?如果程序任务中本身就有串口中断,这样用会不会有冲突呢? ...

是调用的库函数,但是把出口定义到了串口,我不是很明白你说的这个程序任务本身什么意思??不过我测试的没发现冲突。。。。。

出0入0汤圆

发表于 2012-6-1 00:56:44 | 显示全部楼层
shi_90 发表于 2012-6-1 00:46
无符号长整型数据一般不能强制转换类型一般printf只是无符号整形数据(具体我倒没测试,测试完了再告诉你 ...

4楼的方法OK

出0入0汤圆

发表于 2012-6-1 13:08:03 | 显示全部楼层
shi_90 发表于 2012-6-1 00:49
是调用的库函数,但是把出口定义到了串口,我不是很明白你说的这个程序任务本身什么意思??不过我测试的 ...

我是说程序本身就有串口任务的,如果调试时用重定向打印,会不会有冲突?

另外想知道,这种重定向打印很方便,串口用的是中断模式?还是printf发送时要判断TI和等待?

出0入0汤圆

 楼主| 发表于 2012-6-1 13:46:09 | 显示全部楼层
danju 发表于 2012-6-1 13:08
我是说程序本身就有串口任务的,如果调试时用重定向打印,会不会有冲突?

另外想知道,这种重定向打印很 ...

在这种方式下无需判断TI直接打印就可以!!不过你也可以进中断清除TI。

出0入0汤圆

发表于 2012-6-1 15:51:20 | 显示全部楼层
就是在你配置完串口的时候首先写一个数到SBUF寄存器中然后在用printf函数打印就可以,当让这个顺序是不可以变的,如果你想在追问细节为什么,我只能告诉你这应该是开发环境决定的,这一点我就理解这么多,如果有大侠给出更好的解释我也一起共勉。

其实也不用首先写一个数据到SBUF寄存器,只需在串口初始化后,加上一句TI=1;即可。原因是printf函数事实上是调用putchar输出字符的。之所以能输出到串口上,就是因为putchar函数把字符通过串口输出。
这是keil中putchar最简单的版本,其他版本也一样,看函数就明白为什么要先让TI=1;了,楼主写的那个SBUF=0,原理是相同的,写入了数据,那么TI就等于1了,然后就可以使用putchar函数和printf函数了。
putchar函数的源码在{keil安装目录下}\C51\LIB文件夹里的PUTCHAR.C文件里,另外在keil的帮助文档里有说明
  1. char putchar (char c)  {
  2.   while (!TI);
  3.   TI = 0;
  4.   return (SBUF = c);
  5. }
复制代码

出0入0汤圆

 楼主| 发表于 2012-6-2 11:36:59 | 显示全部楼层
tlptotop 发表于 2012-6-1 15:51
其实也不用首先写一个数据到SBUF寄存器,只需在串口初始化后,加上一句TI=1;即可。原因是printf函数事实上 ...

谢谢!!学习了!!

出0入0汤圆

发表于 2012-6-2 11:57:41 | 显示全部楼层
这个东西不错。可以学习学习。

出0入0汤圆

发表于 2012-7-2 20:15:32 | 显示全部楼层
有空学习一下!

出0入0汤圆

发表于 2013-4-19 15:03:15 | 显示全部楼层
MARK一下

出0入0汤圆

发表于 2013-4-20 17:06:45 | 显示全部楼层
MARK一下

出0入0汤圆

发表于 2013-8-13 09:52:18 | 显示全部楼层
试过了,果然可以,非常感谢

出0入0汤圆

发表于 2013-8-13 13:51:07 | 显示全部楼层
正在找这个呢 谢谢

出200入0汤圆

发表于 2013-8-13 14:10:10 来自手机 | 显示全部楼层
学习收藏

出0入0汤圆

发表于 2013-11-5 20:26:41 | 显示全部楼层
学习收藏

出0入0汤圆

发表于 2013-11-8 19:38:49 | 显示全部楼层
不错哦               

出0入0汤圆

发表于 2013-11-8 22:43:52 | 显示全部楼层
keil C51里面好像可以直接用printf 吧

出0入0汤圆

发表于 2014-1-13 21:47:24 | 显示全部楼层
应该叫 I/O 重定向到 uart 吧,怎么说成 uart 重定向到 printf 呢?

出0入0汤圆

发表于 2014-4-28 23:51:28 | 显示全部楼层
tlptotop 发表于 2012-6-1 15:51
其实也不用首先写一个数据到SBUF寄存器,只需在串口初始化后,加上一句TI=1;即可。原因是printf函数事实上 ...

mark,函数转重定向,好东西。留名学习。

出0入0汤圆

发表于 2014-5-6 15:00:50 | 显示全部楼层
mark                                

出0入0汤圆

发表于 2014-5-27 00:03:00 | 显示全部楼层
学习了,碉堡了

出0入0汤圆

发表于 2014-8-12 12:03:31 | 显示全部楼层
Mark 上回看过,重新在看一次

出0入0汤圆

发表于 2014-8-14 10:01:25 | 显示全部楼层
这哪叫重定向?其实这个是KEIL默认的功能,printf()就是输出至串口的,但使用前要做设置:
UART_Init();
TI = 1;
主要的就是TI这句,激活串口中断处理,楼主的做法繁琐了,没有真正理解。

出0入0汤圆

发表于 2014-8-18 17:38:39 | 显示全部楼层
BXAK 发表于 2012-5-31 21:51
无符号长整型数据怎么显示

unsigned long n;

谢谢分享,学习了...

出0入0汤圆

发表于 2014-8-18 18:39:04 | 显示全部楼层

51都可以用printf啊,学习了~~

出0入0汤圆

发表于 2014-11-8 12:45:57 | 显示全部楼层
这个要学习一下

出0入8汤圆

发表于 2014-11-8 12:47:48 来自手机 | 显示全部楼层
这个可以研究一下

出0入0汤圆

发表于 2014-11-10 17:12:54 | 显示全部楼层
想好好用用这个函数   谢谢分享。。。。

出0入0汤圆

发表于 2014-11-10 17:40:35 | 显示全部楼层
mark 一下,谢谢楼主分享

出0入0汤圆

发表于 2014-11-13 08:10:57 来自手机 | 显示全部楼层
这是重定向?调用printe前,ti是1就可以了。另外你试试让助手十六进制模式显示,目测会有很多0

出0入0汤圆

发表于 2015-2-27 16:37:47 | 显示全部楼层
想打印浮点数遇到了麻烦,只好找别人写好的东西。
楼主的办法我好像看的迷迷糊糊的,但是有启发,刚试出来一种办法
1、把C:\Keil\C51\LIB 目录下的putchar.c文件复制到工程目录下,然后加进工程,改写里面的芯片寄存器头文件包含(中国芯片的寄存器头文件#include "xxx.h")
2、在初始化串口函数的最后一句增加SBUF=0;这么一句,不加这一句是不行的。
3、包含头文件#include <stdio.h> 具体printf的参数可以搜索当前keil的帮助文档 里面很详细。
keil 版本是 V952,感觉比自己写的打印函数强大多了!

出0入0汤圆

发表于 2015-2-27 17:35:19 | 显示全部楼层
下班了!明天再看!!!

出0入10汤圆

发表于 2016-11-2 10:48:54 | 显示全部楼层
lize91 发表于 2015-2-27 16:37
想打印浮点数遇到了麻烦,只好找别人写好的东西。
楼主的办法我好像看的迷迷糊糊的,但是有启发,刚试出来 ...

解释的比较清楚  学习了

出0入0汤圆

发表于 2017-9-13 21:41:26 | 显示全部楼层
学习一下,调试方便
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 08:01

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表