休眠模块
休眠模块提供降低功耗的一种手段管理电源的去除和恢复。当处理器和外围设备处于空闲状态,电源可以完全去除只有休眠模块有剩余的电源。根据外部信号或使用内置的实时时钟(RTC)在一定的时间内,电源就可以恢复。
休眠模块可以独立由电池或辅助电源提供。
休眠模块具有以下特点:
■ 1 / 32,768的秒分辨率的32位实时秒计数器(RTC)
- 32位RTC秒匹配寄存器和15位子秒定时匹配唤醒并1 / 32,768的秒分辨率产生中断
- RTC预分频器修整微调时钟速率
■ 两种电源控制机制
-系统电源控制使用离散外部稳压器的
- 片上电源控制使用内部开关下的寄存器控制
■
使用外部信号唤醒的专用引脚
■
只要VBAT是有效的,RTC的操作和休眠存储器为有效。
■
低电池电压检测,发生信号,并产生中断,在低电池选择唤醒
■
在休眠时候GPIO引脚的状态可以保留
■
时钟源来自32.768 kHz外部晶体或振荡器
■
16个32位字的电池备份的存储器保存在休眠状态
■
RTC匹配可编程中断,外部唤醒和低电池事件
[
本帖最后由 蓝雨夜 于 2011-10-24 11:49 编辑 ]
配置VBAT阈值电压:
模块可以监测VBAT引脚的电压电平。配置HIBCTL寄存器的 VBATSEL可以配置阈值电压可以在1.9 V和2.5 V之间。
休眠模块可以产生中断:
■唤醒引脚有效
■RTC匹配
■低电池检测
■写完成
实验目的:Stellaris LM4F232H5QD正常运行跟在进入休眠模式下的功耗比较,没有与M3做比较!条件: EKK-LM4F232板载电流检测外围U15 --INA198,如图所示程序: LM4F232\boards\ek-lm4f232\hibernate例程
INA198:高侧,双向电流并联监视器 RS=R34=0.1Ω RL= 100kΩ Is=OUT/2 所以测量OUT电压就知道当前LM4F232H5QD的工作电流了!
实物测量:使用不同3位半万用表测量
未进入休眠模式: OUT =0.0658V, Is=0.0329A 进入休眠模式后OUT =0。0003V Is=0.00015A
当进入休眠模式时,通过测量R32=1K 电阻上的电压就知道当前修面模块的工作电流了!
未进入休眠模式:Ur32=0.0002V 进入休眠模式后Ur32=0。0019V
//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)
{
}
}