江协科技STM32学习- P36 SPI通信外设

🚀write in front🚀

🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚

🚀Projeet source code🚀

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

stm32学习笔记-作者: Vera工程师养成记

stem32江科大自学笔记-CSDN博客

术语:

|--------------------------------------|---------------------------------------------|
| 英文缩写 | 描述 |
| GPIO:General Purpose Input Onuput | 通用输入输出 |
| AFIO:Alternate Function Input Output | 复用输入输出 |
| AO:Analog Output | 模拟输出 |
| DO:Digital Output | 数字输出 |
| 内部时钟源 CK_INT:Clock Internal | 内部时钟源 |
| 外部时钟源 ETR:External Trigger | 时钟源 External 触发 |
| 外部时钟源 ETR:External Trigger mode 1 | 外部时钟源 External 触发 时钟模式1 |
| 外部时钟源 ETR:External Trigger mode 2 | 外部时钟源 External 触发 时钟模式2 |
| 外部时钟源 ITRx:Internal Trigger inputs | 外部时钟源,ITRx (Internal trigger inputs)内部触发输入 |
| 外部时钟源 TIx:exTernal Input pin | 外部时钟源 TIx (external input pin)外部输入引脚 |
| CCR:Capture/Comapre Register | 捕获/比较寄存器 |
| OC:Output Compare | 输出比较 |
| IC:Input Capture | 输入捕获 |
| TI1FP1:TI1 Filter Polarity 1 | Extern Input 1 Filter Polarity 1,外部输入1滤波极性1 |
| TI1FP2:TI1 Filter Polarity 2 | Extern Input 1 Filter Polarity 2,外部输入1滤波极性2 |
| DMA:Direct Memory Access | 直接存储器存取 |

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。

1.🚚SPI

外设介绍

时钟频率就是SCK波形的频率,一个SCK时钟交换一个bit,所以时钟频率一般体现的是传输速度,单位是Hz或者bit/s。可以看出来,SPI的时钟其实就是由pclk分频得来的,pclk就是外设时钟,APB2的PCLK就是72MHz,APB1的PCLK是36MHz。

注意事项:

  • 💎一是这个频率数值并不是任意指定的,它只能是PCLK执行分频后的数值就只有这八个选项。
  • 💎二是SPI1和SPI2挂载的总线是不一样的,SPI1挂载在APB2,PCLK是72MHz,SPI1挂载在APB1,PCLK是36MHz,所以同样的配置,SPI1的时钟频率要比SPI2的大一倍。

兼容I2S协议:是一种数字音频信号专用协议、

接下来看一下SPI的框图,我们可以大致把它分成两部分,左上角这一部分就是数据寄存器和移位寄存器打配合的过程。然后剩下右下角这一部分,就是一些控制逻辑寄存器。

移位寄存器,右边的数据低位,一位一位的从MOSI移出去,然后MISO的数据一位一位的移入到左边的数据高位 ,显然移位寄存器应该是一个右移的状态,所以目前图上表示的是低位先行的配置。

💎对应右下角有一个LSBFIRST的控制位,这一位可以控制是低位先行还是高位先行。

这里LSBFIRST帧格式:**给0先发送MSB,MSB就是高位的意思,给1先发送LSB ,LSB 就是低位的意思。**那ppt这里目前的状态LSBFIRST的应该是1,低位先行。如果LSBFIRST给0,高位先行的话,这个图还要变动一下,就是移位寄存器变为左移,输出,从左边移出去,输入,从右边移进来,这样才符合逻辑。

然后继续看左边这一块,这里画了个方框,里面把MOSI和MISO做了个交叉,这一块主要是用来进行主从模式引脚变换的。我们这个SPI外设可以做主机,也可以做从机,做主机时这个交叉就不用,MOSI为MO,主机输出,MISO为MI,主机输入,这是主机的情况。

如果我们STM32作为从机的话,MOSI为SI,从机输入,这时他就要走交叉的这一路,输入到移位寄存器,同理MISO为SO,从机输出,这时输出的数据也走交叉的这一路输出到MISO。

接收发送缓冲区

接收发送缓冲区,这两个缓冲区实际上就是数据寄存器DR,下面发送缓冲区就是发送数据寄存器TDR,上面接收缓冲区就是接收数据寄存器RDR,TDR和RDR占用同一个地址,统一叫做DR。

💎写入DR时,数据写入到TDR,读取DR时,数据从RDR读出,数据寄存器和移位寄存器打配合,可以实现连续的数据流。

具体流程:比如我们需要连续发送一批数据,第一个数据写入到TDR,当移位寄存器没有数据移位时,TDR的数据会立刻转入移位寄存器,开始移位,这个转入时刻,会置状态寄存器的TXE为1 ,表示发送寄存器空,当我们检查TXE置1后,紧跟着下一个数据就可以提前写入到TDR里侯着了,一旦上个数据发完,下一个数据就可以立刻跟进,实现不间断的连续传输。然后移位寄存器,这里一旦有数据过来了,它就会自动产生时钟将数据移出去,在移出的过程中,MISO的数据也会移入,一旦数据移出完成,数据移入也完成了这时移入的数据就会整体的从移位计算器,转入到接收缓冲区RDR ,这个时刻会置状态寄存器器的RXNE为1 ,表示接收计寄存器器非空。当我们检查RXNE置1后,就要尽快把数据从RDR读出来 ,在下一个数据到来之前,读出RDR就可以实现连续接收。否则如果下一个数据已经收到了,上个数据还没从RDR读出来,那RDR的数据就会被覆盖,就不能实现连续的数据流了。

右下角是一些控制逻辑,首先是波特率发生器,这个主要就是用来产生SCK时钟的,它的内部主要就是一个分频器,输入时钟是PCLK72M或36M,经过分频器之后输出到SCK引脚,当然这里生成的时钟肯定是和移位寄存器同步的,每产生一个周期的时钟移入移出一个bit

然后右边CR1寄存器的三个位BR0、BR1、BR2,用来控制分频系数。手册这里看到BR[2:0] 是波特率控制,这三位写入下面这些值,可以对PCLK时钟执行2~ 256的分频,分频之后就是SCK时钟,所以这一块就对于来之前这里说的时钟频率是fpclk的2~256分频,那这就是波特率发生器的部分。

  • LSB FIRST,决定高位先行还是低位先行。
  • SPE是SPI使能,就是SPI_Cmd函数配置的位。
  • BR配置波特率,就是SCK时钟频率。
  • MSTR(Master),配置主从模式,1是主模式,0是从模式,我们一般用主模式
  • CPOL和CPHA,用来选择SPI的四种模式。
  • SR状态寄存器,TXE发送寄存器空,RXNE接收寄存器非空,这两个比较重要,我们发送接收数据的时候需要关注这两位。
  • CR2寄存器,是一些使能位,比如中断使能,DMA使能等。

NSS引脚,SS就是从机选择,低电平有效,所以这里前面加了个n,SS引脚我们直接使用一个GPIO模拟就行,因为SS引脚很简单,就置一个高低电平就行了。而且从机的情况下,ss还会有多个。

移位寄存器,是左移,高位移出去,通过GPIO到MOSI,从MOSI输出,显然这是SPI的主机。

之后引入的数据从MISO进来,通过gpio到移位寄存器的低位,这样循环八次,就能实现主机和从机交换一个字节,然后TDR和RDR的配合,可以实现连续的数据流。

另外TDR数据,整体转入移位寄存器的时刻,置TXE标志位。移位寄存器数据整体转入RDR的时刻,置RXNE标志位。

波特率发生器,产生时钟输出到SCK引脚。

数据控制器,看成是一个管理员,它控制着所有电路的运行。

开关控制就是SPI_Cmd,初始化之后,给个ENABLE,初始化整个外设。

SS从机选择引脚,另外这里并没有画SS从机选择引脚,这个引脚我们还是使用普通的GPIO来模拟即可。在一主多从的模型下,GPIO模拟的SS是最佳选择,这就是SPI的简化的结构。

非连续传输的好处,就是容易封装好理解好用,但是会损失一丢丢性能;连续传输呢传输更快,但是操作起来相对复杂,那我们来分别具体分析一下。

  • 💎首先第一行是SCK时钟线,这里CPOLl=1,CPHA=1,示例使用的是SPI模式3,所以SCK默认是高电平,然后在第一个下降沿MOSI和MISO移出数据,之后上升沿引入数据,依次这样来进行。
  • 💎第二行是MOSI/MISO输出的波形,跟随SCK时钟变化,数据位依次出现,这里从前到后依次出现的是b0~b7 ,所以这里示例演示的是低位先行的模式,实际SPI高位先行用的多一些。
  • 💎第三行是TXE发送寄存器空标志位,波形是这样的,等会儿再分析。
  • 💎第四行,是发送缓冲器(写入SPI_DR),实际上就是这里的TDR
  • 💎第三五是BSY, busy是由硬件自动设置和清除的。当有数据传输时,busy置1。

那上面这部分演示的就是输出的流程和现象。

然后下面是输入的流程和现象。

MISO/MOSI(输入),之后是RXNE接收数据寄存器非空标志位,最后是接收缓冲器(读出SPI_DR)。

发送的流程

我们来从左到右依次分析,首先SS置低电平,开始时序,在刚开始时TXE为1,表示TDR空,可以写入数据开始传输,然后下面指示的第一步就是软件写入0xF1至SPI_DR,0xF1就是要发送的第一个数据,之后看到写入之后TDR变为0xF1 ,同时TXE变为0,表示TDR已经有数据了,那此时TDR是等候区,移位寄存器才是真正的发送区。

移位寄存器刚开始肯定没有数据,所以在等候区TDR里的F1 ,就会立刻转入移位寄存器开始发送,转入瞬间置TXE标志位为1,表示发送寄存器空,然后移位寄存器有数据了,波形就自动开始生成,

数据转入移位寄存器之后,数据F1的波形就开始产生了,在移位产生F1波形的同时,等候区TDR是空的,为了移位完成时,下一个数据能不间断的跟随,这里我们就要提早把下一个数据写入到TDR里等着了。

所以下面第二步的操作,是写入F1之后,软件等待TXE=1,在这个位置,一旦TDR空了,我们就写入F2至SPI_DR,写入之后可以看到TDR的内容就变成F2了,也就是把下一个数据放到TDR里候着。

之后的发送流程也是同理,最后在这里如果我们只想发送三个数据,F3转入移位寄存器之后,TXE=1,我们就不需要继续写入了,TXE之后一直是1,注意在最后一个TXE=1之后,还需要继续等待一段时间,F3的波形才能完整发送完,等波形全部完整发送之后,busy的标志由硬件清除,这才表示波形发送完成了,那这些就是发送的流程。

接收的流程

接收的流程:SPI是全双工,发送的同时还有接收 ,所以可以看到在第一个字节发送完成后,第一个字节的接收也完成了,接收到的数据1是A1 ,这时移位寄存器的数据整体转入RDR,RDR随后存储的就是A1 ,转入的同时按RXNE标志位也置1,表示收到数据了。

我们的操作是下面这里写的,软件等待RXNE=1表示收到数据了,然后从SPI_DR也是RDR读出数据A1 ,这是第一个接收到的数据,接收之后软件清除RXNE标志位,然后当下一个数据2收到之后,RXNE重新置1,我们监测到RXNE=1时,就继续读出RDR,这是第二个数据A2 。

最后在最后一个字节时序完全产生之后,数据3才能收到,所以数据3,直到这里才能读出来,

然后注意,一个字节波形收到后,移位寄存器的数据自动转入RDR,会覆盖原有的数据所以我们读出RDR要及时,比如A1这个数据收到之后,最迟你也要在这里把它读走,否则下一个数据A2覆盖A1,就不能实现连续数据流的接收了,这是整个发送和接收的流程这个交换的流程。这个连续传输,对效率要求很高,否则的话,我们更推荐下面这个非连续传输。

非连续传输

那我们看一下这个非连续传输和连续传输,有什么区别呢,

首先这个配置还是spi模式三,sck默认高电平,发送数据时如果检测到TXE=1了,TDR为空,就软件写入0xF1至SPI_DR,这时TDR的值变为F1,TXE变为0,目前移位寄存器也是空,所以这个F1会立刻转入移位寄存器,开始发送,波形产生并且,TXE置回1,表示你可以把下一个数据放在TDR里侯着了。

但是现在区别就来了,在连续传输这里,一旦TXE等于1了,我们就会把下个数据写到TDR里侯着这样是为了连续传输数据衔接更紧密,这样的话,流程就比较混乱,程序写起来比较复杂。

所以在非连续传输这里,TXE等于1了,我们不着急把下一个数据写进去,等待第一个字节时序结束,意味着接收第一个字节也完成了,这时接收的RXNE会置1。我们等待RXNE置1后,先把第一个接收到的数据读出来,之后再写入下一个字节数据,也就是这里的(软件等待TXE等于1,但是较晚写入0xf2SPI_DR),较晚写入TDR后,数据2开始发送,我们还是不着急写数据3,等到了这里,先把接收的数据2收着,再继续写入数据3。

数据3时序结束后,最后再接收数据3置换回来的数据。

我们的整个步骤:

  • 💎第一步等待TXE为1,
  • 💎第二步写入发送的数据至TDR,
  • 💎第三步等待RXNE为1,
  • 💎第四步读取RDR接收的数据,之后交换第二个字节,重复这四步。

非连续传输缺点

非连续传输缺点:就是在这个位置没有及时把下一个数据写入TDR候着,所以等到第一个字节时序完成后,第二个字节还没有送过来,那这个数据传输就会在这里等着,所以这里时钟和数据的时序,在字节与字节之间会产生间隙,拖慢了整体数据传输的速度这个间隙在SCK频率低的时候影响不大,但是在SCK频率非常高时,间隙拖后腿的现象就比较严重了,比如我这里用示波器看了一下,不同SCK频率间隙的影响。

不同SCK频率间隙的影响

256分频

这里有四个波形,SCK分频系数分别是264、128、28、56,先看一下最慢的,256分频,这个SCK频率是72M/26大概是280k。

图示上面是SCK信号,这里使用SPI模式0,所以默认低电平,下面是SS信号,低电平表示选中从机,这个波形是SPI非连续传输,交换五个字节的时序,SCK线,连续交换了五个字节,但是你几乎看不出字节与字节之间的间隙对,因为这个时钟频率比较慢,间隙时长也不大,所以在这个比较慢的波形看来,间隙对它的影响就可以忽略了。

128分频

图是128分频,SCK频率大概560k,这时就更明显的看出来字节之间的间隙了,字节和字节之间并不是严丝合缝的,这会降低整体的字节传输速度。但这个比例上看,这一点点间隙也可以忽略不计的。

2分频

我们直接看一下最快的二分频,这个SCK时钟频率是72M/2=36M,频率非常快,已经超过这个示波器的采样频率,所以每个字节的时钟已经看不完整了。这里可以看到间隙所占的时间比例,已经是数据传输的好几倍了,不能忽略间隙。

如果你忽略了间隙,那计算一下二分频的数据传输速率,应该是256分频的128倍,当你实测一下,它肯定达不到这么高,所以通过看这个波形我们就清楚了,如果你想在极限频率下,进一步提高数据传输速率,追求最高性能,那最好使用连续传输的操作逻辑,或者还要进一步采用DMA自动转运,这些方法效率都是非常高的。

软硬件波形对比

软硬件波形对比,这里上面是软件波形,下面是硬件波形。

这些和I2C的软件件波形对比其实都是差不多的,首先他们的数据变化趋势肯定是一样的,采样得到的数据也是一样的,I2C所描述的scl低电平期间数据变化,高电平期间数据采样,与SPI的SCK下降沿数据移出,上升沿数据移入,最终波形的表现形式都是一样的。

区别就是硬件波形,数据线的变化是紧贴SCK边沿的,而软件波形数据线的变化,在边沿后有一些延迟。只是硬件波形一般会紧贴边缘,软件波形一般只能在电平期间,不过最终都不会影响数据传输,不过软件波形如果能贴近边缘,我们还是贴近边缘,否则如果你等太久比较靠近下一个边沿,那数据也容易出错。

相关推荐
小灰灰搞电子6 分钟前
STM32L4 使用低功耗串口唤醒休眠状态源码分享
stm32·单片机·嵌入式硬件
咸蛋-超人11 小时前
聊一聊 - STM32的堆和栈空间怎么分配
stm32·单片机·嵌入式硬件
raindrops.13 小时前
STM32之LL库使用(二)
stm32·单片机·嵌入式硬件
单片机系统设计16 小时前
基于STM32的水质检测系统
网络·stm32·单片机·嵌入式硬件·毕业设计·水质检测
Y1rong18 小时前
STM32之IIC
stm32·单片机
光子物联单片机1 天前
STM32传感器模块编程实践(十七)DIY智能电子门锁套件模型
c语言·stm32·单片机·嵌入式硬件·mcu
raindrops.1 天前
STM32之LL库使用(一)
stm32·单片机·嵌入式硬件
麻辣长颈鹿Sir1 天前
STM32出现FLASH擦除失败异常现象分析及解决方法
stm32·单片机·嵌入式硬件·flash写入失败·stm32g070·类内构造函数定义域异常
码咔吧咔1 天前
STM32 MCU 的引脚分类
stm32·单片机·嵌入式硬件
意法半导体STM321 天前
【文末送NUCLEO-G431RB】一文说明白STM32G4双Bank启动与升级 LAT1596
前端·数据库·stm32·单片机·嵌入式硬件·mcu·stm32开发