STM32知识分享5(SPI通信协议、Unix时间戳、BKP、RTC实时时钟)
第一部分:SPI通信协议
SPI(Serial Peripheral Interface)是一种由Motorola公司开发的通用数据总线协议,用于高速同步串行通信。它基于四根通信线:SCK(Serial Clock,时钟线)、MOSI(Master Output Slave Input,主机输出从机输入)、MISO(Master Input Slave Output,主机输入从机输出)和SS(Slave Select,从机选择)。SPI采用同步全双工机制,支持总线挂载多设备(一主多从),实现高效数据交换。
1. 硬件电路连接
所有SPI设备的SCK、MOSI和MISO线分别互联,主机通过多条SS控制线连接到各从机的SS引脚。输出引脚(如MOSI)配置为推挽输出模式,输入引脚(如MISO)配置为浮空或上拉输入模式,确保信号稳定传输。
2. 通信原理与核心结构
SPI通信的核心是移位交换过程。主机内置波特率发生器(产生SCK时钟)和移位寄存器(初始数据如10101010),从机也有移位寄存器(初始数据如01010101)。关键信号线包括:
- MOSI:主机发送数据到从机。
- MISO:从机发送数据到主机。
- SCK:主机输出的同步时钟,控制移位节奏。
通信过程如下:
- 同步时钟驱动:主机的波特率发生器输出SCK脉冲,作为移位节拍器。
- 双向移位交换:每个SCK脉冲触发主机和从机的移位寄存器同时向左(或向右)移位。主机移位寄存器的最高位通过MOSI发送给从机,同时从机移位寄存器的对应位通过MISO发送给主机。
- 数据交换结果:经过8个时钟脉冲后,主机和从机的数据完全互换。例如,主机初始10101010变为接收01010101,从机初始01010101变为接收10101010,实现全双工同步通信。
关键特点:
- 全双工通信:数据收发同时完成,无需额外地址或应答信号。
- 主机控制:时钟由主机生成,从机被动同步,协议简单高效。
3. SPI时序基本单元
时序模式由CPOL(时钟极性)和CPHA(时钟相位)定义:
- 起始条件:SS从高电平切换到低电平。
- 终止条件:SS从低电平切换到高电平。
- 四种模式:
- 模式0:CPOL=0(空闲时SCK低电平),CPHA=0(第一个边沿移入数据,第二个边沿移出数据)。
- 模式1:CPOL=0(空闲时SCK低电平),CPHA=1(第一个边沿移出数据,第二个边沿移入数据)。
- 模式2:CPOL=1(空闲时SCK高电平),CPHA=0(第一个边沿移入数据,第二个边沿移出数据)。
- 模式3:CPOL=1(空闲时SCK高电平),CPHA=1(第一个边沿移出数据,第二个边沿移入数据)。
4. W25Q64存储器简介
W25Qxx系列是低成本、小型化的非易失性存储器,常用于数据存储、字库或固件程序存储。存储介质为Nor Flash,时钟频率支持80MHz(标准)、160MHz(双SPI)和320MHz(四SPI)。存储容量基于24位地址:
- W25Q40:4Mbit / 512KByte
- W25Q80:8Mbit / 1MByte
- W25Q16:16Mbit / 2MByte
- W25Q32:32Mbit / 4MByte
- W25Q64:64Mbit / 8MByte
- W25Q128:128Mbit / 16MByte
- W25Q256:256Mbit / 32MByte
Flash操作注意事项:
- 写入操作:必须先执行写使能;每个位只能从1改写为0(不能反向);写入前必须擦除(擦除后所有位变为1),擦除按最小单元进行;连续写入时,最多写入一页数据(超过页尾会覆盖页首);写入结束后,芯片进入忙状态,不响应新操作。
- 读取操作:直接调用读取时序,无需使能或额外操作;无页限制;读取结束后不进入忙状态,但忙状态时不可读取。
5. STM32 SPI外设与结构
STM32集成了硬件SPI收发电路,由硬件自动执行时钟生成和数据收发,减轻CPU负担。特性包括:
- 可配置8位/16位数据帧、高位先行或低位先行。
- 时钟频率:f_{PCLK} / (2, 4, 8, 16, 32, 64, 128, 256)。
- 支持多主机模型、主或从操作、半双工/单工精简模式、DMA兼容和I2S协议。
SPI基本结构:
- 核心模块:
- 波特率发生器:生成SCK时钟信号,决定通信速率。
- 数据控制器:协调数据发送与接收流程。
- 数据收发核心:包括发送数据寄存器(TDR,存放待发送数据)、接收数据寄存器(RDR,存放接收数据)和移位寄存器(核心数据通路,实现串并转换和全双工通信)。
- GPIO接口:输出/输入SCK、MOSI、MISO信号。
- 开关控制:对应片选(SS)信号,用于选择目标从设备。
- 工作流程:
- 主设备通过开关控制选中从设备。
- 波特率发生器输出SCK时钟。
- 数据控制器写入TDR数据,数据进入移位寄存器,在SCK驱动下通过MOSI串行发送。
- 同时,从设备数据通过MISO进入移位寄存器,接收数据存入RDR。
- 发送与接收同步完成,实现高效数据交换。
SPI控制器的核心是“时钟控制 + 移位收发”,通过四条线实现高速同步通信。
第二部分:Unix时间戳、BKP与RTC
Unix时间戳、BKP备份寄存器和RTC实时时钟是STM32中用于时间管理和数据持久化的关键模块,适用于实时系统和低功耗场景。
1. Unix时间戳
Unix时间戳定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒。时间戳存储在一个秒计数器中,该计数器为32位或64位整型变量。世界上所有时区的秒计数器相同,不同时区通过添加偏移量得到当地时间,例如当地时间$t_{\text{local}} = t_{\text{timestamp}} + \text{offset}$。
UTC/GMT基础:
- GMT(格林尼治标准时间):基于地球自转,将地球自转一周等分为24小时。
- UTC(协调世界时):基于原子钟(铯133原子跃迁辐射9,192,631,770周为1秒),当与地球自转偏差超过0.9秒时,通过闰秒协调。
时间戳转换函数(C语言time.h模块):
time_t time(time_t*):获取系统时钟的秒计数器。struct tm* gmtime(const time_t*):秒计数器转换为格林尼治时间日期。struct tm* localtime(const time_t*):秒计数器转换为当地时间日期。time_t mktime(struct tm*):当地时间日期转换为秒计数器。char* ctime(const time_t*):秒计数器转换为默认格式字符串。char* asctime(const struct tm*):日期时间转换为默认格式字符串。size_t strftime(char*, size_t, const char*, const struct tm*):日期时间转换为自定义格式字符串。
2. BKP备份寄存器
BKP(Backup Registers)用于存储用户应用程序数据,当主电源VDD(2.0~3.6V)切断时,由VBAT(1.8~3.6V)维持供电。系统在待机模式唤醒、复位或电源复位时,数据不丢失。但TAMPER引脚侵入事件会清除所有备份寄存器内容。BKP还支持RTC引脚输出校准时钟、闹钟脉冲或秒脉冲。存储容量:20字节(中/小容量设备)或84字节(大容量/互联型设备)。
BKP基本结构:
- 核心供电与输入输出:
- VBAT:备用电源输入(如纽扣电池),保证主电源掉电时数据保存。
- TAMPER:侵入检测输入,电平异常时触发事件清除数据,用于安全防护。
- RTC输出:为实时时钟提供校准或时钟信号。
- 核心寄存器组:
- 数据寄存器(DR1~DR42):共42个16位寄存器,保存用户自定义数据(图中标注大容量和互联型)。
- 控制寄存器:配置工作模式(如侵入检测触发方式)。
- 状态寄存器:记录模块状态(如侵入事件触发)。
- RTC时钟校准寄存器:微调RTC时钟频率,补偿晶振误差。
- 核心功能:
- 数据备份:VBAT供电确保数据非易失。
- 安全防护:TAMPER实现防篡改检测。
- RTC辅助:提供时钟校准支持。
3. RTC实时时钟
RTC(Real Time Clock)是一个独立定时器,提供系统时钟和日历功能。它处于后备区域,系统复位时数据不清零,VDD断电后由VBAT供电继续运行。核心包括32位可编程计数器(对应Unix时间戳秒计数器)和20位可编程预分频器(适配不同输入时钟)。支持三种时钟源:
- HSE时钟除以128(通常8MHz/128)。
- LSE振荡器时钟(通常32.768kHz)。
- LSI振荡器时钟(通常40kHz)。
RTC基本结构:
- 时钟源选择:通过多路选择器输出RTCCLK,支持:
- HSE/128:适合主电源工作时使用。
- LSE:高精度首选(外部低速晶振)。
- LSI:低成本方案(内部RC振荡器)。
- 预分频器:由PRL重装寄存器配置分频系数,决定最终计数器频率和计时精度。
RTC模块通过预分频器将输入时钟分频,驱动32位计数器,实现精准时间跟踪。
