- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
在上一篇文章中 STM8单片机低功耗—活跃停机(Active Halt)模式实现-1 没有使用活跃停机(Active Halt)
模式的定时唤醒功能,使用的是外部中断唤醒,这篇文章来演示一下如何使用活跃停机(Active Halt)
的定时自动唤醒功能。
这个活跃停机(Active Halt)
的定时自动唤醒功能中的定时时间指的就是:从单片机进入低功耗模式之后到下一次系统自动唤醒的时间间隔。比如将自动定时的时长设置为1s,当使用HALT命令让单片机进入低功耗模式之后,单片机内部的定时器开始计时,时间到了1s之后,单片机就会自动从低功耗模式中唤醒,如果要再次进入低功耗需要继续执行一次HALT命令。
要使用自动唤醒功能前必须先设置自动唤醒的时间,设置时间需要通过两个寄存器来设置 异步预分频寄存器 (AWU_APR) 和 时基选择寄存器 (AWU_TBR).。
异步预分频寄存器 (AWU_APR)设置对128KHz的内部低速时钟振荡器的分频系数,最小分频值为2,最大分频值为64。
时基选择寄存器 (AWU_TBR)用来设置自动唤醒的时间间隔,它的值从0 到 15,当设置为0时,表示不使用自动唤醒功能。所以唤醒时间的有效值范围从1 到 15 。它的自动唤醒时间范围如下:
最小唤醒时间 0.01ms左右,最大唤醒时间 30.72s,这个唤醒时间是由 异步预分频寄存器 (AWU_APR) 和 *时基选择寄存器 (AWU_TBR)*这两个寄存器的值共同决定的。
具体计算公式如下:
这个0001到1111的值是由时基选择寄存器 (AWU_TBR)的值,这个值不同那么时间的计算公式也不同。每个数字后面跟着的就是相应的计算公式。 APRdiv 这个值是 异步预分频寄存器 (AWU_APR)设置的分频值,fls这个是是内部低速振荡器时钟频率,这里是128Khz的固定值。
根据这个公式就可以计算出自动唤醒的时间了,比如需要设置自动唤醒时间为5s左右,根据上面的时间表格可以看出,自动唤醒时间在5s左右时。时基选择寄存器 (AWU_TBR)中AWUTB[3:0]的值可以是1110或者1111。当值设置为1110时,异步预分频寄存器 (AWU_APR)中APR[5:0]值的设置范围是26到64,当分频值设置为26时,自动唤醒时间就是2.08s,当分频值设置为64时,自动唤醒时间就是5.12s。同样当时基寄存器的值设置为1111时,分频器的值范围为11到64,此时自动唤醒的时间范围就是5.28s到30.72s。
这样时间设置为5s左右,那么尽量是靠近5s。所以这里就设置时基寄存器的值为1110,换算为16进制计算0x0E,设置分频器值为64,这里要注意一点64的十六进制值是0x40,但是给寄存器里面写入的时候需要写入0x3E。需要给16进制值减去2,这是因为分频值是从2开始的,而不是从0开始的。
然后根据时间计算公式计算延时时间。时基值为1110,那么计算公式如下:
APRdiv的值为64,fls的值为128k。 5 * 2^11 * 64 / 128000 = 5.12s,通过公式计算出来的值和上面表格中的值是相符的。
下面就可以开始编写程序了。首先初始化需要用到的外设。
#define LED PB_ODR_ODR5
void LED_GPIO_Init( void )
{
PB_DDR |= ( 1 << 5 ); // 输出 led
PB_CR1 |= ( 1 << 5 ); // 推挽输出
}
//初始化PD2口
void EXTI_GPIO_Init( void )
{
PD_DDR &= ( ~( 1 << 2 ) ); //输入
PD_CR1 &= ( ~( 1 << 2 ) ); //浮空输入
PD_CR2 |= ( 1 << 2 ); //打开外部中断
}
//PD2口为中断输入 低电平触发
void EXTI_Init( void )
{
EXTI_GPIO_Init();
EXTI_CR1 &= ~( 3 << 6 ); //6 7 位清零
EXTI_CR1 |= ( 1 << 6 ); //PD上升沿触发
}
//端口D外部中断 中断号6
#pragma vector = 8 // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void EXTI_PORTC_Handle( void )
{
//外部中断会将单片机从 停机模式唤醒
}
初始化LED口和外部中断。LED灯用来指示单片机运行状态,正常模式下LED灯闪烁,当进入低功耗之后,LED灯停止闪烁。外部中断用于将单片机从低功耗唤醒。
接下来初始化AWU
void AWU_init()
{
CLK_ICKR |= 0x2C; // 活跃停机模式下主电压调节器处于关 打开低速振荡器(128K) 从停机或者活跃停机模式唤醒使能
FLASH_CR1 |= 0x04; // 当MCU在Active-halt 模式时FLASH处于掉电模式
AWU_APR = 0x3E; //设置异步预分频器值 64分频
AWU_TBR = 0x0E; //自动唤醒中断时间 5*2^11*64/128000=5.12s
AWU_CSR1 = 0x30; //使能自动唤醒中断 使能自动唤醒功能
}
#pragma vector = 3 // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void AWU_HALT_Handler( void )
{
AWU_CSR1 = AWU_CSR1; // 通过读AWU_CSR 清除更新中断标志位
}
在AWU中首先设置当系统设置系统进入活跃停机模式时,打开内部低速振荡器。然后设置系统进入活跃停机模式时,FLASH就进入掉电模式。这样可以进一步的降低系统功耗。接下里设置 异步预分频寄存器 (AWU_APR) 和 *时基选择寄存器 (AWU_TBR)*的值,将自动唤醒时间设置为5s左右。最后使能自动唤醒中断功能,在中断中需要清除自动唤醒中断标志,通过读寄存器的值就可以清除自动唤醒标志。如果不清除自动唤醒标志,那么系统只能被唤醒一次,以后就永远进入活跃停机模式,不会自动唤醒了。除非有外部中断信号或者复位信号,系统才会被唤醒。
最后编写主函数
void SysClkInit( void )
{
CLK_SWR = 0xe1; //HSI为主时钟源 16MHz CPU时钟频率
CLK_CKDIVR = 0x00; //CPU时钟0分频,系统时钟0分频
}
void main( void )
{
unsigned int cnt = 0;
__asm( "sim" ); //禁止中断
SysClkInit();
delay_init( 16 );
LED_GPIO_Init();
EXTI_Init();
__asm( "rim" ); //开启中断
AWU_init(); //使能AWU
__asm( "halt" ); //进入 活跃停机(Active Halt)模式 5s 后自动唤醒
while( 1 ) //进入低功耗之前,电流5.5mA
{
LED = !LED;
delay_ms( 500 );
cnt++;
if( cnt > 10 ) //进入低功耗之后,电流160uA
{
cnt = 0; //中断和复位也能随时唤醒
__asm( "halt" ); //再次进入 活跃停机(Active Halt)模式 5S后自动唤醒
}
}
}
首先初始化系统需要用到的外设,然后初始化AWU,这时使用HALt命令,单片机就会进入活跃停机模式,5s之后系统被自动唤醒,然后进入 while循环中,此时LED灯开始闪烁,5s之后再次使用HALT命令让单片机进入活跃停机模式,此时LED灯不再闪烁,5s之后单片机自动被唤醒,LED灯继续闪烁。这样一直循环下去,LED灯就会闪烁5s,停5s,这样一直循环。
当LED灯闪烁时,说明单片机处于正常工作模式,此时用万用表测量单片机的电流为5.5mA,当LED灯停止闪烁时,说明单片机进入到了活跃停机模式中,此时用万用表测量单片机的电流为160uA。
完整工程连接下载地址: STM8单片机低功耗 活跃停机Active Halt模式实现
具体的软硬件实现点击 http://mcu-ai.com/ MCU-AI技术网页_MCU-AI人工智能 卷积神经网络(CNN)通过从原始数据中自动学习层次特征表示,在图像识别任务中取得了巨大成功。虽然
具体的软硬件实现点击 http://mcu-ai.com/ MCU-AI技术网页_MCU-AI人工智能 血压的测量和预测是心脏病患者和有心脏问题的人的一个重要条件,应该保持持续的控制。在这项研究中,基
具体的软硬件实现点击 http://mcu-ai.com/ MCU-AI技术网页_MCU-AI人工智能 心血管疾病是最严重的死亡原因之一,每年在全世界造成严重的生命损失。持续监测血压似乎是最可行的选择
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是 恩智浦MCX系列MCU的新品MCXN947 。 自 2015 年恩智浦和飞思卡尔合并成新恩智浦之后,关于它们各
我正在开发一个应用程序,该应用程序接受语音输入,并将该输入与 list 中的已知项目进行匹配。 list 中的每个项目都有一个别名列表,以便长标题的项目可以与较短的名称相匹配。 例如: class P
两个双模蓝牙设备连接时,必须使用EDR,不能并联使用LE。然后必须通过 EDR 链路传输 BT 低功耗 GATT 配置文件。这是我从规范中读到的内容。 但是 iOS EDR 堆栈(在没有 MFi 许可
我正在尝试为 S3 开发蓝牙 4.0 应用程序。问题是,手机的行为就像它甚至没有蓝牙 4.0。它不会发现 4.0 设备,并且无法通过 4.0 设备发现。我在手机设置和应用程序中都尝试过,使用 Broa
我正在寻找一种与 Adafruit bluefruit LE(nRF8001 芯片组)板进行交互的方法,在 Windows 桌面应用程序中使用 c#(据我所知,我无法使用 Windows.Device
我是一名优秀的程序员,十分优秀!