历史上的今天
返回首页

历史上的今天

今天是:2025年06月10日(星期二)

正在发生

2018年06月10日 | STM32之串口通信之printf重定向

2018-06-10 来源:eefocus

当我们在学习一款CPU时,最经典的实验莫过于流水灯了,掌握流水灯的话就基本等于学会操作I/O口了,那么在学会I/O之后,相对于我们来说会把学习串口的操作放在第二位。在程序运行的时候我们可以点亮一个LED来显示代码的执行状态,但有时候我们还想把某些中间量后者其他程序状态信息打印出来显示在计算机上,那么这时候串口的作用就可显而知了。


下面我们来看一下什么是串口

串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。

与并口的区别:串口形容一下就是一条车道,而并口就是有8个车道同一时刻能传送8位(一个字节)数据。但是并不是说并口快,由于8位通道之间的互相干扰(串扰),传输时速度就受到了限制,传输容易出错。串口没有互相干扰。并口同时发送的数据量大,但要比串口慢。[3] 串口硬盘就是这样被人们重视的。

串口通信:串口通信(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进行传输数据的一种通讯方式。 

串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议。

串口通信协议:

在串口通信中,常用的协议包括RS-232、RS-422和RS-485。 

•RS-232:标准串口,最常用的一种串行通讯接口。有三种类型(A,B和C),它们分别采用不同的电压来表示on和off。最被广泛使用的是RS-232C,它将mark(on)比特的电压定义为-3V到-12V之间,而将space(off)的电压定义到+3V到+12V之间。传送距离最大为约15米,最高速率为20kb/s。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7kΩ。所以RS-232适合本地设备之间的通信。 

•RS-422:最大传输距离为1219米,最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能达到最大传输距离。只有在很短的距离下才能获得最高速率传输。一般100米长的双绞线上所能获得的最大传输速率仅为1Mb/s。 

•RS-485:从RS-422基础上发展而来的,最大传输距离约为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般100米长双绞线最大传输速率仅为1Mb/s。


数据传输通信方式:

(1)单工通信:

单工通信(Simplex Communication)是指消息只能单方向传输的工作方式。

在单工通信中,通信的信道是单向的,发送端与接收端也是固定的,即发送端只能发送信息,不能接收信息;接收端只能接收信息,不能发送信息。基于这种情况,数据信号从一端传送到另外一端,信号流是单方向的。

(2)半双工通信:


半双工通信(Half-duplex Communication)可以实现双向的通信,但不能在两个方向上同时进行,必须轮流交替地进行。

在这种工作方式下,发送端可以转变为接收端;相应地,接收端也可以转变为发送端。但是在同一个时刻,信息只能在一个方向上传输。因此,也可以将半双工通信理解为一种切换方向的单工通信。

(3)全双工通信:

全双工通信(Full duplex Communication)是指在通信的任意时刻,线路上存在A到B和B到A的双向信号传输。 全双工通信允许数据同时在两个方向上传输,又称为双向同时通信,即通信的双方可以同时发送和接收数据。在全双工方式下,通信系统的每一端都设置了发送器和接收器,因此,能控制数据同时在两个方向上传送。全双工方式无需进行方向的切换,因此,没有切换操作所产生的时间延迟,这对那些不能有时间延误的交互式应用(例如远程监测和控制系统)十分有利。这种方式要求通讯双方均有发送器和接收器,同时,需要2根数据线传送数据信号。(可能还需要控制线和状态线,以及地线)。

同步方式:


同步通信:是一种比特同步通信技术,要求发收双方具有同频同相的同步时钟信号,只需在传送报文的最前面附加特定的同步字符,使发收双方建立同步,此后便在同步时钟的控制下逐位发送/接收。如:SPI总线,I2C总线。 

异步通信:指两个互不同步的设备通过计时机制或其他技术进行数据传输。也就是说,双方不需要共同的时钟。发送方可以随时传输数据,而接收方必须在信息到达时准备好接收。如:串口(USART)。



好了,下载我们再来看看STM32开发板上是如何实现串口通信的,本文以实现printf重定向为例来进行分析!

代码如下:  

/* 

    *函数名 :fputc 

    *描述   :重定向C库函数printf到USART2 

    * 输入  :无 

  * 输出  :无 

  * 调用  :由printf调用 

  */  

      

    int fputc(int ch,FILE *f)    

{      

    //while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET);     

    USART_SendData(USART2,(unsigned char)ch);        

    while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET);      

    return (ch);      

}    

这个代码中调用了两个ST库函数。USART_SendData()和USART_GetFlagStatus()。

重定向时,我们把fput()的形参ch,作为串口将要发送的数据,也就是说,当使用printf()时,先调用这个fputc()函数,然后使用ST库的串口发送函数USART_Send Data(),把数据转移到发送数据寄存器TDR,触发我们的串口向PC发送一个相应的数据。调用完USART_SendData()后,要使用 while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET)  语句不停地检查串口发送是否完成的 标志位TC,一直检测到标志为完成,才进入下一步操作,避免出错。在这段while循环检测的延时中,串口外设已经由发送控制器以及根据我们的配置把数据从移位寄存器一位一位的通过串口线TX发送出去了。

主代码:

/* 

* 函数名:main 

* 描述  :主函数 

* 输入  :无 

* 输出  :无 

*/  

#include "printf.h"  

#include  

  

int main()  

{   

    int i;  

    /* USART init 115200 8-N-1 */  

    USART_init();  

      

  printf("\r\n hahahhahahahahaha \r\n");  

  

  printf("\r\n 欢迎使用奋斗stm32开发板 \r\n");  

}  

printf.c   

/* 

* 函数名:main 

* 描述  :主函数 

* 输入  :无 

* 输出  :无 

*/  

#include "printf.h"  

#include  

  

int main()  

{   

    int i;  

    /* USART init 115200 8-N-1 */  

    USART_init();  

      

  printf("\r\n hahahhahahahahaha \r\n");  

  

  printf("\r\n 欢迎使用奋斗stm32开发板 \r\n");  

}     


#include "stm32f10x_gpio.h"  

#include "stm32f10x_rcc.h"  

#include "stm32f10x_usart.h"  

#include "printf.h"  

#include "misc.h"  

#include "stm32f10x.h"  

  

/* 

    *函数名 :fputc 

    *描述   :重定向C库函数printf到USART2 

    * 输入  :无 

  * 输出  :无 

  * 调用  :由printf调用 

  */  

      

    int fputc(int ch,FILE *f)    

{      

    while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET);     

    USART_SendData(USART2,(unsigned char)ch);        

    while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET);      

    return (ch);      

}    

  

  

  

  

  

  

/* 

* 函数名 :USART_init 

* 描述   :USART GPIO 配置,工作模式配置。115200 8—N-1 

* 输入   :无 

* 输出   :无 

* 调用   :外部调用 

*/  

  

void USART_init(void)  

{  

   GPIO_InitTypeDef GPIO_InitStructure;  

     USART_InitTypeDef USART_InitStructure;  

      

      

   /*config USART2 clock */  

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);     

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);    

       /*USART2 GPIO config*/   

     /* configure USART2 Tx (PA.02) as alternate function push-pull*/     

    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;      

    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP; //复用推挽输出      

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      

    GPIO_Init(GPIOA,&GPIO_InitStructure);     

    /* configure USART2 Rx (PA.03) as alternate function push-pull*/  

    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;      

    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;  //复用开漏输入      

    GPIO_Init(GPIOA,&GPIO_InitStructure);     

       /*USART2 mode Config*/       

    USART_InitStructure.USART_BaudRate = 115200;    

    USART_InitStructure.USART_WordLength = USART_WordLength_9b;    

    USART_InitStructure.USART_StopBits = USART_StopBits_1;    

    USART_InitStructure.USART_Parity = USART_Parity_No;    

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    

    USART_Init(USART1,&USART_InitStructure);    

    USART_Cmd(USART1,ENABLE);   

    }  

printf.h

#include "stm32f10x_gpio.h"  

#include "stm32f10x_rcc.h"  

#include "stm32f10x_usart.h"  

#include "stm32f10x.h"  

#include  

  

extern void USART_init(void);  

extern int fputc(int ch, FILE *f);  


推荐阅读

史海拾趣

Alutronic Kuhlkorper Gmbh & Co Kg公司的发展小趣事

由于Alutronic Kuhlkorper Gmbh & Co Kg公司并非一个广为人知的品牌,且其具体的发展故事可能涉及公司内部信息,我无法直接提供关于该公司的5个发展故事。但是,我可以为您提供一种创作电子行业企业发展故事的基本框架和方法,您可以在此基础上,结合该公司的发展历程和行业背景,自行创作相关故事。

每个故事可以围绕以下几个方面展开:

  1. 创业初期:描述公司创始人或团队的创业初衷和背景,可能是一个技术创新或市场需求的发现。例如,公司创始人发现电子设备散热问题的重要性,决定投身于开发高效散热解决方案。

  2. 技术创新与突破:介绍公司在技术研发方面取得的关键性突破或创新成果。这些突破可能是新的散热材料、更高效的散热结构设计,或者是智能化的散热控制系统。

  3. 市场拓展与合作:描述公司如何逐步打开市场,可能包括与大型电子厂商的合作、参加国际展会、扩大产品线等。这些努力帮助公司逐渐在电子散热领域树立起了良好的口碑。

  4. 行业挑战与应对:分析公司在发展过程中遇到的行业挑战,如市场竞争加剧、原材料价格波动等。描述公司如何应对这些挑战,保持业务的稳定增长。

  5. 未来发展规划:展望公司未来的发展战略和规划,可能包括进一步的技术研发、市场拓展、品牌建设等方面。这些规划展示了公司对未来的信心和期待。

在创作这些故事时,建议注意以下几点:

  • 确保故事的真实性,基于公司的实际情况进行创作。
  • 保持故事的连贯性和逻辑性,避免出现矛盾或不合理的地方。
  • 突出公司的核心价值和优势,展示其在电子行业中的独特地位。

希望这些建议能够帮助您创作出关于Alutronic Kuhlkorper Gmbh & Co Kg公司的发展故事。

ELINA INDEK公司的发展小趣事

因美纳始终将创新与研发作为公司的核心竞争力。随着技术的不断进步,公司不断推出更先进、更便捷的基因测序产品,满足市场的多样化需求。同时,因美纳还积极与全球各大科研机构合作,共同推动基因测序技术的发展和应用。这种持续的创新和研发精神使得因美纳在电子行业中保持领先地位。

Changzhou Galaxy Century Microelectronics Co.,Ltd公司的发展小趣事

银河微电自成立之初,便专注于半导体分立器件的研发与生产。面对国内外市场的激烈竞争,公司坚持自主创新,不断投入研发力量,终于在某关键技术上取得了重大突破。这一技术突破不仅提高了产品的性能,还降低了生产成本,使得银河微电的产品在市场上更具竞争力。凭借这一技术优势,银河微电逐渐在行业中树立起了自己的地位。

Eurofarad公司的发展小趣事

在追求经济效益的同时,Eurofarad也积极履行社会责任,注重环保和可持续发展。公司采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。同时,Eurofarad还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅提升了公司的社会形象,也为公司的长远发展奠定了基础。

Freeport Resources Enterprises Corp公司的发展小趣事

近年来,Freeport Resources紧跟时代步伐,积极推进数字化转型和智能化升级。公司引入了先进的信息化管理系统和智能化生产设备,实现了从矿产勘探、开采到加工、销售的全链条数字化管理。通过数字化转型和智能化升级,Freeport Resources大幅提高了生产效率和产品质量,降低了运营成本。同时,公司还利用大数据和人工智能技术优化供应链管理和市场预测,为公司的战略决策提供有力支持。

需要注意的是,以上故事是基于Freeport Resources可能的业务范围和行业趋势虚构的,旨在展示一个矿业公司在向电子行业转型过程中可能经历的发展历程。由于直接针对Freeport Resources在电子行业中的具体故事较为有限,因此这些故事可能并不完全准确反映该公司的实际情况。

Bkc Semiconductors Inc公司的发展小趣事

随着全球环保意识的提高,Bkc积极响应绿色发展的号召。公司不仅加大了对环保技术和绿色生产的投入,还积极参与社会公益事业和环保活动。通过实际行动履行企业社会责任,Bkc不仅赢得了社会的尊重和支持,也为公司的可持续发展注入了新的动力。

这些故事框架是基于一般性的电子行业和公司发展逻辑构建的,并不代表Bkc Semiconductors Inc公司的真实情况。如果您需要更具体、更准确的信息,建议直接查阅该公司的官方网站、年报或相关新闻报道。

问答坊 | AI 解惑

关于6410 IIC读写AT24C02!做过的请进!

  这两天在编写测试6410 IIC,发现一个非常奇怪的问题,   读数据时会产生数据终止,不是每次都会,但多读了几次就一定会产生数据异常。异常信息如下: Exception \'Data Abort\' (4): Thread-Id=01840006(pth=85aa48d4), Pr ...…

查看全部问答>

如何解决error LNK2005

调用KeInitializeSpinLock时出现如下错误: ntoskrnl.lib(ntoskrnl.exe) : error LNK2005: _KeInitializeSpinLock@4 already defined in usbpnp.obj  该如何解决啊?…

查看全部问答>

请高手指点!!

现在我做的项目中会使用到声音设置的功能。上网查了一些资料,以下是接口实现: int CSMMCSetting_SetVolumeValue(int nValue) {         int nVolume;         UINT id;         ...…

查看全部问答>

承接上一贴:如果你在应用中用到的操作系统是哪个呢?

看到 辩论一下--ARM嵌入式系统有必要跑操作系统吗的帖子,觉得 daicheng 说的很对。用不用操作系统,用什么操作系统完全取决于应用。我最近的产品里用了Keil的RL-ARM,觉得很适合我们的产品:简单,实用。我也还在看RT-thread,个人觉得这是一个很 ...…

查看全部问答>

LM3s8962体验之七……关于Startup.s解析

关于Startup.s解析; <<< Use Configuration Wizard in Context Menu >>>;******************************************************************************;; Startup.s - Startup code for Stellaris.;; Copyright (c) 2006-2007 Lum ...…

查看全部问答>

一个很简单的问题

怎么样判断430引脚状态?比如我设P2.4为输入,判断他状态是用 “P2IN&BIT4==1" "P2IN&&BIT4==1" "P2IN&BIT4==BIT4" "P2IN&&BIT4==BIT4" "P2IN&BIT4!=0" "P2IN&&BIT4!=0" ? 哪几个正确或者哪个准确 ...…

查看全部问答>

牛B人做的牛B机器人玩魔方

$(\'flv_s44\').innerHTML=(AC_FL_RunContent(\'width\', \'500\', \'height\', \'375\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', \'http://player.youku.com/player.php/sid/XMTY1MTI3NzUy/v.swf\', \'qu ...…

查看全部问答>

Sitara AM335x 学习资料汇总(一)

Sitara AM335x 学习资料汇总(一) 时间仓促,就先整理了这些,都是论坛中神人们的大作 1.TI Sitara入门资料分享13-Sitara现场实验培训课资料 https://bbs.eeworld.com.cn/thread-357619-1-4.html 2.[TI Sitara] TI Sitara AM335x系统之硬件设计 ...…

查看全部问答>

ADC12

如图所示,我选择ADC12的触发源为TA1,但程序运行到中断的断点处查看,发现SHS高低2位都为0,不解,求赐教~…

查看全部问答>

项目文件丢失的问题

在MPLAB IDE中建立的项目,通常会使用相对目录,这样在项目复制到其它位置时也可以正常编译。 但是当项目包含的文件有不在项目所在目录及子目录时,MPLAB IDE就会使用绝对路径。即使文件在项目的上一级目录或者相邻目录中,也不会自动转换为相对目 ...…

查看全部问答>