[原创] 【M4 开发板入门】EKK-LM4F232探索四 M4的hibernate功能

蓝雨夜   2011-10-24 11:39 楼主

休眠模块

休眠模块提供降低功耗的一种手段管理电源的去除和恢复。当处理器和外围设备处于空闲状态,电源可以完全去除只有休眠模块有剩余的电源。根据外部信号或使用内置的实时时钟(RTC)在一定的时间内,电源就可以恢复。

休眠模块可以独立由电池或辅助电源提供。

 

休眠模块具有以下特点:

  1 / 32768的秒分辨率的32位实时秒计数器(RTC

- 32RTC秒匹配寄存器和15位子秒定时匹配唤醒并1 / 32768的秒分辨率产生中断

- RTC预分频器修整微调时钟速率

  两种电源控制机制

-系统电源控制使用离散外部稳压器的

- 片上电源控制使用内部开关下的寄存器控制

 

使用外部信号唤醒的专用引脚

 

只要VBAT​​是有效的,RTC的操作和休眠存储器为有效。

 

低电池电压检测,发生信号,并产生中断,在低电池选择唤醒

 

在休眠时候GPIO引脚的状态可以保留

 

时钟源来自32.768 kHz外部晶体或振荡器

 

1632位字的电池备份的存储器保存在休眠状态

  

RTC匹配可编程中断,外部唤醒和低电池事件

[ 本帖最后由 蓝雨夜 于 2011-10-24 11:49 编辑 ]
  • 休眠模块框图

回复评论 (13)

下表列出了休眠模块的外部信号,并介绍了每个功能

[ 本帖最后由 蓝雨夜 于 2011-10-24 11:42 编辑 ]
  • h2.JPG
点赞  2011-10-24 11:40
配置VBAT阈值电压:
模块可以监测VBAT引脚的电压电平。配置HIBCTL寄存器的 VBATSEL可以配置阈值电压可以在1.9 V和2.5 V之间。

休眠模块可以产生中断:
■唤醒引脚有效
■RTC匹配
■低电池检测
■写完成
点赞  2011-10-24 11:42
实验目的:Stellaris LM4F232H5QD正常运行跟在进入休眠模式下的功耗比较,没有与M3做比较!条件: EKK-LM4F232板载电流检测外围U15 --INA198,如图所示程序: LM4F232\boards\ek-lm4f232\hibernate例程
  • h3.JPG
点赞  2011-10-24 11:43
INA198:高侧,双向电流并联监视器 RS=R34=0.1Ω RL= 100kΩ Is=OUT/2 所以测量OUT电压就知道当前LM4F232H5QD的工作电流了!
  • h4.JPG
点赞  2011-10-24 11:44

实物测量:使用不同3位半万用表测量

 

未进入休眠模式: OUT =0.0658V, Is=0.0329A 进入休眠模式后OUT =0。0003V Is=0.00015A

 

当进入休眠模式时,通过测量R32=1K 电阻上的电压就知道当前修面模块的工作电流了!

 

未进入休眠模式:Ur32=0.0002V 进入休眠模式后Ur32=0。0019V

点赞  2011-10-24 11:45
//hibernate example.   
int
main(void)
{
    unsigned long ulIdx;
    unsigned long ulStatus = 0;
    unsigned long ulHibernateCount = 0;
    tContext sContext;
    tRectangle sRect;

    //
    // The FPU should be enabled because some compilers will use floating-
    // point registers, even for non-floating-point code.  If the FPU is not
    // enabled this will cause a fault.  This also ensures that floating-
    // point operations could be added to this application and would work
    // correctly and use the hardware floating-point unit.  Finally, lazy
    // stacking is enabled for interrupt handlers.  This allows floating-
    // point instructions to be used within interrupt handlers, but at the
    // expense of extra stack usage.
    //
    FPUEnable();
    FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the crystal.
    // 设置时钟运行直接从晶体
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
        // 设置时钟运行在50MHZ
    //ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
    //                   SYSCTL_OSC_MAIN);
    //
    // Initialize the UART.
    //  初始化UART
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);

    //
    // Initialize the OLED display
    // 初始化OLED显示屏
    CFAL96x64x16Init();

    //
    // Initialize the graphics context.
    // 初始化图形环境
    GrContextInit(&sContext, &g_sCFAL96x64x16);

    //
    // Fill the top 24 rows of the screen with blue to create the banner.
    //        填充蓝色屏幕的上方24行创建的标题
    sRect.sXMin = 0;
    sRect.sYMin = 0;
    sRect.sXMax = GrContextDpyWidthGet(&sContext) - 1;
    sRect.sYMax = 9;
    GrContextForegroundSet(&sContext, ClrDarkBlue);
    GrRectFill(&sContext, &sRect);

    //
    // Change foreground for white text.
    // 更改为白色文本的前景
    GrContextForegroundSet(&sContext, ClrWhite);

    //
    // Put the application name in the middle of the banner.
    // 把应用程序的名称放到标题的中间
    GrContextFontSet(&sContext, g_pFontFixed6x8);
    GrStringDrawCentered(&sContext, "hibernate", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 4, 0);

    //
    // Initialize the buttons driver
    // 初始化按钮驱动程序
    ButtonsInit();

    //
    // Set up systick to generate interrupts at 100 Hz.
    //设置SysTick 100HZ 产生中断,
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);
    ROM_SysTickIntEnable();
    ROM_SysTickEnable();

    //
    // Enable the Hibernation module.
    // 使能休眠模块
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

    //
    // Print wake cause message on display.
    // 在显示屏上打印唤醒原因消息
    GrStringDrawCentered(&sContext, "Wake due to:", -1,
                         GrContextDpyWidthGet(&sContext) / 2, ROW(2) + 4,
                         true);

    //
    // Check to see if Hibernation module is already active, which could mean
    // that the processor is waking from a hibernation.
    // 请检查如果休眠模块已经被激活,这可能意味着,处理器从休眠中醒来
    if(HibernateIsActive())
    {
        //
        // Read the status bits to see what caused the wake.
        // 读取状态位,看看有什么引起唤醒
        ulStatus = HibernateIntStatus(0);
        HibernateIntClear(ulStatus);

        //
        // Wake was due to the push button.
        // 由于按钮唤醒
        if(ulStatus & HIBERNATE_INT_PIN_WAKE)
        {
            GrStringDrawCentered(&sContext, "BUTTON", -1,
                                 GrContextDpyWidthGet(&sContext) / 2,
                                 ROW(3) + 4, true);
        }

        //
        // Wake was due to RTC match
        // 由于RTC的匹配唤醒
        else if(ulStatus & HIBERNATE_INT_RTC_MATCH_0)
        {
            GrStringDrawCentered(&sContext, "TIMEOUT", -1,
                                 GrContextDpyWidthGet(&sContext) / 2,
                                 ROW(3) + 4, true);
        }

        //
        // Wake is due to neither button nor RTC, so it must have been a hard
        // reset.
        // 由于既不是按钮也不是RTC唤醒,所以它必须被硬复位
        else
        {
            GrStringDrawCentered(&sContext, "RESET", -1,
                                 GrContextDpyWidthGet(&sContext) / 2,
                                 ROW(3) + 4, true);
        }

        //
        // If the wake is due to button or RTC, then read the first location
        // from the battery backed memory, as the hibernation count
        // 如果唤醒是由于按钮或RTC,然后从电池备份的存储器读取第一的位置,作为休眠计数
        if(ulStatus & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0))
        {
            HibernateDataGet(&ulHibernateCount, 1);
        }
    }

    //
    // Enable the Hibernation module.  This should always be called, even if
    // the module was already enabled, because this function also initializes
    // some timing parameters.
    // 启用休眠模块。这应始终被调用,即使已经启用的模块,因为这个函数还初始化一些时序参数
    HibernateEnableExpClk(ROM_SysCtlClockGet());

    //
    // If the wake was not due to button or RTC match, then it was a reset.
    // 如果不是因为按钮或RTC匹配唤醒,那么它是一个复位
    if(!(ulStatus & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0)))
    {
        //
        // Configure the module clock source.
        // 配置模块的时钟源
        HibernateClockSelect(HIBERNATE_CLOCK_SEL_DIV128);

        //
        // Finish the wake cause message.
        // 完成唤醒导致消息
        GrStringDrawCentered(&sContext, "RESET", -1,
                             GrContextDpyWidthGet(&sContext) / 2,
                             ROW(3) + 4, true);

        //
        // Wait a couple of seconds in case we need to break in with the
        // debugger.
        // 等待几秒钟的情况下,我们需要分开调试
        SysTickWait(3 * 100);

        //
        // Allow time for the crystal to power up.  This line is separated from
        // the above to make it clear this is still needed, even if the above
        // delay is removed.
        // 上电晶体允许时间 。这条线是从上面的分开,要清楚这仍然需要被删除,即使上述延迟
        SysTickWait(15);
    }

    //
    // Print the count of times that hibernate has occurred.
    // 打印,休眠已发生的次数计数
    usnprintf(cBuf, sizeof(cBuf), "Hib count=%4u", ulHibernateCount);
    GrStringDrawCentered(&sContext, cBuf, -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(1) + 4, true);

    //
    // Print messages on the screen about hibernation.
    // 关于休眠的屏幕上的打印信息
    GrStringDrawCentered(&sContext, "Select to Hib", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(4) + 4, true);
    GrStringDrawCentered(&sContext, "Wake in 5 s,", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(5) + 4, true);
    GrStringDrawCentered(&sContext, "or press Select", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(6) + 4, true);
    GrStringDrawCentered(&sContext, "for immed. wake.", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(7) + 4, true);

    //
    // Clear the button pressed flag, in case it was held down at the
    // beginning.
    // 清除“按钮按下的标志,假设它开始保持按下
    bSelectPressed = 0;

    //
    // Wait for user to press the button.
    // 等待用户按下按钮
    while(!bSelectPressed)
    {
        //
        // Wait a bit before looping again.
        // 循环再等待一个位
        SysTickWait(10);
    }

    //
    // Tell user to release the button.
    // 告诉用户释放按钮
    GrStringDrawCentered(&sContext, "                ", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(4) + 4, true);
    GrStringDrawCentered(&sContext, "Release the", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(5) + 4, true);
    GrStringDrawCentered(&sContext, "button.", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(6) + 4, true);
    GrStringDrawCentered(&sContext, "                ", -1,
                         GrContextDpyWidthGet(&sContext) / 2,
                         ROW(7) + 4, true);

    //
    // Wait for user to release the button.
    // 等待用户释放按钮
    while(bSelectPressed)
    {
    }

    //
    // If hibernation count is very large, it may be that there was already
    // a value in the hibernate memory, so reset the count.
    // 如果休眠数是非常大的的,它可能已经有一个休眠内存中的值,所以复位计数
    ulHibernateCount = (ulHibernateCount > 10000) ? 0 : ulHibernateCount;

    //
    // Increment the hibernation count, and store it in the battery backed
    // memory.
    // 增加休眠计数,并储存在电池供电的存储器
    ulHibernateCount++;
    HibernateDataSet(&ulHibernateCount, 1);

    //
    // Clear and enable the RTC and set the match registers to 5 seconds in the
    // future. Set both to same, though they could be set differently, the
    // first to match will cause a wake.
    // 清除和使能RTC并且将设置匹配寄存器为5秒。设置都相同,但他们有可能设置不同,第一个匹配将导致唤醒
    HibernateRTCSet(0);
    HibernateRTCEnable();
    HibernateRTCMatch0Set(5);

    //
    // Set wake condition on pin or RTC match.  Board will wake when 5 seconds
    // elapses, or when the button is pressed.
    // 设置管脚唤醒条件或RTC匹配。每过去5秒过后将会唤醒,或当按下按钮
    HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC);

    //
    // Request hibernation.
    // 请求休眠状态
    HibernateRequest();

    //
    // Give it time to activate, it should never get past this wait.
    // 给他时间来激活,它应该永远不会通过这段等待
    SysTickWait(100);

    //
    // Should not have got here, something is wrong.  Print an error message to
    // the user.
    // 不应该来到这里的,什么是错的。打印一个错误信息给用户
    sRect.sXMin = 0;
    sRect.sXMax = 95;
    sRect.sYMin = 0;
    sRect.sYMax = 63;
    GrContextForegroundSet(&sContext, ClrBlack);
    GrRectFill(&sContext, &sRect);
    GrContextForegroundSet(&sContext, ClrWhite);
    ulIdx = 0;
    while(cErrorText[ulIdx])
    {
        GrStringDraw(&sContext, cErrorText[ulIdx], -1, COL(0), ROW(ulIdx), true);
        ulIdx++;
    }

    //
    // Wait for the user to press the button, then restart the app.
    //  等待用户按下按钮,然后重新启动应用程序
    bSelectPressed = 0;
    while(!bSelectPressed)
    {
    }

    //
    // Reset the processor.
    // 处理器复位
    ROM_SysCtlReset();

    //
    // Finished.
    //
    while(1)
    {
    }
}
点赞  2011-10-24 11:46
没东西试。
点赞  2011-10-24 13:56
LZ不错。顶哈。。。。ST的F4也出来了,相比之下,貌似。。。。。
只有想不到,没有做不到。
点赞  2011-10-24 22:29
LZ 赞一个啊!
点赞  2011-10-25 17:10

不错顶起

http://shop34182318.taobao.com/ https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
点赞  2011-10-25 20:07

不错

好吧 我承认  我正在使用STM8的AWU  不过遇到点问题 ·~ 
点赞  2011-10-25 22:06
LZ,太犀利了。这么快就玩上了
点赞  2011-12-20 14:30
楼主能否更新一下程序啊,这个程序有点问题
点赞  2015-8-9 09:09
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复