1. Unix时间戳
1.1 Unix时间戳简介
Unix时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始,共计经历的秒数,不考虑闰秒。
只使用秒计时,不进位。时间戳存在于一个秒计数器,为32位/64位的整型变量。
根据计算,32位有符号数变量会于2038年溢出。世界上所有地区的秒计数器相同,不同时间通过添加偏移来得到当地时间,如下图所示:
1.2 GMT和UTC
GMT(格林尼治平均时):基于格林尼治天文台观测地球自转得到的平太阳时,是旧的世界时间标准,现多仅用于口语时区表达。
UTC(协调世界时):以原子钟为基础的现代国际标准时间基准,通过闰秒适配地球自转,全球时区以此为参照。
1.3 Time.h模块
C语言的Time.h模块提供了时间获取和时间戳转换的函数。
可以方便的进行秒计数器,日期时间和字符串之间的转换。
- 核心类型
time_t:一般是long类型,用来保存时间戳(从 1970-01-01 00:00:00 UTC 起算的秒数)struct tm:结构体,保存年月日时分秒星期的分解日历时间
structtm{inttm_sec;// 秒 0~59inttm_min;// 分 0~59inttm_hour;// 时 0~23inttm_mday;// 日 1~31inttm_mon;// 月 0~11(0代表1月!考点坑)inttm_year;// 年:从1900开始算,要+1900才是真实年份inttm_wday;// 星期 0=周日inttm_yday;// 年内第几天inttm_isdst;// 夏令时标记};高频函数:
| 函数 | 功能 |
|---|---|
time(time_t *t) | 获取当前时间戳(UTC 基准) |
localtime(const time_t *) | 时间戳 → 本地时间,返回struct tm* |
gmtime(const time_t *) | 时间戳 → UTC 世界时,返回struct tm* |
mktime(struct tm*) | 本地tm结构体 → 转回时间戳 |
strftime() | 把tm结构体格式化成时间字符串 |
difftime(t2,t1) | 计算两个time_t的时间差,返回 double(秒) |
2. BKP寄存器
2.1 简介
BKP(Backup Register)备份寄存器
- BKP 是 STM32 备份域里的一组 16 位寄存器
- 主电源 VDD 断电后,只要 VBAT 备用电池有电,BKP 里的数据就不会丢
- 普通系统复位、上电复位、待机唤醒,都不会清空 BKP
功能:
- 用户数据存储:掉电保存少量参数,重启直接读取。
- TAMPER 侵入检测:PC13 复用为 TAMPER 引脚,可配置:一旦检测到引脚电平变化(拆开设备触发开关),硬件自动清空全部 BKP 寄存器,还能触发中断,用于安全设备防篡改。
用户数据存储容量:
- 小 / 中容量(F103C8T6):10 个 16 位寄存器,总共 20 字节(BKP_DR1 ~ BKP_DR10)
- 大容量 / 互联型:42 个 16 位寄存器,总共 84 字节(BKP_DR1 ~ BKP_DR42)
基本结构:
RTC时钟输出:
RTC 输出引脚 PC13 属于备份域,可硬件输出 512Hz 校准时钟或闹钟脉冲,主芯片断电、VBAT 有电时仍能输出信号。
2.2 VDD和VBAT
- VDD(3.3V 主电源)正常工作:后备域由 VDD 供电,VBAT 电池不耗电
- VDD 掉电:芯片内部自动切换,后备域由**VBAT(1.8~3.6V)**供电,维持 RTC 计时和BKP 数据
3. RTC
3.1 RTC简介
RTC(Real Time Clock)实时时钟
- RTC是一个独立的定时器,可以为系统提供时钟和日历的功能;
- RTC位于后备区域,可通过VBAT供电;
- RTC通过32位可编程计数器存储秒,对应Unix时间戳的秒计数器;
- 20位的可编程预分频器,适配不同频率的时钟;
时钟源:
HSE时钟除以128(此时再经过20分频,可以得到1Hz的时钟)
LSE振荡器时钟(经过32768分频后刚好1秒)
LSI振荡器时钟(经过40Khz的分频,得到1Hz的时钟)
只有LSE才能通过VBAT供电;
3.2 RTC框图
灰色部分为备用区域,待机的时候会维持供电;
RTCCLK进入时,首先经过预分频,然后计数器进行计数。
RTC_ALR,可以设置一个闹钟,当计数器的值和RTC_ALR的值相同会产生一个中断。
RTC可以产生右边的三个中断:
RTC_Second:开启此中断,会每秒进入一次中断;
RTC_Overflow:32位计数器溢出,2106年才会溢出;
RTC_Alarm:闹钟中断;
可以通过WKUP或者闹钟信号唤醒待机:
结构简图:
3.3 VBAT供电方案
按照数据手册,直接向VBAT引脚供电,内部搭配供电开关,可以实现电路的切换:
按照参考手册的推荐电路:
4. PWR
4.1 简介
PWR负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能。
PVD(可编程电压监测器)可以检测VDD电源电压,当VDD下降到PVD的阈值以下或者上升到PVD阈值之上,PVD会触发中断,用于执行紧急关闭任务。
低功耗模式包括:
睡眠模式(Sleep),停机模式(Stop)和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备使用时间。
4.2 电源框图
分为模拟供电VDDA,数字供电VDD以及备用电源VBAT
模拟供电部分:正极为VDDA负极为VSSA,以及AD转换器有VREF-和VREF+
数字供电部分:CPU核心,存储器和内部数字外设供电为1.8V
低电压监测器,就是用来检测是否有电,从而切换VBAT供电,当VDD有电,此时由VDD供电,当VDD没电,此时由VBAT供电。
4.3 PVD
当电压过低,或者过高,可以触发中断,进入中断,进行对应的操作:
中断申请通过外部中断实现:
4.4 低功耗模式
图中分别展示了三种低功耗模式:
且从上到下关闭的区域越多:
睡眠模式:只是将CPU时钟关闭,可以通过任意中断或者事件进行唤醒
停机模式:将1.8V区域时钟,以及振荡器关闭
待机模式:三部分都关闭,只能通过表格特定的事件唤醒
中断和事件:
中断要 CPU 跑代码;事件只是硬件信号,可查询可触发别的外设。
4.4 低功耗模式选择
执行WFI(Wait For Interrupt)或者WFE(Wait For Event)指令后,STM32进入低功耗模式
PDDS = Power Down DeepSleep
LPDS = Low-Power DeepSleep
5. Flash闪存
5.1 简介
Flash包括:
程序存储器,系统存储器和选项字节三个部分
作用:
- 利用程序存储器保存掉电不丢失的用户数据;
- 在程序中编程(In-Application Programming),实现程序的自我更新;
在进行Flash的写操作过程,只能对页进行操作。最小的修改单位为页。
5.2 内部闪存模块
闪存分为小容量,中容量和大容量产品:
以中容量产品为例:
三部分Flash是上面的三部分
通过闪存存储器接口寄存器来对Flash进行擦除和编写:
页的起始地址:
0000 0400 0800 0C00 1000
5.3 Flash基本结构简图
闪存的基本结构如下图所示:
5.4 芯片的电子签名
电子签名存储在系统存储器,包含芯片识别信息,在出厂时编写,不可更改。
闪存容量寄存器:
基地址:0x1FFF F7E0
大小: 16位
产品唯一身份标识寄存器:
基地址:0x1FFF F7E8
大小:96位
作用:
可以对程序进行加密操作,如果想要程序只能在指定设备运行,那么可以在程序多处加入ID号判断。