自学内容网 自学内容网

我在高职教STM32——串口通信(4)

        大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正因如此,才有了借助 CSDN 平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思的教学设计分享出来,主要面向广大师生朋友,单片机老鸟就略过吧。欢迎点赞+关注,各位的支持是本人持续输出的动力,多谢多谢!

        通信,按照传统的理解就是信息的传输与交换。对于像STM32这样的单片机来说,通信则与传感器、存储芯片、外围控制芯片等技术紧密结合,成为整个单片机系统的“神经中枢”。没有通信,单片机所实现的功能仅仅局限于单片机本身,就无法通过其它设备获得有用信息,也无法将自己产生的信息告诉其它设备。如果单片机通信没处理好的话,它和外围器件的合作程度就会受到限制,最终整个系统也无法完成强大的功能,由此可见单片机通信技术的重要性。UART(Universal Asynchronous Receiver/Transmitter,即通用异步收发器)串行通信是单片机最常用的一种通信技术,通常用于单片机和电脑之间、单片机和单片机之间、单片机与外围器件的通信。

【学习目标】

  1. 知道通信基本概念的含义;
  2. 理解通信机制中物理层和协议层分离的理念;
  3. 学会配置STM32的串口功能;
  4. 了解printf()函数“打印”至串口的实现过程;
  5. 掌握使用串口调试软件对单片机的调试方法。

        STM32串口通信涉及的知识较多,为了不让篇幅太长,本章打算分五个部分来讲解,本文是第四部分。

五、STM32的USART收发通信实验

        我们经常使用USART来实现STM32与电脑之间的数据传输。这使得我们调试程序非常方便,比如我们可以把一些变量的值、函数的返回值、寄存器标志位等等通过USART发送到串口调试助手,这样我们可以非常清楚程序的运行状态,当我们正式发布程序时再把这些调试信息去除即可。我们不仅仅可以将数据发送到串口调试助手,我们还可以在串口调试助手发送数据给STM32,程序根据接收到的数据进行下一步工作。

5.1 任务描述

        通过本实验,我们来测试和体验一下串口最基本的发送和接收效果,如图15所示。首先,通电之后在串口助手上“打印”开机信息;接着,开发板进入等待接收串口数据的状态,如果我们在串口助手发送区域输入任意内容(以回车结束),单击“手动发送”按钮,则在串口助手接收区回显相同的信息。工作期间,绿色LED一直闪烁,表明程序正在运行。

图15 串口收发通信的效果

5.2 工程文件清单

        综上所述,串口数据的收发对于STM32的开发来说,算得上是一种“标配”功能,这就是为什么我们从第一个实验开始就在工程 Basic 目录下放了 usart.cusart.h 两个文件,用于串口的初始化和中断接收。现在,是时候结合以上的知识来剖析这两个文件里的代码了,我们把本实验的工程文件清单列在图16中。

图16 串口收发测试工程文件清单

5.3 硬件电路

        图17和图18把开发板上与USART有关的电路连接呈现出来了,本实验只用到了USART1这个串口,硬件连接和配置上只关注该串口即可。

图17 USB转串口电路
图18 开发板上所使用的串口

5.4 编程要点

  1. 使能RX和TX引脚GPIO时钟和USART时钟;
  2. 初始化GPIO,并将GPIO复用到USART上;
  3. 配置USART参数;
  4. 配置中断控制器并使能USART接收中断;
  5. 使能USART;
  6. 在USART接收中断服务函数实现数据接收和发送。

5.5 usart.h代码剖析

        usart.h 和 usart.c 这两个文件的源码来自正点原子STM32系列的开发板,版权归广州市星翼电子科技有限公司所有。根据笔者自己的开发和教学经验,在STM32串口驱动的完整性和可移植性方面,正点原子的确做的非常优秀,我们不妨就来学习一下人家的优秀之处。由于串口驱动源码背后涉及的信息量较大,本小节先剖析 usart.h 头文件的源码,如代码清单2所示。源码中仅给了简要注释,详细的阐释见代码清单后的注解,阅读时最好结合 usart.c 的源码一起来看。

//------------------------------------------------------------
// 代码清单2:usart.h
//------------------------------------------------------------

#ifndef __USART_H
#define __USART_H

#include "stdio.h"  //为了使用printf()函数

//************************************************************
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32开发板
//串口1初始化   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//************************************************************

//------------------------------------------------------------
// 必要的宏定义
//------------------------------------------------------------
#define  USART_REC_LEN  200  //定义最大接收字节数 200
#define  EN_USART1_RX 1//使能(1)/禁止(0)串口1接收

//------------------------------------------------------------
// 全局变量声明
//------------------------------------------------------------
//接收缓冲,最大USART_REC_LEN个字节,末字节为换行符
extern u8  USART_RX_BUF[USART_REC_LEN];
//接收状态标记
extern u16 USART_RX_STA;

//------------------------------------------------------------
// 函数声明
//------------------------------------------------------------
void uart_init(u32 bound);

#endif

        第8行的 stdio.h 这个头文件大家肯不会陌生,这是标准C的输入/输出库,我们把它包含进来是为了使用经典的printf()函数,其用意估计大家也猜到了,那就是“打印”信息,这不就是本章的主要目的吗?但这里其实还有两个问题需要解决:第一,标准库里的 printf() 是向显示器这个标准输出设备“打印”信息,而我们却希望向串口这个设备“打印”信息,这里便涉及到一个“重定向”的问题;第二,stdio.h 这是标准C库里才有的头文件,但STM32硬件和Keil软件究竟是否支持这个库,这里又涉及到一个“半主机调试”模式的问题。关于这两个问题,我们会结合 usart.c 的源码来解释。

        第23行定义的宏用来规定串口一次能接收的长度(即字节数),这个数不宜太大,否则一次接收太多内容可能存在数据包丢失的情况。那如果实际接收内容的长度超过了这个规定值该怎么办呢?我们会在接收数据的中断程序中进行处理,分多次接收即可。

        第24行定义的宏将配合 usart.c 文件里的条件编译决定是否开启串口接收的功能。一般情况下,如果只是使用串口“打印”调试信息,是不需要启用接收功能的,那么把这个宏的值改为0即可。

        第30行声明了一个字符数组,用来存放串口一次接收的内容。

        第32行声明的变量是u16类型的,它的16个bit位表示的信息如图19所示。这里有必要阐明的一点是,我们习惯的回车效果在ASCII码里其实是用“回车+换行”两个字符表示的,我们把这两个字符的相关信息汇总到表3中。结合 USART_RX_STA 变量的含义可知,串口接收的内容如果遇到了回车,表示这次接收的结束。同理,如果我们想通过 printf() 函数“打印”出回车效果,那么就需要“\r\n”连续两个转义字符来实现。

图19 USART_RX_STA变量表示的信息
表3 ASCII码中的回车与换行符

(第四部分完,usart.c源码会在第五部分中详细剖析)


原文地址:https://blog.csdn.net/gmc832002/article/details/140560251

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!