//系统睡眠模式并唤醒演示:GPIOA_6和GPIOA_5作为唤醒源,共6种睡眠等级
#include "CH57x_common.h" // 引入CH57x系列单片机的通用头文件
void DebugInit(void)
{
GPIOA_SetBits(GPIO_Pin_9); // 设置GPIOA的第9位为高电平
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); // 配置GPIOA的第9位为推挽输出,输出电流为5mA
UART1_DefInit(); // 初始化UART1串口
}
int main()
{
DelayMs(2); // 延时2毫秒
SetSysClock( CLK_SOURCE_HSE_32MHz ); // 设置外部32MHz晶振作为系统时钟
GPIOA_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); // 配置GPIOA的所有引脚为上拉输入模式
GPIOB_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); // 配置GPIOB的所有引脚为上拉输入模式
/* 配置串口调试 */
DebugInit(); // 调用DebugInit函数进行调试初始化
PRINT( "Start @ChipID=%02x
", R8_CHIP_ID ); // 打印芯片ID
DelayMs(200); // 延时200毫秒
#if 1
/* 配置唤醒源为 GPIO - PA6&PA5 */
GPIOA_ModeCfg( GPIO_Pin_6|GPIO_Pin_5, GPIO_ModeIN_PU ); // 配置GPIOA的第6和第5位为上拉输入模式
GPIOA_ITModeCfg( GPIO_Pin_6|GPIO_Pin_5, GPIO_ITMode_FallEdge ); // 配置GPIOA的第6和第5位下降沿触发中断
NVIC_EnableIRQ( GPIO_IRQn ); // 使能GPIO中断
PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE ); // 使能GPIO唤醒功能
#endif
#if 1
PRINT( "IDLE mode sleep \n");
DelayMs(1);
LowPower_Idle(); // 进入IDLE低功耗模式
PRINT( "wake.. \n");
DelayMs(500); // 延时500毫秒
#endif
#if 1
PRINT( "Halt_1 mode sleep \n");
DelayMs(1);
LowPower_Halt_1(); // 进入Halt_1低功耗模式
/*
使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us
HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙
DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5)
*/
if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电
PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电
DelayUs((1200)/5);
}
else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源
DelayUs((1200-330)/5);
}
HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
DelayUs(5/5); // 等待稳定 1-5us
SetSysClock( CLK_SOURCE_HSE_32MHz );
PRINT( "wake.. \n");
DelayMs(500);
#endif
#if 1
PRINT( "Halt_2 mode sleep \n");
DelayMs(1);
LowPower_Halt_2(); // 进入Halt_2低功耗模式
/*
使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us
HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙
DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5)
*/
if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电
PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电
DelayUs((1200)/5);
}
else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源
DelayUs((1200-330)/5);
}
HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
DelayUs(5/5); // 等待稳定 1-5us
SetSysClock( CLK_SOURCE_HSE_32MHz );
PRINT( "wake.. \n");
DelayMs(500);
#endif
#if 1
PRINT( "sleep mode sleep \n");
DelayMs(1);
LowPower_Sleep( RB_PWR_RAM14K|RB_PWR_RAM2K ); //只保留14+2K SRAM 供电
/*
使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us
HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙
DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5)
*/
if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电
PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电
DelayUs((1200)/5);
}
else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源
DelayUs((1200-330)/5);
}
HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
DelayUs(5/5); // 等待稳定 1-5us
SetSysClock( CLK_SOURCE_HSE_32MHz );
PRINT( "wake.. \n");
DelayMs(500);
#endif
#if 1
PRINT( "shut down mode sleep \n");
DelayMs(1);
LowPower_Shutdown( NULL ); //全部断电,唤醒后复位
/*
此模式唤醒后会执行复位,所以下面代码不会运行,
注意要确保系统睡下去再唤醒才是唤醒复位,否则有可能变成IDLE等级唤醒
*/
/*
使用HSI/5=6.4M睡眠,唤醒时间大概需要 2048Tsys≈330us
HSE起振一般不超过1.2ms(500us-1200us),所以切换到外部HSE,需要 1.2ms-330us 这个时间可以保证HSE足够稳定,一般用于蓝牙
DelayUs()函数时基于32M时钟的书写,此时主频为6.4M,所以 DelayUs((1200-330)/5)
*/
if(!(R8_HFCK_PWR_CTRL&RB_CLK_XT32M_PON)) { // 是否HSE上电
PWR_UnitModCfg( ENABLE, UNIT_SYS_HSE ); // HSE上电
DelayUs((1200)/5);
}
else if(!(R16_CLK_SYS_CFG&RB_CLK_OSC32M_XT)){ // 是否选择 HSI/5 做时钟源
DelayUs((1200-330)/5);
}
HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
DelayUs(5/5); // 等待稳定 1-5us
SetSysClock( CLK_SOURCE_HSE_32MHz );
PRINT( "wake.. \n");
DelayMs(500);
#endif
while(1);
}
void GPIO_IRQHandler(void)
{
GPIOA_ClearITFlagBit( GPIO_Pin_6|GPIO_Pin_5 ); // 清除GPIOA的第6和第5位的中断标志位
}
|