【STM32】| 01——常用外设 | USART

系列文章目录
【STM32】| 01——常用外设 | USART


失败了也挺可爱,成功了就超帅。

文章目录

前言

本文描述串口相关原理、配置及使用
如基础收发功能、串口+DMA+IDEL接收一帧数据、防止数据丢失加入环形缓冲区等
环境:stm32f103zet6 keil HAL库

1. 基础理论

串口能干吗 可以用来通信。串口通信是我们常用的设备通信方式。下面先从涉及的相关概念说起

1.1 并行通信和串行通信

一般通信方式可以分为两类
1、串行通信 如串口、SPI、IIC等
2、并行通信 如SRAM等
在这里插入图片描述

1.2 同步通信和异步通信

在这里插入图片描述

1.3 单工/半双工/全双工

根据数据传输方向可以分为这三种
在这里插入图片描述

1.4 电平信号(RS232/TTL)和差分信号(RS485)

他们都用于串口。TTL、RS232/485都算电器上标准 都是基于串口的 这里简单大概介绍详细的可自行看下哦
在这里插入图片描述
TTL应用:单片机连接电脑通过串口助手通信:单片机如果没板载 串口转TTL的芯片的话 就需要通过 单片机串口接 USB转TLL然后插到电脑上
其他也需要相应的转换器或板载转换芯片

1.5 端口(COM)

一般我们指物理接口 比如DB9
当我们用串口助手 时需要选择 COM几
因为电脑识别到串口设备后显示为端口 COM几
USB-TTL/RS232/485 都会识别为端口

2. 串口理论

串口通信是串行通信的一种。也是全双工异步通信。

2.1 串口物理连接

串口接线 中有最多 5根 TX/RX/RTS/CTS/GND
一般我们只用 TX/RX/GND 3根
其他两根用作流控:即通信过程中 握手

2.1.1 多个单片机之间串口连接

MCU通常带有串口功能 直接使用串口对应引脚连接就可以
在这里插入图片描述

2.1.2 单片机和其他设备连接

串口和电脑连接
1、单片机板载USB转串口 如板载CH340芯片等
在这里插入图片描述

2、单片机通过外部USB转TTL 连接电脑

在这里插入图片描述
单片机和传感器串口连接
1、单片机连接输出RS485信号的传感器
在这里插入图片描述
在这里插入图片描述
以上列举了几种
总结
单片机(TTL)串口连接 RS232/485需要进行相应转换

2.2 串口数据信号

串口数据按照以下方式 每次传输一字节数据 数据按一位一位传输 从数据低位到高位。
1个起始位+8个数据位+1个校验位(有/无)+停止位
下图是串口数据帧组成

在这里插入图片描述
奇校验:数据位中1的个数为奇数 该位为1 反之为0
如数据位 00101101 4个1偶数 奇校验该位为1 偶校验该位为0

用逻辑分析仪抓取串口实际波形
在这里插入图片描述

还有传输最重要的参数 那就是传输速度。
串口的传输速度称为波特率 只有在相同波特率下才可以通信
在这里插入图片描述

所以我们在使用串口时需要配置它的波特率 数据位停止位 校验位这几个参数。

2.3 MCU串口外设

不同厂商的都大同小异 我这里以stm32为例
我们通过看查 STM32参考手册 去看串口详细描述即功能框图
通过看查我们可以了解到 stm32 USART外设 通用同步异步串口收发器
也就是说这个串口也可以同步用也可以异步全双工 它还有其他额外功能
比如 支持IRDA SIR(串行红外)、智能卡模拟还有一些检测校验等。
下面我们详细看下他的功能框图

在这里插入图片描述

在这里插入图片描述

发送一个数据 先给到发送数据寄存器 通过移位寄存器一位一位送走
接收一个数据从接收数据寄存器获取
具体一些含义通过阅读相关寄存器描述可以很清楚了解这里就步多说了
总的来说 我们使用这个串口外设时候有很多功能 比如发送完成会产生中断
接收也可以 空闲检测等等这些在一些数据处理或应用中极其有用。
多读参考手册 多翻寄存器 对底层了解清楚那么遇到一些问题就很容易解决

3. 串口实践

主要讲述 HAL库所以 使用Cubemx生成 记录如何配置以及使用起来

3.1 串口查询式收发

3.1.1 Cubemx配置

新建好对应芯片工程后
首先配置时钟系统 使用HSE外部晶振 系统时钟设置为最高 STM32F103 72MHZ请添加图片描述

开始配置串口 我们用串口1
我们可以看到配置波特率 停止位 校验位 数据位选项 然后
软件自动帮我们配置了串口1默认引脚
请添加图片描述

3.1.2 编写发送代码

可以通过 functions选项看查usart HAL库函数API
请添加图片描述

每秒发送程序运行次数
请添加图片描述

3.1.3 编写接收代码

可以看到虽然我有时一次发送了好几个字节 实际串口一直是一个一个接收发送的
请添加图片描述

3.1.4 查询式收发的应用场景

查询式发送:发送数据/重定向printf (调用printf即可在串口助手显示相关内容 如输出调试信息等)
查询式接收:我们一般不用这种方式接收数据 因为需要阻塞等待接收/不断检测接收 影响程序执行 占用资源
查询式缺点:实时性差

所以一般没特殊要求的话 发送采用查询式发送 接收采用中断式

重定向printf方法
1、使用 MicroLIB 库
引入微型C标准库 头文件添加 stdio.h 重定义 fputc 即可
在这里插入图片描述
效果
请添加图片描述

2、不用微库 使用自定义kprintf 格式化输出
请添加图片描述

3.2 串口中断式收发

3.2.1 Cubemx配置

只需要在串口配置界面 勾选串口全局中断就好
在这里插入图片描述

3.2.2 使用串口中断式发送

调用HAL库提供的 中断发送函数即可

1S发送一个字符1
在这里插入图片描述

分析下中断发送执行流程
调用串口中断发送函数 才会使能 发送中断 触发中断后(第一次进入串口中断) 它先失能串口发送中断 使能发送完成中断 再进一次串口中断 执行发送完成回调函数
请添加图片描述
debug验证
观察右侧串口SR C1寄存器 发送相关位 TXE TC TXEIE TCIE
变化
在这里插入图片描述

3.2.3 使用串口中断式接收

在这里插入图片描述
接收流程就不分析了 和发送一样只不过 是接收中断

3.2.4 中断式收发应用场景

接收数据需要实时的所以 一般我们用中断接收 接收数据可满足正常接收数据需求
如果使用中断发送 发送一个数据也频繁进入中断影响系统开销

3.3 串口DMA收发

3.3.1 Cubemx配置

DMA TX/RX 配置正常模式
DMA接收发送需要执行完一次(执行完会清除相应位)调用一次
在这里插入图片描述

3.3.2 串口DMA(DMA正常模式)接收/发送

请添加图片描述

3.3.3 串口DMA(DMA循环模式)接收/发送

这里只用RX DMA通道配置为循环 (发送配置为循环会一直发送 没接收也会一直发送)
DMA RX配置为循环模式
这样只需调用一次 DMA接收 就可以一直触发dma接收
在这里插入图片描述

请添加图片描述

3.4 串口空闲中断接收不定长数据

前面介绍的几种接收都是 接收固定长度 当我们数据帧不确定长度时候 就需要通过空闲中断去实现接收不定长数据了(一帧一帧数据肯定有间隔的 使能IDLE即可检测串口空闲 从而实现接受不定长数据)

先看看寄存器 IDLE位描述
在这里插入图片描述

在这里插入图片描述

3.4.1 查询式(阻塞)接收 + IDLE

在这里插入图片描述
请添加图片描述

3.4.2 中断式接收 + IDLE

在这里插入图片描述
接收到数据会调用这个函数
在这里插入图片描述
运行效果
请添加图片描述
程序运行流程(通过debug演示程序如何调用执行的)
在这里插入图片描述

在这里插入图片描述

3.4.3 DMA接收 + IDLE

在这里插入图片描述
串口DMA IDLE和 中断IDLE 中断调用流程类似 不同在于 在串口中断处理函数里 做了DMA相关操作
在这里插入图片描述

运行效果
这里DMA RX配置为正常模式 所以需要在接收回调里 再次调用 准备下次DMA接收(如果DMA配置为循环模式 只需调用一次即可)
请添加图片描述

3.5 环形缓冲区ringbuffer

环形缓冲区也被称为 循环队列 。它是队列的一种应用。
数据结构 队列(Queue): 它的数据是先进先出( First in First out) 简称FIFO。该结构下添加删除数据 被成为入队/出队。
环形缓冲区就是 首尾相连的队列 通过两个指针操作数据 一个读指针一个写指针。当一个数据元素被用掉后,其余数据元素不需要移动其存储位置。如图
在这里插入图片描述
开源的ringbuffer有很多 他们原理都一样的 好多参考linux的kfifo
ringbuffer是无锁的 所以 适用于 单个生产者消费者 并发的情况 如果多个加锁即可。 它有什么用呢?防止数据丢失(数据包大量突发采用中断接收会造成丢包现象也可以说解决生产者消费者速度差异)不用考虑大小不够溢出(环形 旧的数据会覆盖)等等

这里使用 rttherad的 ringbuffer
它源码用到一些变量定义或断言 是基于rttherad的 我这边小小修改了一下 替换了一些 断言用判断代替了

3.5.1 ringbuffer结构体定义

在这里插入图片描述
其他很好立理解 读写镜像标志位这里讲解下 用来记录读完/写满缓冲区 比如 如果写满了 写镜像标志从 0变为1 。用做判断缓冲区数据是空还是满。后面通过分析源码 去理解镜像意思。

3.5.2 ringbuffer状态标志定义

在这里插入图片描述

3.5.3 ringbuffer接口函数

在这里插入图片描述

ringbuffer_init 初始化

在这里插入图片描述
图解:初始化一个长度13的ringbuffer
在这里插入图片描述

ringbuffer_put 写入指定长度数据

写入指定长度数据至到写满 再写不进去
在这里插入图片描述
在这里插入图片描述
镜像标志即 写满标志

ringbuffer_put_force 强制写入指定长度数据

强制写入指定长度数据写满后还可以 再写覆盖旧的
在这里插入图片描述
在这里插入图片描述

ringbuffer_putchar 写入一个字节数据

写满就无法写入了
在这里插入图片描述

ringbuffer_putchar_force 强制写入一个字节数据

在这里插入图片描述

ringbuffer_get 获取指定长度数据

和写入数据类似 只不过操作 读索引和读镜像 这里不图解啦
在这里插入图片描述

ringbuffer_getchar 获取1个字节数据

在这里插入图片描述

ringbuffer_status 获取环形缓冲区状态

在这里插入图片描述

ringbuffer_data_len 获取已存在数据长度

在这里插入图片描述

ringbuffer_space_len 获取剩余数据长度

在这里插入图片描述

3.5.4 ringbuffer的使用

中断接收 + 环形缓冲区

在这里插入图片描述
在这里插入图片描述

加入环形缓冲区和中断接收效果对比

IDLE中断接收+环形缓冲区

调用IDLE接收开启IDLE 并在回调函数中接收到的写入环形缓冲区即可 接口即可
在这里插入图片描述
接收到并发送出去
在这里插入图片描述
请添加图片描述

IDLE+DMA+环形缓冲区

在配置好DMA 调用IDLE接收 在回调里 写入环形缓冲区即可
这里不做演示啦

  • 26
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103是意法半导体(STMicroelectronics)推出的一款32位单片机系列,属于Cortex-M3内核。下面是一份简要的说明,帮助你了解STM32F103。 1. 内核架构:STM32F103采用ARM Cortex-M3内核,具有较高的性能和低功耗特性。它运行在最高72MHz频率下。 2. 存储器:STM32F103具有不同的存储器选项,包括闪存(Flash)和随机存取存储器(SRAM)。闪存用于存储程序代码和常量数据,SRAM用于存储变量和堆栈。 3. 外设STM32F103拥有丰富的外设,包括通用定时器、串行通信接口(USART、SPI、I2C)、模数转换器(ADC)、通用输入输出引脚(GPIO)等。这些外设可用于实现各种应用,如控制、通信和传感器接口。 4. 开发环境:对于STM32F103的开发,你可以使用ST提供的官方开发工具——STM32CubeIDE,它是基于Eclipse的集成开发环境。此外,你还可以使用其他第三方软件,如Keil MDK或IAR Embedded Workbench。 5. 编程语言:你可以使用C/C++编程语言进行STM32F103的开发。ST提供了丰富的库函数和示例代码,方便开发者快速上手。 6. 资源:为了更好地了解STM32F103,你可以参考ST官方的技术文档、数据手册和应用笔记。此外,CSDN等网站上也有很多关于STM32F103的教程和案例供你学习参考。 需要注意的是,上述信息只是对STM32F103的一个简要介绍,如果你希望深入了解它的特性和开发方法,建议你查阅更多资料并进行实际的开发练习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值