SPI外设简介
简介部分
-
可配置8/16位数据帧、高位先行/低位先行
-
SPI和I2C都是高位先行,串口是低位先行
-
PCLK是外设时钟,APB2是72MHz、APB1是36MHz
-
SPI1的时钟频率比SPI2的大一倍
-
如果需要快速大量传输数据,可以使用DMA数据转运,更高效
-
I2S协议主要是数字音频传输协议
框图介绍
-
左上角移位寄存器
-
右边的数据低位,一位一位的,从MOSI移出去
-
然后MISO的数据一位一位的移入到左边的数据高位
-
移位寄存器是一个右移的状态
-
LSBFIRST标志位可以控制是低位先行还是高位先行
-
发送缓冲寄存器TDR和接收缓冲寄存器RDR占用同一个地址,统一叫做DR
-
发送数据先写入TDR,再转到移位寄存器发送,发送的同时接收数据,等到八位数据从移位寄存器发送完,移位寄存器也移入了8位通过MISO来的数据,接收到的数据转到RDR,置标志位RXNE为1,然后读取数据
-
数据寄存器和移位寄存器的配合,可以实现无延迟的连续传输
-
发送和接收的寄存器是公用的
-
-
波特率发生器
-
主要用来产生SCK时钟的
-
内部主要是一个分频器
-
经过分频器之后,输出到SCK引脚
-
非连续传输步骤
-
等待TXE为1
-
写入发送的数据到TDR
-
等待RXNE为1
-
读取RDR接收的数据
硬件SPI读写W25Q64编码步骤
-
直接在MySPI模块进行修改
-
首先SS引脚还是使用软件模拟,所以写SS的函数留着
-
然后下面是三个,软件读写SPI通信引脚的函数,可以删掉
-
之后,MySPI初始化这里可以全都删掉,替换为SPI外设的初始化、(保留SS引脚的gpio初始化函数)
-
软件写SS引脚产生起始和停止信号的可以留着
-
之后,交换字节函数里的内容全都删掉,这样软件SPI操作时序的部分,就删完了
-
接着写上硬件SPI的代码就好
-
硬件SPI的代码其实就两个部分
-
第一部在初始化函数里,写上SPI初始化的代码
-
第二部分在交换一个字节函数里,写上SPI外设操作时序,完成交换一个字节的流程
-
第一步开启时钟、开启SPI和GPIO的时钟
-
第二部初始化GPIO,SCK和MOSI配置为复用推挽输出、MISO是硬件外设的输入信号,配置为上拉输入(因为输入设备可以有多个所以不存在复用输入这个东西,普通GPIO口可以输入,外设也可以输入)
-
最后是SS引脚,SS是软件控制的输出引脚,所以配置为通用推挽输出,这就是GPIO口的初始化配置
-
第三步配置SPI外设,使用一个结构体选参数即可,调用SPI_Init
-
调用SPI_Cmd给SPI使能即可
-
初始化之后,惨老这个框图,执行运行控制的代码,从而产生交换字节的时序
-
首先等待Txe为1
-
使用库函数写入DR
-
通过发送ByteSend数据,会通过MOSI一位一位的移出去,在MOSI线上,就会自动产生这个发送的时序波形,由于是非连续传输,所以时序产生的这段时间,就不必把下一个数据放到Tdr等着,这段时间直接死等过去就行了,当MOSI移位完成,证明接收移位也完成了,MISO也移入了一个字节的数据到RXE,会置标志位RXNE标志位
-
等待RXNE为1,表示收到一个字节,同时也表示发送时序产生完成了
-
读取RDR,调用库函数读取RDR
-
在这里并不需要向软件一样,手动给SCK、MOSI置高低电平,也不用关心怎么把数据一个一个的取出来,这些工作硬件电路会自动帮我们完成
-
注意事项:
1.这里的硬件SPI,必须是发送,同时接收,要想接收必须要先发送,因为只有给TDR写东西,才会触发时序的产生,如果不发送只调用接收的函数,时序是不会动的
2.TXE和RXNE是不是会自动清除的问题,上面的图上写的是,TXE标志由硬件置位,并由软件清除、RXNE也是,这个由软件清除就比较迷惑,是不是要求我们,在标志位置1之后,还需要我们手动调用清除标志位的函数,实际上 这个并不需要我们手动清除,手册上状态标志那一节有写
-
-