专栏
系统时钟和低功耗模式
MSP432单片机各部件能在有条不紊地自动工作,实际上是在其系统时钟作用下,由CPU指挥芯片内各个部件自动协调工作,使内部逻辑硬件产生各种操作所需要的脉冲信号而实现的。MSP432单片机通过软件控制时钟系统可以使其工作在多种模式,包括6种活动模式和5种低功耗模式,通过这些工作模式,可合理地利用单片机内部资源,从而实现低功耗。时钟系统是MSP432单片机中非常关键的部件,通过时钟系统可以在功耗和性能之间寻求最佳的平衡点,为单芯片系统的超低功耗设计提供了灵活的实现手段。
时钟系统结构与原理
1.时钟系统结构
(1)7个时钟来源
时钟系统模块具有7个时钟来源。
①LFXTCLK:低频振荡器,可以使用32768Hz的手表晶振、标准晶体、谐振器或低于32kHz的外部时钟源;
②VLOCLK:内部超低功耗低频振荡器,典型频率9.4kHz;
③REFOCLK:内部低功率低频振荡器,典型频率为32768Hz或128kHz;
④DCOCLK:内部数字时钟振荡器,频率可选,默认频率为3MHz;
⑤MODCLK:内部低功耗振荡器,典型频率25MHz;
⑥HFXTCLK:高频振荡器,可以是标准晶振、谐振器或1MHz~48MHz的外部时钟源,在旁路模式下,HFXTCLK还可以通过外部方波信号驱动;
⑦SYSOSC:内部振荡器,典型频率5MHz。
(2)5个时钟信号
时钟系统模块可以产生五个时钟信号供CPU和外设使用:
①ACLK:辅助时钟(Auxiliary clock)。可以通过软件选择LFXTCLK、VLOCLK、REFOCLK。ACLK可以进行1/2/4/8/16/32/64/128分频,频率最高可达128kHz,主要用于低频外设;
②MCLK:主时钟(Master clock)。可以通过软件选择LFXTCLK、VLOCLK、REFOCLK、DCOCLK、MODCLK、HFXTCLK。MCLK可以进行1/2/4/8/16/32/64/128分频,用于CPU和外围模块;
③HSMCLK:子系统时钟(Subsystem master clock)。HSMCLK的时钟来源与MCLK相同,HSMCLK主要用于高速外设,HSMCLK也可以进行1/2/4/8/16/32/64/128分频;
④SMCLK:低速子系统时钟(Low-speed subsystem master clock)。SMCLK的时钟来源与MCLK相同,SMCLK的最大频率为HSMCLK最大频率的一半,用于外围模块,SMCLK也可以进行1/2/4/8/16/32/64/128分频;
⑤BCLK:低速备份时钟(Low-speed backup domain clock)。可以通过软件选择LFXTCLK和REFOCLK。当外围设备在低功耗模式时,可使用BCLK,最高频率为32kHz。
时钟系统模块的时钟源和时钟信号间的关系如表5-1所示,表中的“√”为可选配置。例如,可以用DCO来驱动MCLK,也可用MDOSC来驱动MCLK,以此类推。
(3)MSP432P401x单片机的时钟系统结构图
①对于紧靠在一起的多个同名控制位,以总线的形式表示这些控制位的组合。例如结构框图中右上角的DIVA控制位,虽然只有一个黑点,但是,其下面的连线上标着“\3”,说明这是3位总线,共有8种组合(000、001、010、011、100、101、110、111),前六种组合分别代表对ACLK进行1、2、4、8、16、32、64、128分频后输出
②梯形图表示多路选择器,它负责从多个输入通道中选择一个作为输出,具体由与其连接的控制位决定。例如,SELA控制位所连接的梯形图,其主要功能为选择一个时钟源作为ACLK模块的参考时钟。
2.时钟系统的原理
系统复位后,进入活动模式0(AM0_LDO)。在活动模式0下,系统时钟默认配置为:
- 设备有LFXT晶振可用时:
- –LFXT晶振被选中为LFXTCLK时钟源;
- –ACLK选择LFXTCLK(SELAx = 0),ACLK不可分频(DIVAx = 0);
- –BCLK选择LFXTCLK(SELBx = 0);
- –LFXT保持禁用,LFXT晶体引脚与通用I/O复用。
- 设备没有LFXT晶振可用时:
- –ACLK选择REFOCLK(SELAx = 0或2),ACLK不可分频(DIVAx = 0);
- –BCLK选择REFOCLK(SELBx = 1);
- –REFOCLK可被启用。
- 设备有HFXT晶振可用时:
- –HFXIN和HFXOUT引脚被设置为通用I/O。
- DCOCLK被MCLK、HSMCLK和SMCLK选择时(SELMx = SELSx = 3),所有时钟都不可分频(DIVMx = DIVSx = DIVHSx = 0)。
时钟系统模块可以在程序执行期间的任何时间进行配置或重新配置。
(1)内部超低功耗低频振荡器(VLO)
内部超低功耗低频振荡器在无需外部晶振的情况下,可提供10kHz的典型频率。当不需要精确的时钟基准时,VLO可提供一个低成本、超低功耗的时钟源。为实现低功耗,在不需要的情况下,VLO可以关闭,只在需要时启用。
VLO在以下情况下将被启用:
- 在所有活动模式和低功耗模式0(LPM0)下:
- –VLO_EN = 1;
- –VLO为ACLK参考时钟源(SELAx = 1);
- –VLO为MCLK参考时钟源(SELMx = 1);
- –VLO为HSMCLK参考时钟源(SELSx = 1);
- VLO为SMCLK参考时钟源(SELSx = 1);
- 在LPM3和LPM3.5下:
- –VLO_EN = 1。
- 在LPM4.5下:
- –VLO关闭,VLO_EN无效。
MSP430 & 432 低功耗模式
SYSTICK定时中断
- SYSTICK-系统滴答定时器
- 系统滴答定时器,在操作系统中是十分重要的,它可以提供一个好的系统时钟节拍,就和我们的心脏一样,跳动着一定的频率。
- 它则为系统的运行提供了一个好的时间基准。
我们来看官方手册2.2.1的内容
2.2.1 System Timer (SysTick)
Cortex-M4 includes an integrated system timer, SysTick, which provides a simple 24-bit clear-on-write
decrementing wrap-on-zero counter with a flexible control mechanism. The counter can be used in severaldifferent ways, for example:
-
An RTOS tick timer that fires at a programmable rate (for example,100 Hz) and invokes a SysTickroutine.
-
A high-speed alarm timer using the system clock.
-
A variable rate alarm or signal timer—-the duration is range-dependent on the reference clock used andthe dynamic range of the counter.
-
A simple counter used to measure time to completion and time used.
-
An internal clock source control based on missing/meeting durations.The COUNT bit in the STCSR control and status register can be used to determine if an action completed within a set duration, as
SYSTICK相关寄存器
- STCSR 控制及状态寄存器
- STRVR 重装载数值寄存器
- STCVR 当前数值寄存器
- STCR 校准数值寄存器
只用到了0(ENABLE)、1(TICKINT)、2(CLKSOURCE)和16位(COUNTFLAG)。
-
16(COUNTFLAG):如果在上次读取本寄存器后,SYSTICK已经数到了0,则该位为1,如果读取该位,该位将自动清零。如果通过DAP仿真器进行调试,你可以通过AHP-AP Control Register控制寄存器进行置0,否则其他状态下,这个位不会被改变。
-
2(CLKSOURCE):0=外部时钟源(STCLK);1=内核时钟(FCLK)。
-
1(TICKINT):1=SYSTICK倒数到0时产生SYSTICK异常请求;0=数到0时无动作。
-
0(ENABLE):SYSTICK定时器的使能位。
-
23:0(RELOAD):当倒数至零时,将被重装载的值。
- 23:0(CURRENT):读取时返回当前倒计数的值,写它则使之清零,同时还会清楚在SYSTICK控制及状态寄存器中的COUNTFLAG标志。
- 31(NOREF):1=没有外部参考时钟(STCLK不可用);0=外部参考时钟可用。
- 30(SKEW):1=校准值不是准确的 10ms;0=校准值是准确的 10ms
- 23:0(TENMS):10ms的时间内倒计数的格数。
SYSTICK配置步骤
- 我们第一步是需要配置STCVR这个寄存器,第一步要给出重装载的值,是24位数据,那么我们就可以计算出我们对应的最大的延时数。
- 接下来我们需要配置我们的STCVR这个寄存器,这个寄存器对应我们的SYSTICK->VAL,是我们当前寄存器的值,我们需要把它清零。
- 最后就是控制状态寄存器了,需要使能SYSTICK这个模块,同时把时钟源控制位置一。
SYSTICK sdk相关
关于SYSTICK的例程
导入
在CCS中导入所安装的SDK的目录下
C:\ti\simplelink_msp432p4_sdk_3_40_01_02\examples\nortos\MSP_EXP432P401R\driverlib\systick_interrupt_gpio_blink\ccs 的工程文件
导入后打开systick_interrupt_gpio_blink.c文件进行分析:
点击一个函数,右键->Open Declaration:
可以看到函数和手册里的内容不一致,带有ROM或MAP前缀:
这是因为在MSP432P4系列芯片中,提供ROM库和SDK库,把驱动库固定在了ROM存储器里面。
对于MSP432芯片,你可以使用固化在ROM里面的驱动库,也可以选择外部SDK库的驱动库。
使用ROM库的好处是速度快、安全,缺点是版本固定不能更新。
例程
利用定时器中断实现一秒闪烁一次LED灯
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
//主函数
int main(void)
{
/* Halting the Watchdog */
MAP_WDT_A_holdTimer();//暂停开门狗
/* Configuring GPIO as an output */
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);//将引脚P1^0设置为输出引脚
/* Configuring SysTick to trigger at 1500000 (MCLK is 1.5MHz so this will
* make it toggle every 1s) */
MAP_SysTick_enableModule();//使能系统滴答定时器模块
MAP_SysTick_setPeriod(1500000);//设置装载初值,1秒
MAP_Interrupt_enableSleepOnIsrExit();//使能退出时进入中断睡眠模式
MAP_SysTick_enableInterrupt();//使能系统滴答定时器中断
/* Enabling MASTER interrupts */
MAP_Interrupt_enableMaster();//使能总中断
while (1)
{
MAP_PCM_gotoLPM0();//在中断等待阶段,进入LPM0状态
}
}
//中断服务子程序
void SysTick_Handler(void)
{
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
}
分析
下载例程后,我们可以发现一个问题,LED闪烁得很快。并没有按1秒来闪烁。
接下来我们打开system_msp432p401r.c文件进行分析
可以发现系统时钟SYSTEM_CLOCK的值是3MHz,而不是例程所说的1.5HHz,所以LED闪烁得很快,这里将系统时钟的值改为1.5MHz或者重新设定初值为3000000,就得达到一秒闪烁一次LED灯的效果。
打开工程文档ccs下的startup_msp432p401r_ccs.c启动文件
可以看到各种中断函数的向量表,采用的是弱定义。弱定义的意思是如果未注册新的中断函数,就默认使用启动文件当中定义好的中断函数;如果有新注册的中断函数,就使用该新的中断函数,就如该例程中,我们新注册了SysTick_Handler中断函数,重写了中断服务子程序。