STM8单片机低功耗---活跃停机(Active Halt)模式实现-2

x33g5p2x  于2022-04-22 转载在 其他  
字(3.2k)|赞(0)|评价(0)|浏览(410)

在上一篇文章中 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模式实现

相关文章