目录
- RTC 实时时钟实验
- RTC 时钟简介
- RTC 框图
- RTC 寄存器
- 硬件设计
- 低功耗实验
- 电源控制(PWR)简介
- 电源系统
- 电源监控
- 电源管理
- PVD 电压监控实验
- PWR 寄存器
- 硬件设计
- 睡眠模式实验
- 硬件设计
- 停止模式实验
- PWR 寄存器
- 硬件设计
- 待机模式实验
- PWR 寄存器
- 硬件设计
- ADC 实验
- ADC 简介
- 单通道ADC 采集实验
- ADC 寄存器
- 内部温度传感器实验
- 光敏传感器实验
- DAC 实验
RTC 实时时钟实验
本章,我们将介绍STM32F103 的内部实时时钟(RTC)。我们将使用LCD 模块来显示日期
和时间,实现一个简单的实时时钟,并可以设置闹铃,另外还将介绍BKP 的使用。
RTC 时钟简介
STM32F103 的实时时钟(RTC)是一个独立的定时器。STM32 的RTC 模块拥有一组连续
计数的计数器,在相对应的软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设
置系统的当前时间和日期。
RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模
式唤醒后RTC 的设置和时间维持不变,只要后备区域供电(纽扣电池)正常,那么RTC 将可以一直运行。
但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外写操
作。所以在要设置时间之前,先要取消备份区域(BKP)写保护。
RTC 框图
下面先来学习RTC 框图,通过学习RTC 框图会有一个很好的整体掌握,同时对之后的编
程也会有一个清晰的思路。RTC 的框图,如图27.1.1 所示:
我们在讲解RTC 架构之前,说明一下框图中浅灰色的部分,他们是属于备份域的,在VDD
掉电时可在VBAT的驱动下继续工作,这部分包括RTC 的分频器,计数器以及闹钟控制器。在
寄存器部分才展开解释一下备用域。下面把RTC 框图分成以下2 个部分讲解:
①APB1 接口: 用来和APB1 总线相连。通过APB1 总线可以访问RTC 相关的寄存器,对
其进行读写操作。
②RTC 核心: 由一组可编程计数器组成,主要分成两个模块。第一个模块是RTC 的预分
频模块,它可编程产生1 秒的RTC 时间基准TR_CLK。RTC 的预分频模块包括了一个20 位的
可编程分频器(RTC 预分频器)。如果在RTC_CR 寄存器中设置相对应的允许位,则在每个
TR_CLK 周期中RTC 产生一个中断(秒中断)。第二个模块是一个32 位的可编程计数器,可被
初始化为当前的系统时间,一个32 位的时钟计数器,按秒钟计算,可以记录4294967296 秒,
约合136 年左右,作为一般应用足够了。
RTC 还有一个闹钟寄存器RTC_ALR,用于产生闹钟。系统时间按TR_CLK 周期累加并与
存储在RTC_ALR 寄存器中的可编程时间相比较,如果RTC_CR 控制寄存器中设置了相应允许
位,比较匹配时将产生一个闹钟中断。
由于备份域的存在,所以RTC 内核可以完全独立于RTC APB1 接口。而软件是通过APB1
接口访问RTC 的预分频值、计数器值和闹钟值的。但是相关可读寄存器只在RTC APB1 时钟
进行重新同步的RTC 时钟的上升沿被更新,RTC 标志也是如此。这就意味着,如果APB1 接
口刚刚被开启之后,在第一次的内部寄存器更新之前,从APB1 上读取的RTC 寄存器值可能
被破坏了(通常读到0)。因此,若在读取RTC 寄存器曾经被禁止的RTC APB1 接口,软件
首先必须等待RTC_CRL 寄存器的RSF 位(寄存器同步标志位,bit3)被硬件置1。
RTC 寄存器
接下来,我们介绍本实验我们要用到的RTC 寄存器。
⚫ RTC 控制寄存器(RTC_CRH/CRL)
RTC 控制寄存器共有两个控制寄存器RTC_CRH 和RTC_CRL,两个都是16 位的。
RTC 控制寄存器高位RTC_CRH,描述如图27.1.2.1 所示:
该寄存器是RTC 控制寄存器高位,本章将用到秒钟中断,所以在该寄存器必须设置最低位
为1,以允许秒钟中断。
RTC 控制寄存器低位RTC_CRL,描述如图27.1.2.2 所示:
该寄存器是RTC 控制寄存器低位,本章我们用到的是该寄存器的0,3~5 这几个位,第0
位是秒钟标志位,我们在进入闹钟中断的时候,通过判断这位来决定是不是发生了秒钟中断。
然后必须通过软件将该位清零(写零)。第3 位为寄存器同步标志位,我们在修改控制寄存器
RTC_CRH/RTC_CRL 之前,必须先判断该位,是否已经同步了,如果没有则需要等待同步,在
没同步的情况下修改RTC_CRH/RTC_CRL 的值是不行的。第4 位为配置标志位,在软件修改
RTC_CNT/RTC_PRL 的值的时候,必须先软件置位该位,以允许进入配置模式。第5 位为RTC
操作位,该位由硬件操作,软件只读。通过该位可以判断上次对RTC 寄存器的操作是否完成,
如果没有,我们必须等待上一次操作结束才能开始下一次操作。
⚫ RTC 预分频装载寄存器(RTC_PRLH/RTC_PRLL)
RTC 预分频装载寄存器也是有两个寄存器组成,RTC_PRLH 和RTC_PRLL。这两个寄存器
用来配置RTC 时钟的分频数的,比如我们使用外部32.768K 的晶振作为时钟的输入频率,那么
我们要设置这两个寄存器的值为32767,得到一秒钟的计数频率。
RTC 预分频装载寄存器高位描述如图27.1.2.3 所示:
该寄存器是RTC 预分频装载寄存器高位,低四位有效用来存放PRL 的19~16 位。关于PRL
的其余位存放在RTC_PRLL 寄存器。
RTC 预分频装载寄存器低位描述如图27.1.2.4 所示:
该寄存器是RTC 预分频装载寄存器低位,存放RTC 预分频装载值低位。如果输入时钟是
32.768kHz,这个预分频寄存器中写入0x7FFF 可获得周期1 秒钟的信号。
⚫ RTC 预分频余数寄存器(RTC_DIVH/RTC_DIVL)
RTC 预分频余数寄存器是用来获得比秒钟更加准确的时钟,比如可以得到0.1 秒,甚至0.01
秒等,该寄存器的值自减的,用于保存还需要多少时钟周期获得一个秒信号。在一次秒钟更新
后,由硬件重新装载。这两个寄存器和RTC 预分频装载寄存器的各位是一样的,这里我们就
不列出来了。
⚫ RTC 计数器寄存器(RTC_CNTH/RTC_CNTL)
RTC 计数器寄存器RTC_CNT,由2 个16 位寄存器组成RTC_CNTH 和RTC_CNTL,总共
32 位,用来记录秒钟值。注意的是,修改这两个寄存器的时候要先进入配置模式。RTC_CNT 描
述如图27.1.2.5 所示:
⚫ RTC 闹钟寄存器(RTC_ALRH/RTC_ALRL)
RTC 闹钟寄存器,该寄存器也是由2 个16 位的寄存器组成RTC_ALRH 和RTC_ALRL。总
共32 位,用来标记闹钟产生的时间(以秒为单元)。对于STM32F1 系列的芯片来说,RTC 外
设没有专门的年用日寄存器来分别存放这些信息,全部日期信息以秒的格式存储在这两个寄存器中,后面编程时会对时间进行特殊处理。如果RTC_CNT 的值与RTC_ALR 的值相等,并使
能了中断的话,会产生一个闹钟中断。注意:该寄存器的修改也是要进入配置模式才能进行。
RTC 闹钟寄存器描述如图27.1.2.6 所示:
⚫ 备份数据寄存器(BKP_DRx)
备份数据寄存器描述如图27.1.2.6 所示。
该寄存器是一个16 位寄存器,可以用来存储用户数据,可在VDD 电源关闭时,通过VBAT
保持上电状态。备份数据寄存器不会在系统复位、电源复位、从待机模式唤醒时复位。
那么在MCU 复位后,对RTC 和备份数据寄存器的写访问就被禁止,需要执行一下操作才
可以对RTC 及备份数据寄存器进行写访问:
- 通过设置寄存器RCC_APB1ENR 的PWREN 和BKPEN 位来打开电源和后备接口时钟
- 电源控制寄存器(PWR_CR)的DBP 位来使能对后备寄存器和RTC 访问
⚫ 备份区域控制寄存器(RCC_BDCR)
备份区域控制寄存器描述如图25.1.2.7 所示。
RTC 的时钟源选择及使能设置都是通过这个寄存器来实现的,所以我们在RTC 操作之前
先要通过这个寄存器选择RTC 的时钟源,然后才能开始其他的操作。
硬件设计
-
例程功能
本实验通过LCD 显示RTC 时间,并可以通过usmart 设置RTC 时间,从而调节时间,或设
置RTC 闹钟,还可以写入或者读取RTC 后备区域SRAM。LED0 闪烁,提示程序运行。 -
硬件资源
1)LED 灯
LED0 – PE5
LED1 – PB5
2)串口1(PA9/PA10 连接在板载USB 转串口芯片CH340 上面)
3)RTC(实时时钟)
4)正点原子2.8/3.5/4.3/7/10 寸TFTLCD 模块(仅限MCU 屏,16 位8080 并口驱动) -
原理图
RTC 属于STM32F103 内部资源,通过软件设置好就可以了。不过RTC 不能断电,否则数
据就丢失了,我们如果想让时间在断电后还可以继续走,那么必须确保开发板的电池有电。
低功耗实验
本章,我们将介绍STM32F103 的电源控制(PWR),并实现低功耗模式相关功能。我们将
通过四个实验来学习并实现低功耗相关功能,分别是PVD 电压监控实验、睡眠模式实验、停止
模式实验和待机模式实验。
电源控制(PWR)简介
电源控制部分(PWR)概述了不同电源域的电源架构以及电源配置控制器。PWR 的内容比
较多,我们把它们的主要特性概括为以下3 点:
电源系统:VDDA供电区域、VDD供电区域、1.8V 供电区域、后备供电区域。
电源监控:POR/PDR 监控器、PVD 监控器。
电源管理:低功耗模式。
下面将分别对这3 个特性进行简单介绍。
电源系统
为了方便对电源系统进行管理,设计者把STM32 的内核和外设等器件跟据功能划分了不
同的电源区域,具体如图28.1.1.1 所示。
在电源概述框图中我们划分了3 个区域①②③,分别是独立的A/D 转换器供电和参考电
压、电压调节器、电池备份区域。下面分别进行简单介绍:
①独立的A/D 转换器供电和参考电压(VDDA供电区域)
VDDA供电区域,主要是ADC 电源以及参考电压,STM32 的ADC 模块配备独立的供电方
式,使用了VDDA引脚作为输入,使用VSSA引脚作为独立地连接,VREF引脚为提供给ADC 的
参考电压。
②电压调节器(VDD /1.8V 供电区域)
电压调节器是STM32 的电源系统中最核心部分,连接VDD供电区域和1.8 供电区域。VDD
供电来自于VSS和VDD,给I/O 电路以及待机电路供电,电压调节器主要为备份域以及待机电
路以外的所有数字电路供电,其中包括内核、数字外设以及RAM,调节器的输出电压约为1.8V,
因此由调压器供电的区域称为1.8V 供电区域。
电压调节器根据应用方式不同有三种不同的工作模式。在运行模式下,调节器以正常工作
模式为内核、内存和外设提供1.8V;在停止模式下,调节器以低功耗模式提供1.8V 电源,以
保存寄存器和SRAM 的内容。在待机模式下,调节器停止供电,除了备用电路和备份域外,寄
存器和SRAM 的内容全部丢失。
③电池备份区域(后备供电区域)
电池备份区域也就是后备供电区域,使用电池或者其他电源连接到VBAT脚上,当VDD断电
时,可以保存备份寄存器的内容和维持RTC 的功能。同时VBAT 引脚也为RTC 和LSE 振荡器
供电,这保证了当主要电源被切断时,RTC 能够继续工作。切换到VBAT供电由复位模块中的掉
电复位功能控制。
电源监控
电源监控的部分我们主要关注PVD 监控器,此外还需要知道上电复位(POR)/掉电复位
(PDR)。其他部分的内容请大家查看《STM32F10xxx 参考手册_V10(中文版).pdf》第4.2 节
(38 页)。
⚫ 上电复位(POR)/掉电复位(PDR)
上电时,当VDD低于指定VPOR阈值时,系统无需外部复位电路便会保持复位模式。一旦
VDD电源电压高于VPOR阈值,系统便会退出复位状态,芯片正常工作。掉电时,当VDD低于指
定VPDR阈值时,系统就会保持复位模式。如图28.1.2.1 所示,RESET 为上电复位信号。
注意:POR 与PDR 的复位电压阈值是固定的,VPOR阈值(典型值)为1.92V,VPDR阈值
(典型值)为1.88V。
⚫ 可编程电压检测器(PVD)
上面介绍的POR、PDR 功能都是设置电压阈值与外部供电电压VDD比较,当VDD低于设
置的电压阈值时,就会直接进入复位状态,防止电压不足导致的误操作。
下面介绍可编程电压检测器(PVD),它可以实时监视VDD的电压,方法是将VDD与PWR
控制寄存器(PWR_CR)中的PLS[2:0]位所选的VPVD阈值进行比较。其中PWR_CSR 寄存器中
的PVDO 位决定了VDD是高于VPVD还是低于VPVD,本实验中配置的是VDD低于VPVD阈值这
个条件。当检测到电压低于VPVD阈值时,如果使能EXTI16 线中断,即使能PVD 中断,可以
产生PVD 中断,具体取决于EXTI16 线配置为检测上升还是下降沿,然后在复位前,在中断服
务程序中执行紧急关闭系统等任务。PVD 阀值检测波形,如图28.1.2.2 所示。
PVD 阀值有8 个等级,有上升沿和下降沿的区别,具体由PWR_CSR 寄存器中的PVDO 位
决定。PVD 阈值等级表具体如表28.1.2.1 所示。
电源管理
电源管理的部分我们要关注低功耗模式,在STM32 的正常工作中,具有四种工作模式,运
行、睡眠、停止以及待机。在上电复位后,STM32 处于运行状态时,当内核不需要继续运行,
就可以选择进入后面的三种模式降低功耗。这三种低功耗模式电源消耗不同、唤醒时间不同和
唤醒源不同,我们要根据自身的需要选择合适的低功耗模式。
下面是低功耗模式汇总介绍,如下表所示。
下面对睡眠模式、停止模式和待机模式,分开介绍。
1、睡眠模式
进入睡眠模式,Cortex_M3 内核停止,所有外设包括Cortex_M3 核心的外设,如NVIC、系
统时钟(SysTick)等仍在运行,有两种进入睡眠模式的模式WFI 和WFE。WFI(Wait for interrupt)
和WFE(Wait for event)是内核指令,会调用一些汇编指令,我们会使用即可,更详细的描述可
以查看《CM3 权威指南》。睡眠后唤醒的方式即由等待“中断”唤醒和“事件”唤醒。
2、停止模式
进入停止模式,所有的时钟都关闭,所有的外设也就停止了工作。但是VDD电源是没有关
闭的,所以内核的寄存器和内存信息都保留下来,等待重新开启时钟就可以从上次停止的地方
继续执行程序。
值得注意的是:当电压调节器处于低功耗模式下,当系统从停止模式退出时,将会有一段
额外的启动延时。如果在停止模式期间保持内部调节器开启,则退出启动时间会缩短,但相应
的功耗会增加。
3、待机模式
待机模式可实现最低功耗。该模式是在CM3 深睡眠模式时关闭电压调节器,整个1.8V 供
电区域被断电。PLL、HSI 和HSE 振荡器也被断电。除备份域(RTC 寄存器、RTC 备份寄存器
和备份SRAM)和待机电路中的寄存器外,SRAM 和其他寄存器内容都将丢失。不过如果我
们使能了备份区域(备份SRAM、RTC、LSE),那么待机模式下的功耗,将达到3.8uA 左右。
那么我们如何进入待机模式呢?其实很简单,只要按表28.1.3.3 所示的步骤执行就可以了:
PVD 电压监控实验
本小节我们来学习PVD 电压监控实验,该部分的知识点内容请回顾28.1.2 电源监控。我们
直接从寄存器介绍开始。
PWR 寄存器
本实验用到PWR 的部分寄存器,在《STM32F10XXX 参考手册(中文版)》的4.4 小节可以
找到PWR 寄存器描述。这里我们只介绍PVD 电压监控实验用到的PWR 控制寄存器(PWR_CR),
还有就是我们要用到EXTI16 线中断,所以还要配置EXTI 相关的寄存器,具体如下:
⚫ PWR 控制寄存器(PWR_CR)
PWR 控制寄存器描述如图28.2.1.1 所示:
位[7:5] PLS 用于设置PVD 检测的电压阀值,即前面我们介绍PVD 的8 个等级阀值选择。
位4 PVDE 位,用于使能或者禁止PVD 检测,显然我们要使能PVD 检测,该位置1。
这个寄存器还有其它的位我们没有列出来,也是跟电源相关的,如待机,掉电等,我们后
面的实验再讲解这些功能,这里先跳过。
⚫ EXTI 中断屏蔽寄存器(EXTI_IMR)
EXTI 中断屏蔽寄存器描述如图28.2.1.2 所示:
我们要使用到EXTI16 线中断,所以MR16 位要置1,即开放来自EXTI16 线的中断请求。
⚫ EXTI 上升沿触发选择寄存器(EXTI_RTSR)
EXTI 上升沿触发选择寄存器描述如图28.2.1.3 所示:
我们要使用到EXTI16 线中断,所以TR16 位要置1,即允许EXTI16 线的上升沿触发。
⚫ EXTI 下降沿触发选择寄存器(EXTI_FTSR)
EXTI 下降沿触发选择寄存器描述如图28.2.1.4 所示:
我们要使用到EXTI16 线中断,所以TR16 位要置1,即允许EXTI16 线上的下降沿触发。
⚫ EXTI 挂起寄存器(EXTI_PR)
EXTI 挂起寄存器描述如图28.2.1.5 所示:
EXTI 挂起寄存器EXTI_PR 管理的是EXTI0 线到EXTI19 线的中断标志位。在PVD 中断
服务函数里面,我们记得要对PR16 位写1,来清除EXTI16 线的中断标志。
硬件设计
- 例程功能
开发板供电正常的话,LCD 屏会显示"PVD Voltage OK!"。当供电电压过低,则会通过PVD
中断服务函数将LED1 点亮;当供电电压正常后,会在PVD 中断服务函数将LED1 熄灭。LED0
闪烁,提示程序运行。 - 硬件资源
1)LED 灯
LED0 –PB5
LED1 –PE5
2)PVD(可编程电压监测器)
3)正点原子2.8/3.5/4.3/7/10 寸TFTLCD 模块(仅限MCU 屏,16 位8080 并口驱动) - 原理图
PVD 属于STM32F103 的内部资源,只需要软件设置好即可正常工作。我们通过LED0 和
LCD 来指示进入PVD 中断的情况。
睡眠模式实验
本小节我们来学习睡眠模式实验,该部分的知识点内容请回顾28.1.2.3 电源管理。我们直
接从寄存器介绍开始。
28.3.1 EXTI 寄存器
本实验我们用到外部中断来唤醒睡眠模式。进入睡眠模式很简单,直接调用内核指令WFI
(参考28.1.3 电源管理对这个指令的讲解)即可进入。用外部中断唤醒,就要在进入睡眠模式
前,先对外部中断进行配置。例如,使能中断线(EXTI_IMR ),使用何种触发模式
(EXTI_FTSR/EXTI_RTSR)。当中断触发(即EXTI_PR 中某位能查询到1),跳转到中断服务
函数里,最后还得手动清除该标记即(EXTI_PR 中对某位进行置1 处理)。
⚫ EXTI 中断屏蔽寄存器(EXTI_IMR)
EXTI 中断屏蔽寄存器描述如图28.3.1.1 所示:
本实验使用WK_UP(PA0)唤醒,即EXTI0 线中断,所以在外部中断服务函数要把MR0
位置1。
⚫ EXTI 上升沿触发选择寄存器(EXTI_RTSR)
EXTI 上升沿触发选择寄存器描述如图28.3.1.2 所示:
我们要使用到EXTI0 线中断,所以TR0 位要置1,即EXTI0 使用的是上升沿进行触发。
⚫ EXTI 挂起寄存器(EXTI_PR)
EXTI 挂起寄存器描述如图28.3.1.3 所示:
在EXTI0 中断服务函数里面,需要清除EXTI0 中断标记,即对PR0 位写1。
硬件设计
- 例程功能
LED0 闪烁,表明代码正在运行。按下按键KEY0 后,LED1 点亮,提示进入睡眠模式,此
时LED0 不再闪烁,说明已经进入睡眠模式。按下按键WK_UP 后,LED1 熄灭,提示退出睡眠
模式,此时LED0 继续闪烁,说明已经退出睡眠模式。 - 硬件资源
1)LED 灯
LED0 –PB5 LED1 –PE5
2)独立按键
KEY0 –PE4 WK_UP - PA0
3)电源管理(低功耗模式- 睡眠模式)
4)正点原子2.8/3.5/4.3/7/10 寸TFTLCD 模块(仅限MCU 屏,16 位8080 并口驱动) - 原理图
PWR 属于STM32F103 的内部资源,只需要软件设置好即可正常工作。我们通过KEY0 让
CPU 进入睡眠模式,再通过WK_UP 触发EXTI 中断来唤醒CPU。LED0 指示程序是否执行,
LED1 指示CPU 是否进入睡眠模式。
停止模式实验
本小节我们来学习停止模式实验,该部分的知识点内容请回顾28.1.2.3 电源管理。我们直
接从寄存器介绍开始。
PWR 寄存器
本实验我们用到外部中断来唤醒停止模式。我们用到WFI 指令进入停止模式,这个后面会讲,进入停止模式后,使用外部中断唤醒。外部中断部分内容参照睡眠模式即可,都是共用同
样的配置。
下面主要介绍PWR_CR 寄存器相关位。
⚫ PWR 控制寄存器(PWR_CR)
PWR 的控制寄存器描述如图28.4.1.1 所示:
通过PDDS 位选择进入停止模式还是待机模式,停止模式即对PDDS 位置0 即可。在停止
模式下,电压调节器有两种模式:开启或者低功耗,选择低功耗模式,即LPDS 置1。
⚫ 系统控制寄存器(SCB_SCR)
系统控制寄存器描述如图28.4.1.2 所示:
该寄存器存在于ARM 内核中,详细描述可查阅《Cortex-M3 权威指南》,在本实验中,我
们需要把SLEEPDEEP 位置1,这样子后面调用WFI 命令时,进入的就是停止模式了。在唤醒
后,需要清除SLEEPDEEP 位,进行置0。
硬件设计
- 例程功能
LED0 闪烁,表明代码正在运行。按下按键KEY0 后,LED1 点亮,提示进入停止模式,此
时LED0 不再闪烁,说明已经进入停止模式。按下按键WK_UP 后,LED1 熄灭,提示退出停止
模式,此时LED0 继续闪烁,说明已经退出停止模式。 - 硬件资源
1)LED 灯
LED0 –PB5
LED1 –PE5
2)独立按键
KEY0 –PE4
WK_UP - PA0
3)电源管理(低功耗模式–停止模式)
4)正点原子2.8/3.5/4.3/7/10 寸TFTLCD 模块(仅限MCU 屏,16 位8080 并口驱动) - 原理图
PWR 属于STM32F103 的内部资源,只需要软件设置好即可正常工作。我们通过KEY0 让
CPU 进入停止模式,再通过WK_UP 触发EXTI 中断来唤醒CPU。LED0 指示程序是否执行,
LED1 指示CPU 是否进入停止模式。
待机模式实验
本小节我们来学习待机模式实验,该部分的知识点内容请回顾28.1.2.3 电源管理。我们直
接从寄存器介绍开始。
PWR 寄存器
本实验是先对相关的电源控制寄存器配置待机模式的参数,然后通过WFI 指令进入待机模
式,使用WKUP 引脚的上升沿来唤醒(这是特定的唤醒源)。
下面主要介绍本实验用到的寄存器,系统控制寄存器的部分与上一实验一致,就不介绍了
⚫ PWR 控制寄存器(PWR_CR)
PWR 的控制寄存器描述如图28.5.1.1 所示:
这里我们通过设置PDDS 位,使CPU 进入深度睡眠时进入待机模式,同时,我们需要通过
CWUF 位清除之前的唤醒位。
⚫ 电源控制/状态寄存器(PWR_CSR)
电源控制/状态寄存器描述如图28.5.1.2 所示:
该寄存器我们只关心EWUP 位,设置EWUP 为1,即WKUP 引脚作为待机模式的唤醒源。
硬件设计
- 例程功能
LED0 闪烁,表明代码正在运行。按下按键KEY0 后,进入待机模式,待机模式下大部分
引脚处于高阻态,所以说这时候LED0 会熄灭,TFTLCD 也会熄灭。按下WK_UP 按键后,退出待机模式(相当于复位操作),程序重新执行,LED0 继续闪烁,TFTLCD 屏点亮。 - 硬件资源
1)LED 灯
LED0 –PB5
2)独立按键
KEY0 –PE4
WK_UP - PA0
3)电源管理(低功耗模式–待机模式)
4)正点原子2.8/3.5/4.3/7/10 寸TFTLCD 模块(仅限MCU 屏,16 位8080 并口驱动) - 原理图
PWR 属于STM32F103 的内部资源,只需要软件设置好即可正常工作。我们通过KEY0 让
CPU 进入待机模式,再通过WK_UP 上升沿来唤醒CPU。LED0 指示程序是否执行。
ADC 实验
本章,我们将介绍STM32F103 的ADC(Analog-to-digital converters,模数转换器)功能。
我们通过四个实验来学习ADC,分别是单通道ADC 采集实验、单通道ADC 采集(DMA 读取)
实验、多通道ADC 采集(DMA 读取)实验和单通道ADC 过采样(16 位分辨率)实验。
ADC 简介
ADC 即模拟数字转换器,英文详称Analog-to-digital converter,可以将外部的模拟信号转换
为数字信号。
STM32F103 系列芯片拥有3 个ADC(C8T6 只有2 个),这些ADC 可以独立使用,其中
ADC1 和ADC2 还可以组成双重模式(提高采样率)。STM32 的ADC 是12 位逐次逼近型的模
拟数字转换器。它有18 个通道,可测量16 个外部和2 个内部信号源,其中ADC3 根据CPU 引
脚的不同其通道数也不同,一般有8 个外部通道。ADC 中的各个通道的A/D 转换可以单次、
连续、扫描或间断模式执行。ADC 的结果可以以左对齐或者右对齐存储在16 位数据寄存器中。
STM32F103 的ADC 主要特性我们可以总结为以下几条:
1、12 位分辨率;
2、转换结束、注入转换结束和发生模拟看门狗事件时产生中断
3、单次和连续转换模式
4、自校准
5、带内嵌数据一致性的数据对齐
6、采样间隔可以按通道分别编程
7、规则转换和注入转换均有外部触发选项
8、间断模式
9、双重模式(带2 个或以上ADC 的器件)
10、ADC 转换时间:时钟为72MHz 为1.17us
11、ADC 供电要求:2.4V 到3.6V
12、ADC 输入范围:VREF–≤VIN≤VREF+
13、规则通道转换期间有DMA 请求产生
下面来介绍ADC 的框图:
图中,我们按照ADC 的配置流程标记了七处位置,分别如下:
①输入电压
在前面ADC 的主要特性也对输入电压有所提及,ADC 输入范围VREF–≤VIN≤VREF+,最终
还是由VREF–、VREF+、VDDA和VSSA决定的。下面看一下这几个参数的关系,如图30.1.2 所示:
从上图可以知道,VDDA和VREF+接VCC3.3,而VSSA和VREF-是接地,所以ADC 的输入范
围即0~3.3V。
②输入通道
在确定好了ADC 输入电压后,如何把外部输入的电压输送到ADC 转换器中呢,在这里引
入了ADC 的输入通道,在前面也提及到了ADC1 和ADC2 都有16 个外部通道和2 个内部通
道;而ADC3 就有8 个外部通道。外部通道对应的是上图中的ADCx_IN0、ADCx_IN1…
ADCx_IN15。ADC1 的通道16 就是内部通道,连接到芯片内部的温度传感器,通道17 连接到
Vrefint。而ADC2 的通道16 和17 连接到内部的VSS。ADC3 的通道9、14、15、16 和17 连接
到的是内部的VSS。具体的ADC 通道表见表30.1.1 所示:
③转换顺序
当ADC 的多个通道以任意顺序进行转换就诞生了成组转换,这里有两种成组转换类型:
规则组和注入组。规则组就是图中的规则通道,注入组就是图中的注入通道。为了避免大家对
输入通道,以及规则通道和注入通道的理解混淆,后面规则通道以规则组来代称,注入通道以
注入组来代称。
规则组最多允许16 个输入通道进行转换,而注入组最多允许4 个输入通道进行转换。这里
讲解一下规则组和注入组。
规则组(规则通道)
规则组,按字面理解,“规则”就是按照一定的顺序,相当于正常运行的程序,平常用到最
多也是规则组。
注入组(注入通道)
注入组,按字面理解,“注入”就是打破原来的状态,相当于中断。当程序执行的时候,中
断是可以打断程序的执行。同这个类似,注入组转换可以打断规则组的转换。假如在规则组转
换过程中,注入组启动,那么注入组被转换完成之后,规则组才得以继续转换。
为了便于理解,下面看一下规则组和注入组的执行优先级对比图,如图30.1.3 所示:
了解了规则组和注入组的概念后,下面来看看它们的转换顺序,即转换序列。转换序列可
以分为规则序列和注入序列。下面分别来介绍它们。
规则序列
规则组最多允许16 个输入通道进行转换,那么就需要设置通道转换的顺序,即规则序列。
规则序列寄存器有3 个,分别为SQR1、SQR2 和SQR3。SQR3 控制规则序列中的第1 个到第
6 个转换;SQR2 控制规则序列中第7 个到第12 个转换;SQR1 控制规则序列中第13 个到第16
个转换。规则序列寄存器控制关系汇总如表30.1.2 所示:
从上表可以知道,当我们想设置ADC 的某个输入通道在规则序列的第1 个转换,只需要
把相应的输入通道号的值写入SQR3 寄存器中的SQ1[4:0]位即可。例如想让输入通道5 先进行转换,那么就可以把5 这个数值写入SQ1[4:0]位。如果还想让输入通道8 在第2 个转换,那么
就可以把8 这个数值写入SQ2[4:0]位。最后还要设置你的这个规则序列的输入通道个数,只需
把输入通道个数写入SQR1 的SQL[3:0]位。注意:写入0 到SQL[3:0]位,表示这个规则序列有
1 个输入通道的意思,而不是0 个输入通道。
注入序列
注入序列,跟规则序列差不多,决定的是注入组的顺序。注入组最大允许4 个通道输入,
它的注入序列由JSQR 寄存器配置。注入序列寄存器JSQR 控制关系如表30.1.3 所示:
注入序列有多少个输入通道,只需要把输入通道个数写入到JL [ 1 : 0 ]位,范围是0~3。注
意:写入0 表示这个注入序列有一个输入通道,而不是0 个输入通道。这个内容很简单。编程
时容易犯错的是注入序列的转换顺序问题,下面给大家讲解一下。
如果JL[ 1 : 0 ]位的值小于3,即设置注入序列要转换的通道个数小于4,则注入序列的转
换顺序是从JSQx[ 4 : 0 ](x=4-JL[1:0])开始。例如:JL [ 1 : 0 ]=10、JSQ4 [ 4 : 0 ]= 00100、JSQ3 [ 4 : 0 ]= 00011、JSQ2 [ 4 : 0 ]= 00111、JSQ1 [ 4 : 0 ]= 00010,意味着这个注入序列的转换顺序
是:7、3、4,而不是2、7、3。如果JL[ 1 : 0 ]=00,那么转换顺序是从JSQ4 [ 4 : 0 ]开始。
④触发源
在配置好输入通道以及转换顺序后,就可以进行触发转换了。ADC 的触发转换有两种方法:
分别是通过ADON 位或外部事件触发转换。
(1)ADON 位触发转换
当ADC_CR2 寄存器的ADON 位为1 时,再独立给ADON 位写1(其它位不能一起改变,
这是为了防止误触发),这时会启动转换。这种控制ADC 启动转换的方式非常简单。
(2)外部触发转换
另一种方法是通过外部事件触发转换,例如定时器捕获、EXTI 线和软件触发,可以分为规
则组外部触发和注入组外部触发。
规则组外部触发使用方法是将EXTTRIG 位置1,并且通过EXTSET[2:0]位选择规则组启动
转换的触发源。如果EXTSET[2:0]位设置为111,那么可以通过SWSTART 为启动ADC 转换,
相当于软件触发。
注入组外部触发使用方法是将JEXTTRIG 位置1,并且通过JEXTSET[2:0]位选择注入组启
动转换的触发源。如果JEXTSET[2:0]位设置为111,那么可以通过JSWSTART 为启动ADC 转
换,相当于软件触发。
ADC1 和ADC2 的触发源是一样的,ADC3 的触发源和ADC1/2 有所不同,这个需要注意。
⑤转换时间
(1)ADC 时钟
在学习转换时间之前,我们先来了解ADC 时钟。从标号⑤框出来部分可以看到ADC 时钟是
要经过ADC 预分频器的,那么ADC 的时钟源是什么?ADC 预分频器的分频系数可以设置的
范围又是多少?以及ADC 时钟频率的最大值又是多少?下面将为大家解答。
ADC 的输入时钟是由PCLK2 经过分频产生的,分频系数是由RCC_CFGR 寄存器的
ADCPRE[1:0]位设置的,可选择2/4/8/16 分频。需要注意的是,ADC 的输入时钟频率最大值是
14MHz,如果超过这个值将会导致ADC 的转换结果准确度下降。
一般我们设置PCLK2 为72MHz。为了不超过ADC 的最大输入时钟频率14MHz,我们设
置ADC 的预分频器分频系数为6,就可以得到ADC 的输入时钟频率为72MHz/6,即12MHz。
例程中,我们也是如此设置的。
(2)转换时间
STM32F103 的ADC 总转换时间的计算公式如下:
⑥数据寄存器
ADC 转换完成后的数据输出寄存器。根据转换组的不同,规则组的完成转换的数据输出到
ADC_DR 寄存器,注入组的完成转换的数据输出到ADC_JDRx 寄存器。假如是使用双重模式,
规则组的数据也是存放在ADC_DR 寄存器。下面给大家简单介绍一下这两个寄存器。
(1)ADC 规则数据寄存器(ADC_DR)
ADC 规则组数据寄存器ADC_DR 是一个32 位的寄存器,独立模式时只使用到该寄存器低
16 位保存ADC1/2/3 的规则转换数据。在双ADC 模式下,高16 位用于保存ADC2 转换的数
据,低16 位用于保存ADC1 转换的数据。
因为ADC 的精度是12 位的,ADC_DR 寄存器无论高16 位还是低16,存放数据的位宽都
是16 位的,所以允许选择数据对齐方式。由ADC_CR2 寄存器的ALIGN 位设置数据对齐方式,
可选择:右对齐或者左对齐。
细心的朋友可能发现,规则组最多有16 个输入通道,而ADC 规则数据寄存器只有一个,
如果一个规则组用到好几个通道,数据怎么读取?如果使用多通道转换,那么这些通道的数据
也会存放在DR 里面,按照规则组的顺序,上一个通道转换的数据,会被下一个通道转换的数
据覆盖掉,所以当通道转换完成后要及时把数据取走。比较常用的方法是使用DMA 模式。当
规则组的通道转换结束时,就会产生DMA 请求,这样就可以及时把转换的数据搬运到用户指
定的目的地址存放。注意:只有ADC1 和ADC3 可以产生DAM 请求,而由ADC2 转换的数据
可以通过双ADC 模式,利用ADC1 的DMA 功能传输。
(2)ADC 注入数据寄存器x(ADC_JDRx)(x=1~4)
ADC 注入数据寄存器有4 个,注入组最多有4 个输入通道,刚好每个通道都有自己对应的
数据寄存器。ADC_JDRx 寄存器是32 位的,低16 位有效,高16 位保留,数据也同样需要选
择对齐方式。也是由ADC_CR2 寄存器的ALIGN 位设置数据对齐方式,可选择:右对齐或者左
对齐。
⑦中断
ADC 中断可分为三种:规则组转换结束中断、注入组转换结束中断、设置了模拟看门狗状
态位中断。它们都有独立的中断使能位,分别由ADC_CR 寄存器的EOCIE、JEOCIE、AWDIE
位设置,对应的标志位分别是EOC、JEOC、AWD。
模拟看门狗中断
模拟看门狗中断发生条件:首先通过ADC_LTR 和ADC_HTR 寄存器设置低阈值和高阈值,
然后开启了模拟看门狗中断后,当被ADC 转换的模拟电压低于低阈值或者高于高阈值时,就
会产生中断。例如我们设置高阈值是3.0V,那么模拟电压超过3.0V 的时候,就会产生模拟看
门狗中断,低阈值的情况类似。
DMA 请求
规则组和注入组的转换结束后,除了可以产生中断外,还可以产生DMA 请求,我们利用
DMA 及时把转换好的数据传输到指定的内存里,防止数据被覆盖。
注意:只有ADC1 和ADC3 可以产生DAM 请求,DMA 相关的知识请回顾DMA 实验。
⑧单次转换模式和连续转换模式
单次转换模式和连续转换模式在框图中是没有标号,为了更好地学习后续的内容,这里简
单给大家讲讲。
(1)单次转换模式
通过将ADC_CR2 寄存器的CONT 位置0 选择单次转换模式。该模式下,ADC 只执行一
次转换,由ADC_CR2 寄存器的ADON 位启动(只适用于规则组),也可以通过外部触发启动
(适用于规则组或注入组)。
如果规则组的一个输入通道被转换,那么转换的数据被储存在16 位ADC_DR 寄存器中、
EOC(转换结束)标志位被置1、如果设置了EOCIE 位,则产生中断,然后ADC 停止。
如果注入组的一个输入通道被转换,那么转换的数据被储存在16 位ADC_DRJx 寄存器中、
JEOC(转换结束)标志位被置1、如果设置了JEOCIE 位,则产生中断,然后ADC 停止。
(2)连续转换模式
通过将ADC_CR2 寄存器的CONT 位置1 选择连续转换模式。该模式下,ADC 完成上一
个通道的转换后会马上自动地启动下一个通道的转换,由ADC_CR2 寄存器的ADON 位启动,
也可以通过外部触发启动。
如果规则组的一个输入通道被转换,那么转换的数据被储存在16 位ADC_DR 寄存器中、
EOC(转换结束)标志位被置1、如果设置了EOCIE 位,则产生中断。
如果注入组的一个输入通道被转换,那么转换的数据被储存在16 位ADC_DRJx 寄存器中、
JEOC(转换结束)标志位被置1、如果设置了JEOCIE 位,则产生中断。
⑨扫描模式
扫描模式在框图中是没有标号,为了更好地学习后续的内容,这里简单给大家讲讲。
可以通过ADC_CR1 寄存器的SCAN 位配置是否使用扫描模式。如果选择扫描模式,ADC
会扫描所有被ADC_SQRx 寄存器或ADC_JSQR 选中的所有通道,并对规则组或者注入组的每
个通道执行单次转换,然后停止转换。但如果还设置了CONT 位,即选择连续转换模式,那么
转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。
如果设置了DMA 位,在每次EOC 后,DMA 控制器把规则组通道的转换数据传输到SRAM
中。而注入通道转换的数据总是存储在ADC_JDRx 寄存器中。
到这里,我们基本上介绍了ADC 的大多数基础的知识点,其它知识后面用到会继续补充,
如果还有不懂的内容,请参考《STM32F10xxx 参考手册_V10(中文版).pdf》的第11 章。
单通道ADC 采集实验
本实验我们来学习单通道ADC 采集实验。本实验使用规则组单通道的单次转换模式,并
且通过软件触发,即由ADC_CR2 寄存器的SWSTART 位启动。下面先带大家来了解本实验要
配置的寄存器。
ADC 寄存器
这里,我们只介绍本实验用到的寄存器的关键位,其它寄存器后续用到会继续介绍。
⚫ ADC 控制寄存器1(ADC_CR1)
ADC 控制寄存器1 描述如图30.2.1.1 所示:
SCAN 位用于选择是否使用扫描模式。本实验我们使用单通道采集,所以没必要选择扫描
模式,该位置0 即可。
DUALMOD[3:0]位用来设置ADC 的操作模式,我们的例程中ADC 相关的实验都是使用独
立模式,所以设置为0000 即可。
⚫ ADC 控制寄存器2(ADC_CR2)
ADC 控制寄存器2 描述如图30.2.1.2 所示:
该寄存器我们针对性的介绍一些位:ADON 位用于打开或关闭AD 转换器,还可以用于触
发ADC 转换。CONT 位用于设置单次转换模式还是连续转换模式,本实验我们使用单次转换
模式,所以CONT 位置0 即可。CAL 位用于开启AD 校准。RSTCAL 位用于判断校准寄存器是
否已初始化。ALIGN 用于设置数据对齐,我们使用右对齐,所以该位置0。EXTSEL[2:0]位用
于选择规则组启动转换的外部事件触发源,本实验使用的是软件触发(SWSTART),所以这三
个位置为111。EXTTRIG 位必须置1,EXTSEL[2:0]位才能选择软件触发(SWSTART),别漏了
这步,否则设置软件触发会不成功。SWSTART 位用于启动一次规则组通道的转换,即软件触发转换。
⚫ ADC 采样事件寄存器1(ADC_SMPR1)
ADC 采样事件寄存器1 描述如图30.2.1.3 所示:
⚫ ADC 采样事件寄存器2(ADC_SMPR2)
ADC 采样事件寄存器2 描述如图30.2.1.4 所示:
ADC 采样时间设置需要由两个寄存器设置,ADC_SMPR1 和ADC_SMPR1,分别设置通道
10~17 和通道0~9 的采样时间,每个通道用3 个位设置。可以看出ADC 的每个通道的采样时间
是支持单独设置的。
一般每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降
低ADC 的转换速率,看大家怎么衡量选择了。本实验中,我们设置采样时间是239.5 个周期。
结合前面介绍过的转换时间公式:
⚫ ADC 规则序列寄存器1
ADC 规则序列寄存器共有3 个,这几个寄存器的功能都差不多,这里我们仅介绍一下ADC
规则序列寄存器1(ADC_SQR1),描述如图30.2.1.5 所示:
L[3:0]用于设置规则组序列的长度,取值范围:015,表示规则组的长度是116。本实验
只用了1 个输入通道,所以L[3:0]位设置为0000 即可。
SQ13[4:0]SQ16[4:0]位设置规则组序列的第1316 个转换编号,第1~12 个转换编号的设
置请查看ADC_SQR2 和ADC_SQR3 寄存器。设置过程非常简单,忘记了请参考前面给大家整
理出来的规则序列寄存器控制关系汇总表。
本实验我们使用单通道,ADC1 通道14,所以规则组序列里只有一个输入通道,我们将
ADC_SQR3 寄存器的SQ1[4:0]位的值设置为14 即可。
⚫ ADC 规则数据寄存器(ADC_DR)
ADC 规则数据寄存器描述如图30.2.1.6 所示:
在规则序列中AD 转换结果都将被存在这个寄存器里面,而注入通道的转换结果被保存在
ADC_JDRx 里面。该寄存器的数据可以通过ADC_CR2 的ALIGN 位设置左对齐还是右对齐。
在读取数据的时候要注意。
⚫ ADC 状态寄存器(ADC_SR)
ADC 状态寄存器描述如图30.2.1.7 所示:
该寄存器保存了ADC 转换时的各种状态。本实验我们通过EOC 位的状态来判断ADC 转
换是否完成,如果查询到EOC 位被硬件置1,就可以从ADC_DR 寄存器中读取转换结果,否
则需要等待转换完成。
至此,本实验要用到的ADC 关键寄存器全部介绍完了,对于未介绍的部分,请大家参考
《STM32F10xxx 参考手册_V10(中文版).pdf》第11 章相关内容。
30.2.2 硬件设计
- 例程功能
采集ADC1 通道1(PA1)上面的电压,并在LCD 模块上面显示ADC 规则数据寄存器12
位的转换值以及将该值换算成电压后的电压值。使用杜邦线将ADC 和RV1 排针连接,使得PA1
连接到电位器上,然后将ADC 采集到的数据和转换后的电压值在TFTLCD 屏中显示。用户可
以通过调节电位器的旋钮改变电压值。LED0 闪烁,提示程序运行。 - 硬件资源
1)LED 灯
LED0 – PB5
2)串口1(PA9/PA10 连接在板载USB 转串口芯片CH340 上面)
3)正点原子2.8/3.5/4.3/7/10 寸TFTLCD 模块(仅限MCU 屏,16 位8080 并口驱动)
4)ADC1 :
通道1 –PA1