7.2 外部中断/唤醒
芯片的部分 I/O 管脚具有中断功能,并可实现睡眠唤醒。
为了使用外部中断,端口位必须配置成输入模式。并提供 4 种触发模式:高电平、低电平、上升
沿、下降沿。
唤醒功能需要打开端口位的中断使能 R16_Px_INT_EN,并开启寄存器 R8_SLP_WAKE_CTRL 中的 GPIO
唤醒控制位 RB_SLP_GPIO_WAKE。
1 /********************************** (C) COPYRIGHT ******************************* 2 * File Name : Main.c 3 * Author : LB 4 * Version : V1.0 5 * Date : 2021/12/28 6 * Description : 系统睡眠模式并唤醒演示:GPIOA_5作为唤醒源,共4种睡眠等级 7 *******************************************************************************/ 8 9 /* 10 注意:切换到HSE时钟源,所需等待稳定时间和选择的外置晶体参数有关,选择一款新的晶体最好阅读厂家提供的晶体及其 11 负载电容参数值。通过配置R8_XT32M_TUNE寄存器,可以配置不同的负载电容和偏置电流,调整晶体稳定时间。 12 */ 13 14 #include "CH58x_common.h" 15 16 void DebugInit( void ) 17 { 18 GPIOA_SetBits( GPIO_Pin_9 ); 19 GPIOA_ModeCfg( GPIO_Pin_9, GPIO_ModeOut_PP_5mA ); 20 UART1_DefInit(); 21 } 22 23 int main() 24 { 25 SetSysClock( CLK_SOURCE_PLL_60MHz ); 26 27 GPIOA_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); 28 GPIOB_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); 29 30 /* 配置串口调试 */ 31 DebugInit(); 32 PRINT( "Start @ChipID=%02x\n", R8_CHIP_ID ); 33 DelayMs( 200 ); 34 35 #if 1 36 /* 配置唤醒源为 GPIO - PA5 */ 37 GPIOA_ModeCfg( GPIO_Pin_5, GPIO_ModeIN_PU ); //初始化IO状态 38 GPIOA_ITModeCfg( GPIO_Pin_5, GPIO_ITMode_FallEdge ); // 设置下降沿唤醒 39 PFIC_EnableIRQ( GPIO_A_IRQn ); //开启GPIO中断 PA口 40 41 GPIOB_ModeCfg( GPIO_Pin_4, GPIO_ModeIN_PD ); //初始化IO状态 42 GPIOB_ITModeCfg( GPIO_Pin_4, GPIO_ITMode_HighLevel ); // 高电平唤醒 43 PFIC_EnableIRQ( GPIO_B_IRQn ); //开启GPIO中断 PB口 44 PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE, Long_Delay );//开启GPIO唤醒使能 45 #endif 46 47 #if 0 48 PRINT( "IDLE mode sleep \n" ); 49 DelayMs( 1 ); 50 LowPower_Idle(); 51 PRINT( "wake.. \n" ); 52 DelayMs( 500 ); 53 #endif 54 55 #if 0 56 PRINT( "Halt mode sleep \n" ); 57 DelayMs( 2 ); 58 LowPower_Halt(); 59 HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) 60 DelayMs( 2 ); 61 PRINT( "wake.. \n" ); 62 DelayMs( 500 ); 63 #endif 64 65 while(1) //睡眠模式演示 66 { 67 #if 1 68 PRINT( "sleep mode sleep \n" ); 69 DelayMs( 2 ); 70 // 注意当主频为80M时,Sleep睡眠唤醒中断不可调用flash内代码。 71 LowPower_Sleep( RB_PWR_RAM30K | RB_PWR_RAM2K ); //只保留30+2K SRAM 供电 72 HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) 73 DelayMs( 5 );//等时钟稳定 74 PRINT( "wake.. \n" ); 75 DelayMs( 5 ); 76 #endif 77 } 78 79 #if 0 80 PRINT( "shut down mode sleep \n" ); 81 PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE, Long_Delay ); 82 DelayMs( 2 ); 83 LowPower_Shutdown( 0 ); //全部断电,唤醒后复位 84 /* 85 此模式唤醒后会执行复位,所以下面代码不会运行, 86 注意要确保系统睡下去再唤醒才是唤醒复位,否则有可能变成IDLE等级唤醒 87 */ 88 HSECFG_Current( HSE_RCur_100 ); // 降为额定电流(低功耗函数中提升了HSE偏置电流) 89 PRINT( "wake.. \n" ); 90 DelayMs( 500 ); 91 #endif 92 93 while( 1 ) 94 ; 95 } 96 97 __INTERRUPT 98 __HIGH_CODE 99 void GPIOA_IRQHandler( void ) 100 { 101 GPIOA_ClearITFlagBit( GPIO_Pin_5 ); //GPIO唤醒会进中断,要清除GPIO中断 102 } 103 104 __INTERRUPT 105 __HIGH_CODE 106 void GPIOB_IRQHandler( void ) 107 { 108 GPIOB_ClearITFlagBit( GPIO_Pin_4 ); //GPIO唤醒会进中断,要清除GPIO中断 109 }