每节课都是一个项目 手把手用STM32打造联网气象站-6-STM32基础三件套-USART的初始化和使用

STM32基础系列包含了三件套,掌握了这三件套,类似于掌握了程咬金三板斧,就可以开始干项目,创造价值了。毕竟,真正的编程是一项实战性很强的技术,掌握编程主要靠实战,而不是靠知识灌输。

STM32的编程三板斧:

  1. GPIO初始化;
  2. TIM定时器(含中断);
  3. USART串口;

我们已经完成了前面2板斧,并且完成了一些有趣有用的例子。

接下来我们讲解重要的第三板斧:USART串口的使用。

1. USART串口的重要性

 首先我们必须理解,USART串口非常之重要!

我们在物联网项目中用到的各类模块:WIFI模块,蓝牙模块,ZIGBEE模块,4G模块,LORA模块,NBIOT模块,全部都是采用串口方式,和MCU进行通信。

如果我们需要开发一个采集器,最简单直接方便的方式,就是用串口和PC进行通信,从PC获得控制命令,并且上报对应数据到PC端。

我们的教程在串口部分,会分为两讲来完成:

这一讲,也就是第六讲,我们将完成串口的初始化和测试,我们在这里打通STM32常用的5个串口,同时通过这一讲,我们学习一下,可能是最好用的串口工具-纸飞机串口助手-的一些用法;

下一讲第七讲,我们实现几个用串口通信的有趣的项目,并且把这些串口通信代码进行归档整理,方便后续项目开发中进行调用。

接下来就开始我们的串口之旅!

2. USART串口基础知识

STM32的串口通信接口有两种,分别是:UART(通用异步收发器)、USART(通用同步异步收发器)。而对于大容量STM32F10x系列芯片,分别有3个USART和2个UART。

当我们采用串口连接调试时,一定要注意,串口的收发端需要共地。很多没有经验的工程师,将串口调试工具和MCU之间,就只连接一根线,然后会抱怨串口不同,就是没有理解串口收发的接线原理。

用串口调试的时候,为什么需要接地呢?

因为我们所有的数字信号,都是按照高电平和低电平进行传送的,而无论是高电平还是低电平,其中核心是:需要公共地,作为参考电压,高电平和低电平都是相对这个公共地而言的。如果发送端和接收端没有公共地,那么就无法传送信号了,因为没有参考点,无法判断到底是高电平还是低电平。

 

上图展示了串口收发的接线方式,可以看到,MCU的TX连接USB-TTL的RX, MCU的RX连接USB-TTL的TX,而两者的GND连接到一起。

 

另外,解释一下USB-TTL,这个是我们常用的串口调试工具,也就是把USB转换为串口,同时这个串口的电平为TTL电平。TTL电平的含义是:一般行业中,将3.3V定义为TTL电平。

3. STM32串口的初始化

串口的初始化步骤分为3个步骤:

1.初始化串口GPIO;

2.初始化串口;

3. 初始化中断并使能串口;

下面详细讲解一下串口初始化步骤。

3.1 初始化串口的GPIO

串口需要实现通信,首先需要完成GPIO的初始化,把TX设置为输出,把RX设置为输入。

 串口1对应的是: PA9为TX, PA10为RX;

串口2对应的是:PA2为TX, PA3为RX;

串口1和串口2是我们日常使用最多的串口。

 

串口3对应的是:PB10为TX, PB11为RX;串口3和I2C接口是重合的,很多时候会把它配置成为I2C接口而不是串口。

 

 串口4对应的是:PC10为TX, PC11为RX; 

 串口5对应的是:PC12为TX, PD2为RX;串口4和串口5和SDIO重合,如果需要用到SDIO,则不能再使用串口4和串口5。

掌握串口IO分步的一个小规律是:TX总是比RX小。比如USART1, TX为A9, RX为A10;比如USART2, TX为A2, RX为A3; 比如USART3, TX为B10, RX为B11。掌握这个规律,方便我们在调试的时候,准确找到对应串口位置。

了解串口对应的GPIO后,我们就可以完成GPIO初始化了。

 

从上面代码可以看出,串口的输出端配置和前面部分没有任何区别。串口输入端配置会稍有区别,输入端配置不需要配置速度,只需要配置好输入模式即可

3.2 配置串口

配置串口的基本步骤和配置GPIO没啥区别:创建一个结构体类型的全局变量,启动时钟,配置结构体参数并完成初始化。

但是我们需要专门关注一下,串口常用的一些参数:

串口常用参数包括:波特率,位数,停止位,校验位。这些参数中,最最常用的是波特率。在51时代,一般常用波特率为9600,到了STM32时代,常用波特率变为115200;对于数据通信,STM32能够支持的稳定波特率可以达到921600。对于更高的波特率,有时候可能会导致丢包现象。

因此,串口的配置过程,主要就是把串口的这些常用参数进行配置的过程。

3.3 配置NVIC中断

我们首先复习一下,在TIM定时器配置中,我们已经详细讲解过了NVIC中断配置。

(27条消息) 每节课都是一个项目 手把手用STM32打造联网气象站-4-STM32基础三件套-TIM定时器初始化_可志嵌入式的博客-CSDN博客

详细可以看上面博文。

根据前面描述,我们知道,配置中断时,首先需要设置中断分组,然后配置中断源,配置抢占优先级和响应优先级,最后使能中断即可。

但是这是针对仅仅初始化一个中断源的情况。当我们需要初始化两个中断源时,就需要把设置中断分组单独列出来。其他步骤照旧。

把TIM_NVIC_Config中的配置拿出来。

 

 把USART_NVIC_Configuration中的中断分组配置也拿出来。

 然后一起把他们放到main中,将中断优先级分组设置为分组2。

这里就出现一个问题:串口中断和TIM定时器中断,我们将哪个优先级设置为更高?

这里没有定论:如果时用定时器做时钟,而仅仅用串口做调试,明显需要把定时器设置更高。而如果用串口做通信串口,那么为了避免串口丢帧,明显需要串口的优先级设置为更高。

我们这里将串口优先级设置的更高,设置为抢占0, 响应0,基本上时最高级别待遇了。

然后把TIM定时器串口优先级设置为抢占1,响应2。这种情况下,串口是可以打断TIM定时器中断的。 

3.4 串口发送数据

完成串口配置之后,如何知道串口是否配置成功了呢?我们需要让串口发送一个数据,用串口助手软件接受到这个数据,这样可以说明串口配置成功了。

 在上面代码中,我们直接调用ST的库函数,完成串口字节发送。然后通过while查询标志位,看看发送是否成功。

当然,Usart_SendByte不要忘记,在.h文件中进行声明,方便其他的.c文件调用。

编程技巧1:编程过程中,我们需要保留很多调试点和验证点,方便我们在编程过程中,及时验证,及时开发。

编程技巧2:while等待模式,用来等待某个信号到达。一般避免连接外部信号的时候,使用while方式。

3.5 初始化并完成串口输出

 通过串口,输出H i,达到对应效果。

3.6 熟悉纸飞机串口调试助手

好用的纸飞机串口助手体验 - 知乎 (zhihu.com)

 纸飞机串口调试助手的详细说明,可以查看上面的知乎链接。

这个串口支持串口数据正则表达式查询,可以在大量数据中,匹配响应的数据。可以进行绘图,能够通过图像查看不同的数据格式。可以支持自定义命令字符串,当我们需要调试各类WIFI模块,4G模块的时候,用这个工具非常方便。

 

基本使用也很简单,选择波特率为115200,然后打开串口,即可完成。 

当你看到这个Hi的时候,就表示串口的移植已经完成了。

更进一步的串口功能,我们会在后面进行详细讲解。

3.7 小步快走,梳理串口移植步骤

这一小节,我们讲解一下,如何从前面的TIM定时器任务中,一步一步移植串口驱动,并完成串口的输出。主要是为了讲解我们项目中常用技巧:小步快走法

这个核心方法我们在后面还会反复提到。

小步快走法就是:不要一次做多步改动,而是每次之改动一点点,然后下载验证测试,验证功能OK之后,再进行下一步改动。

开发过程中,采用小步快走法的好处是:一旦出现问题,我们可以很清晰的定位到问题所在位置,快速定位,快速发现,快速解决

下面结合实际情况,讲解一下,用小步快走法,如何修改NVIC中断分组,完成TIM和USART的初始化

 第一步:把NVIC优先级配置拉出来,放到main.c中;

 

第二步:调整基本定时器的抢占优先级和响应优先级,然后编译下载测试代码功能。这里就是小步快走的核心思想:我们通过代码少量改动,验证NVIC新的分组功能;充分验证完成后,再进行下一步代码修改。

 第三步:将usart_config和和Usat_SendByte放进工程中,编译下载运行,查看结果。

我们强调小步快走法,是因为嵌入式开发过程本身比较复杂,一个代码错误,一个变量错误,一个语句错误,都会导致执行结果失败。虽然编译器已经帮我们过滤了很多低级错误,但是还是会出现一系列其他的低级错误,而小步快走法,就可以有效规避这样的错误。

纸上得来终觉浅,绝知此事要躬行!

马上下载测试代码,看看效果。

测试代码链接

https://download.csdn.net/download/book_drabit/85942758

4. 串口接收并环回

上面的教程讲解了串口发送数据,通过纸飞机串口助手查看数据的过程。我们理解小步快走法的编程和调试方式。但是上面的串口并没有接收任何数据。接下来我们实现串口接收功能。也就是把串口发送的数据原封不动发送回来。

环回测试是工程项目中常用术语,我们可以对串口数据,网口数据或者其他通信接口数据,进行环回测试。通过环回测试,我们可以判断串口收发是否正常工作。

如上所示,我们在it.c中,不断检查IT_RXNE这个位是否为SET,如果是SET表示串口接收到了数据。

ucTemp为临时变量,通过调用库函数ReceiveData,来获取接收的数据;

然后再调用库函数SendData将数据原封不动的发出去。

这里先抛出2个问题:

1. 为何串口收到数据后,能够自动触发这个USART_IRQHandler?

2. 如果把这个IRQHandler移动到其他的.c文件中,是否还能够正常触发中断?

(27条消息) 每节课都是一个项目 手把手用STM32打造联网气象站-4-STM32基础三件套-TIM定时器初始化_可志嵌入式的博客-CSDN博客

从上面链接的3.4节,可以找到对应答案。

上面代码下载后,可以看到串口环回测试成功。

可以在这里,添加LED_TOGGLE,当每次串口收到数据时候,可以进行闪烁。

由于板上只用了一个LED,前面已经用它来设置时间了,因此我们需要把前面的定时开关LED的语句注释掉。

 纸上得来终觉浅,绝知此事要躬行!

马上下载测试代码,看看效果。

测试代码链接

https://download.csdn.net/download/book_drabit/85947015

5. 串口发送字符串和采用printf打印

5.1串口发送字符串

前面一个一个字符发送非常麻烦,我们接着实现字符串发送功能:

 

从字符发送,到字符串发送,差的是一个while循环。

do
{

}while(*(str+i))!='\0');

 上面这个while循环,是需要您能够手敲代码记下来的,在字符串处理中,我们常用这种方法,来判断是否达到了字符串结尾。

 这里再抛出2个问题:

为何通过判断'\0'就可以判断字符串结尾?

在什么情况下?字符串结尾可能不出现'\0'?

5.2将printf映射到串口

上面实现了SendString函数,但是这样还是不够方便,因为很多时候,我们需要打印数字,十六进制数字,字符等不同的格式。这个时候,我们就需要用到printf了。

当我们使用stm32中的printf时,我们实际上是在使用microlib.h中的printf语句。

我们需要在MDK工程中,勾选Use MicroLIB这个选项,表示接下来,我们会使用这个库中的函数。

关于MicroLib的说明如下:

MicroLib是缺省c库的备选库,它可装入少量内存中,与嵌入式应用程序配合使用,且这些应用程序不在操作系统中运行。
MicroLib进行了高度优化以使代码变得很小,功能比缺省c库少,不具备某些ISO c特性,部分库函数的运行速度也比较慢,如内存拷贝函数memcpy()。
MicroLib与缺省c库之间的主要差异在网上有许多文章都有写到,这里摘抄记录:
(1)MicroLib 不符合 ISO C 库标准。 不支持某些 ISO 特性,并且其他特性具有的功能也较少。
(2)MicroLib 不符合 IEEE 754 二进制浮点算法标准。
(3)MicroLib 进行了高度优化以使代码变得很小。
(4)无法对区域设置进行配置。 缺省 C 区域设置是唯一可用的区域设置。
(5)不能将 main() 声明为使用参数,并且不能返回内容。
(6)不支持 stdio,但未缓冲的 stdin、stdout 和 stderr 除外。
(7)MicroLib对 C99 函数提供有限的支持。
(8)MicroLib不支持操作系统函数。
(9)MicroLib不支持与位置无关的代码。
(10)MicroLib不提供互斥锁来防止非线程安全的代码。
(11)MicroLib不支持宽字符或多字节字符串。
(12)与stdlib不同,MicroLib不支持可选择的单或双区内存模型。MicroLib只提供双区内存模型,即单独的堆栈和堆区。

勾选MicroLib之后,并不代表我们就直接用printf输出了,因为其打印的字符串最终不知道打印到何处。我们要做的是将调试信息打印到usart1或者usart2中,所以需要对printf()函数所依赖的打印输出函数fputc()进行重定向。(MicroLib中的printf()函数打印操作依赖fputc())

添加了fputc之后,如果直接编译,会出现编译错误,因为其中用的FILE对应的头文件没有被包含。

 需要在usart.c中包含stdio.h的头文件。

在调用printf的地方,也同样需要包含stdio.h,因为printf这个函数也是在这个头文件中定义的。

执行结果如上图,这样就可以任意地用printf打印函数执行的相关信息了。

纸上得来终觉浅,绝知此事要躬行!

马上下载测试代码,看看效果。

测试代码链接

https://download.csdn.net/download/book_drabit/85949703

 

并且试着修改一下上电打印输出信息,波特率等,查看一下效果。

接下来会一步一步带你完成家庭气象站的开发工作,敬请收藏关注,以免下次找不到了。

 

 

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值