完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前言:平时我们进行c语言编程的时候会经常用到printf函数进行打印输出,来调试代码。可是这个printf函数C库已经帮我们实现好了,通常只需要直接调用即可,但是如果在一个新的开发平台,如果库没有帮我们实现好,比如STM32开发板,那么我们怎么实现printf打印输出呢?
首先我们来了解一下串口通信! 1、什么是串口通信? 串口通信(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进行传输数据的一种通讯方式。 串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议。 2、串口通信协议 在串口通信中,常用的协议包括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。 3、同步通信?异步通信? 同步通信:是一种比特同步通信技术,要求发收双方具有同频同相的同步时钟信号,只需在传送报文的最前面附加特定的同步字符,使发收双方建立同步,此后便在同步时钟的控制下逐位发送/接收。如:SPI总线,I2C总线。 异步通信:指两个互不同步的设备通过计时机制或其他技术进行数据传输。也就是说,双方不需要共同的时钟。发送方可以随时传输数据,而接收方必须在信息到达时准备好接收。如:串口(USART) 4、通信方式 •单工模式(Simplex Communication):单向的数据传输。通信双方中,一方为发送端,一方则为接收端。信息只能沿一个方向传输,使用一根传输线。双方是固定的。 •半双工模式(Half Duplex):通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。数据传输允许数据在两个方向上传输,但是,在任何时刻只能由其中的一方发送数据,另一方接收数据。 •全双工模式(Full Duplex)通信允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。在全双工模式中,每一端都有发送器和接收器,有两条传输线,信息传输效率高。 5、数据格式 (1)起始位:起始位必须是持续一个比特时间的“0”,标志传输一个字符的开始。 (2)数据位:数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,一般可以是5位、7位或8位。传输数据时先传送字符的低位,后传送字符的高位。 (3)奇偶校验位:奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个“1”;如果是偶校验,需要保证传输的数据总共有偶数个“1” (4)停止位:停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是“1”,标志着传输一个字符的结束。 (5)空闲位:空闲位是指从一个字符的停止位结束到下一个字符的起始位开始,表示线路处于空闲状态,必须由高电平来填充。 了解了串口通信的基础知识之后,我们再来看看STM32开发板上是如何实现串口通信的,我以实现printf重定向为例来进行分析! 先看代码: main.c:
printf.c:
printf.h:
代码分析: 1.串口初始化配置 学了STM串口通信之后,我们知道配置串口通信至少要配置:字长(一次传送的数据长度),波特率(每秒传输的数据位数),奇偶校验位,还有停止位。当然我在 配置过程中把他们分别设为8,115200,No ,1。 串口的配置主要与USART_InitTypeDef这个结构体有关,里面存放了控制参数成员:
就用到了串口,所以也要对串口进行初始化!而我是用的USART2,所以要对其进行相应的配置。 查看STM32硬件原理图: 由原理图可知,这个串口是支持TTL电平的,接收数据RX是接在PA3管脚上的,发送数据是接在PA2上的。由于我是要输出到PC上的串口终端,所以PA2要 设为复用推挽输出模式,PA3设为复用开漏输入模式。 查看stm32f10x_it.c这个代码可知USART2是挂接在APB1总线上的,GPIO是挂在APB2总线上的,如下所示: 所以我们在进行时钟初始化的时候要特别注意。 2.printf重定向 其实printf重定向就是我们将printf重新定向到串口,也就是我们可以自己重写C的库函数,当连接器检查到用户编写了与C库函数相同的名字,优先采用 用户编写的函数这样用户就可以实现对库的修改了。 printf函数实际是一个宏,最终调用的是 fputc(int ch,FILE *f)这个函数,所以我们需要修改这个函数。 下面我们着重分析一下fputc函数: 这个库函数调用了两个ST库函数,分别是:USART_GetFlagStatus()与USART_SendData(),形参ch表示串口将要发送的数据,也就是说。当使用printf()时,它先调用fpuc()函数,然后使用ST库的串口发送函数USART_SendData(),把数据转移到发送数据寄存器TDR.触发我们的串口向PC发送一个相应的数据,调用完USART_SendData()之后, 使用 while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET)语句不停的检查串口的数据是否发送完成的标志位TC,一直检查到标志为“完成”,才进行下一步操作, 要注意的是USART_SendData()每次只发送一个字节的数据! 注意:由于fputc()函数的形参调用了C库的FILE,所以在程序中加入stdio.h这个头文件,便且在keil的编译器的设置中勾选Use MicroLIB(使用微库) 3.硬件连接 首先硬件上我们将USB转串口线的TXD,RXD,GND,分别接在32开发板USART2上的RXD,TXD,GND。 由于USART2是TTL电平,所以我们用的u***转串口线一定要是支持TTL电平的,否则串口通信不上! 4.效果图 串口调试助手显示: |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1816 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1631 浏览 1 评论
1098 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
739 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1691 浏览 2 评论
1950浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
754浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
585浏览 3评论
604浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
568浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 01:26 , Processed in 0.848921 second(s), Total 78, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号