SPI通信和RTC实时时钟
SPI通信
一、简介
有四根通信线SCK(Serial Clock 串行时钟线)、MOSI(Master Output Slave Input 主机输出从机输入)、MISO(Master Input Slave Output 主机输入从机输出)、SS(Slave Select 从机选择)
同步时序(SCK),全双工(MOSI、MISO)
支持总线挂载多设备,是一主多从,有一条专门用来进行从机选择的线(SS),一机一根
二、硬件电路
看清楚箭头,箭头是传输方向
每有一个从机,SPI主机都要引出一根SS线连接
这里的端口电压为比较电压,是相对于GND的电压,所以所有设备需要共地,如果从机没有电源的话,还需要从主机VCC连接线来供电
主机通过置SS为低电平选择从机进行通信,在初始状态时,主机的所有SS引脚都为高电平,且在同一时间只能与一个从机进行通信
输出引脚配置为推挽输出,输入引脚配置为浮空输入或上拉输入
三、基本原理
SPI通信的基本原理就是进行移位交换
首先波特率发生器存在于主机,由主机控制,通过SLK线使从机同步时序,移位寄存器都是向左移位,移出后在MOSI和MISO产生相应的电平变化,如下图所示
向左移位移出,同时通信线发生移出数字相应的电平变化,然后再写入
如此往复八次就能实现一个字节的迁移,这是同时发送接收的情况
在只进行发送和只进行接收的时候,也是一样的移位和迁移,但只进行发送 时,此时从机移位寄存器中的值为无效值 ,通常为0x00或0xFF,只进行接收 的时候,主机移位寄存器中的值为无效值
四、SPI时序
起始条件:SS从高电平切换到低电平
终止条件:SS从低电平切换到高电平
1、时序基本单元
CPOL时钟极性
CPHA时钟相位
CPOL | CPHA | 模式 | 说明 |
---|---|---|---|
0 | 0 | 模式0 | 空闲状态时,SCK为低电平;SCK第一个边沿移入数据,第二个边沿移出数据 |
0 | 1 | 模式1 | 空闲状态时,SCK为低电平;SCK第一个边沿移出数据,第二个边沿移入数据 |
1 | 0 | 模式2 | 空闲状态时,SCK为高电平;SCK第一个边沿移入数据,第二个边沿移出数据 |
1 | 1 | 模式3 | 空闲状态时,SCK为高电平;SCK第一个边沿移出数据,第二个边沿移入数据 |
在SS由高电平切换到低电平后,在SCK第一个边沿(CPOL=0是上升沿,CPOL=1是下降沿)之前,MOSI和MISO开始变换电平,在第一个边沿移入(CPHA=0,CPHA=1为移出)数据,然后在第二个边沿(CPOL=0是下降沿,CPOL=1是上升沿)移出(CPHA=0,CPHA=1为移出)数据
但是在CPHA=0的情况下,第一个数据还没有移出肯定是没有办法移入的,所以在SS下降沿时,在SCK第一个边沿之前就要触发移出数据,移出数据是对应着MOSI和MISO上升或下降沿的
2、时序
SPI的时序与I2C的时序基本相同,有些细微的差别,不多赘述
五、FLASH操作注意事项
1、写入操作
写入操作之前要先进行使能
每个数据位只能由1改写为0,不能由0改写为1
写入数据前必须先擦除,擦除后,所有数据位变为1,因为这样可以使再写入的数据保持原样
擦除必须按最小擦除单元(一个扇区)进行,没办法只擦除一个指定字节,只能整片一起擦,除非该扇区只存储了这一个字节
连续写入多字节时,最多写入一页的数据(缓冲区存储),超过页尾位置的数据会回到页首覆盖写入
写入(或者擦除)操作结束后,芯片进入忙状态,不响应新的读写操作,忙状态就是缓冲区向FLASH写入的这个状态,读取状态寄存器,如果BUSY位为1,就是忙状态,如果为0,就不是忙状态了,就可以继续响应新的操作了
2、读取操作
直接调用读取时序,无需使能,无需额外操作,没有页的限制,读取操作结束后不会进入忙状态,但不能再忙状态时读取
六、SPI外设
1、简介
STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能、减轻CPU的负担
时钟频率只能为外部时钟除以2,4,8,16,32,64,128,256来得到
支持多主机模型或一主多从模型
可精简为半双工或单工通信,半双工就是在SPI的两条通信线中选择一条进行双向通信,类似于I2C,单工通信就是指去除SPI两根通信线的某一根,另一根功能不变
2、结构
先看左上角红色方框,这里是一个重叠电路,因为MOSI在设备时主机时输出是从机时输入,MISO同理,所以在设备做主机和从机时所走的线路不一样,因为接在移位寄存器上的线路是不变的,所以我们要改变前面的线路,在做主机时,就是从蓝色的线直接进出,做从机时输出,就在上方蓝线经过红色方框的电路时走到下方的棕色线上去,然后从MISO输出,输入就是从MOSI进入时走下方棕色线到移位寄存器
然后绿色椭圆就是发送接收的缓冲区以及移位寄存器,LSBFIRS控制位控制移位为左移还是右移,要发送的数据写入发送缓冲区后一位一位地移入移位寄存器,然后再由移位寄存器一位一位地移出,此时TXE和RXNE的变化与USART串口的相同,不过串口有两个移位寄存器,这里只有一个
下方的蓝色椭圆中就是波特率发生器,外接时钟,可以如上面所说的按照指定比例分频,与移位寄存器时序相同,这里的波特率发生器由绿色方框中的BR0、BR1、BR2共同控制
最后就是蓝色方框以及绿色方框中的寄存器,我们可以看到蓝色方框中我们熟悉的寄存器如TXE和RXNE,绿色方框中的CPOL、CPHA
七、传输方式
连续传输适用于高性能、高要求的传输,相应地,其代码也要更加复杂,如果没有严格要求,可以使用非连续传输,更简单一些
1、主模式全双工连续传输
这里的BSY标志就是上面提到的BUSY
发送:
开始时TXE为1,表示发送缓冲器TDR为空,可以写入并传输,然后看下方的指示,发送缓冲器TDR被写入0xF1,同时TXE置0,然后发送缓冲器TDR中的数据会转入移位寄存器,此时TXE置为1,然后移位寄存器就开始发送,波形开始生成
然后按照下方指示2,写入0xF1之后,软件等待TXE=1,也就是在发送缓冲器TDR中的数据转入到移位寄存器时,写入发送缓冲器TDR第二个数据0xF2,当第一个数据0xF1发送完毕后,第二个数据0xF2就转入到移位寄存器中发送,同时第三个数据再写入发送缓冲器TDR,以此类推
当发送最后一个数据时,最后一个数据转入移位寄存器后TXE置为1,当BSY标志位0时,表示当前不忙,也就是发送完毕
接收:
当第一个数据接收完成时,转入接收缓冲器RDR,转入的同时RXNE置1,检测到RXNE为1时就读出RDR,等CPU读出后,RXNE置0,重复上述过程,读取多个数据
RDR中的数据在写入后要尽快读走,要在下一个数据写入之前,因为RDR再被写入前一个数据就会被覆盖
2、非连续传输
该图只有输出,没有输入,因为非连续传输的原理比较简单,一发一收
发送:
这里跟上面其实是一样的,只不过在这里主要看BSY位,因为非连续传输不需要连续,所以一个数据写入TDR后,移位到移位寄存器发送,此时TDR为空,但此时不需要再写入新的数据到TDR中,在BSY位置为0时再写入,然后重复上述过程
接收:
输入就更简单了,当数据写入移位寄存器后,由移位寄存器转移到RDR中,此时不用紧跟着数据写入移位寄存器,而是在移位寄存器RDR中的数据读出后,再继续写入下一个数据到移位寄存器,重复上述过程
RTC实时时钟
一、Unix时间戳
Unix时间戳定义为伦敦时间从1970年1月1日0时0分0秒开始所经过的秒数
时间戳存储在一个秒计数器中,秒计数器为32位或64位的变量
也就是说,如果该变量为无符号型,也就是它所能承受的最大值为2^32-1或2 ^64-1,后面这个数字是非常大的,宇宙级别的时间,所以现在随着科技的进步,很多设备都给上64位的版本了
世界上所有时区的秒计数器相同,不同时区通过添加偏移量来得到当地时间,这个偏移量其实就是时差
0秒标志着伦敦时间1970年1月1日0时0分0秒,北京时间1970年1月1日8时0分0秒
二、BKP
1、简介
BKP就是备份寄存器,可用于存储用户应用程序数据,当VDD电源(系统主电源2.0~3.6V)被切断,它们仍然由VBAT(备用电池电源1.8 ~ 3.6V)维持供电,当系统在待机模式下被唤醒,或系统复位或电源复位时,它们也不会被复位
TAMPER引脚产生的侵入事件将所有备份寄存器内容清除(这是一个保护功能,防拆作用)
RTC引脚输出RTC校准时钟、RTC闹钟脉冲或秒脉冲
存储RTC时钟校准寄存器
用户数据存储容量为20字节(小容量和中容量设备)或84字节(大容量和互联型设备)
2、基本结构
BKP先通过VDD进行供电,在有主电源VDD的情况下优先使用主电源供电
数据寄存器是16位的,每个寄存器可以存储两字节,小容量和中容量的设备一般有10个数据寄存器,从DR1到DR10,大容量和互联型的设备一般有42个数据寄存器,从DR1到DR42
因为BKP与RTC联系紧密,所以BKP中有控制RTC的部分
三、RTC
1、简介
RTC就是实时时钟,是一个独立地定时器,可为系统提供时钟和日历的功能
RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD断电后可借助VBAT供电继续走时(同BKP)
32位的可编程计数器,可对应Unix时间戳的秒计数器
20位的可编程预分频器,可适配不同频率的输入时钟
可选择三种RTC时钟源:
HSE(外部高速晶振)时钟除以128
LSE(外部低速晶振)振荡器时钟(主要使用,只有这个连接着备用电源)
LSI(内部低速晶振)振荡器时钟
2、基本结构
RTC时钟外接一个RTCCLK,一般是外部低速晶振,红色方框里的就是一个预分频器,与前面介绍过的预分频器其实是一种类型,并且实现方式相同,只是这里用了不同的名字
然后就是绿色方框里的就是一个32位的可编程计数器,是无符号32位,最多使用到2106年,到时候就会发生溢出,就可以产生一个溢出中断,也就是RTC_Overflow中断,绿框中还一个闹钟设备RTC_ALR,给它定一个时间,当CNT==ALR时,就会触发RTC_Alarm中断,也可以通过下面的线退出待机模式,最后还有一个中断就是RTC_Second中断,是每秒进一个中断
右边的三个中断,F结尾的是对应的中断标志位,IE结尾的是中断使能,凉凉通过一个与门,之后三个中断连接到一个或门连接NVIC中断控制器
上图就是RTC外部电路,一个是备用电池供电,一个是外部低速晶振
备用电池在标准下应该用推荐连接,这里在电路上有两个二极管,这两个二极管的作用就是防止电流倒灌,在有外接电源时,使用3.3V的外部电源,在无外部电源时,使用备用电池B2供电,外部还需要接一个0.1uF的滤波电容
3、注意事项
设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟
设置PWR_CR的DBP,使能对BKP和RTC的访问
若在读取RTC寄存器时,若RTC的APB1接口处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1
必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器
对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行,可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中,仅当RTOFF状态位为1时,才可以写入RTC寄存器
(这跟上面的忙状态差不多)
今日分享就到这里了~