做了一個簡單的項目,電路板使用電池供電,需要系統在待機時低功耗。而對外接口只有4個按鍵,也就是喚醒必須要通過這四個按鍵。
系統功能就不介紹了,只給出進入低功耗的代碼和退出低功耗的代碼。
使用芯片為stm8s103

1 /***************************************************************** 2 //進入到停機模式 3 *****************************************************************/ 4 void EnterHalt() 5 { 6 int j=255; 7 8 /* 防止定時器中斷喚醒了CPU */ 9 TIM1_CR1 &= 0xFE; /* 用戶操作計數器關掉 */ 10 11 asm("sim"); 12 13 /* PC3 PC4 PC5 PC6 使能外部中斷 */ 14 PC_DDR_DDR3 = 0; 15 PC_CR1_C13 = 1; 16 PC_CR2_C23 = 1; 17 18 PC_DDR_DDR4 = 0; 19 PC_CR1_C14 = 1; 20 PC_CR2_C24 = 1; 21 22 PC_DDR_DDR5 = 0; 23 PC_CR1_C15 = 1; 24 PC_CR2_C25 = 1; 25 26 PC_DDR_DDR6 = 0; 27 PC_CR1_C16 = 1; 28 PC_CR2_C26 = 1; 29 30 EXTI_CR1 = 0x00; //PC端口 低電平和下降沿都中斷 31 32 for(j=255;j>0;j--); //延時一會 33 34 asm("rim"); 35 asm("HALT"); /* 進入停機模式 */ 36 }
先關閉中斷,配置IO口為外部中斷,開中斷,進入低功耗。
在外部中斷中,配置IO口為普通IO。

1 #pragma vector = 7 2 __interrupt void EXTI_PORTC_IRQHandler(void) 3 { 4 ExitHalt(); //開定時器 配置Lock鍵為普通IO 5 } 6 7 /**************************************************************** 8 //退出停機模式 9 *****************************************************************/ 10 void ExitHalt() 11 { 12 TIM1_CR1 |= 0x01; /* 開用戶操作定時器 */ 13 14 //PC3 PC4 PC5 PC6配置為普通IO口 輸入 用於按鍵檢測 15 PC_DDR_DDR3 = 0; 16 PC_CR1_C13 = 1; 17 PC_CR2_C23 = 0; 18 19 PC_DDR_DDR4 = 0; 20 PC_CR1_C14 = 1; 21 PC_CR2_C24 = 0; 22 23 PC_DDR_DDR5 = 0; 24 PC_CR1_C15 = 1; 25 PC_CR2_C25 = 0; 26 27 PC_DDR_DDR6 = 0; 28 PC_CR1_C16 = 1; 29 PC_CR2_C26 = 0; 30 31 EXTI_CR1 = 0x00; 32 }
流程如上,實際會出現一個小問題,就是配置IO口為外部中斷,開了中斷以后,就立即進入了中斷程序(中斷條件為低電平和下降沿)。進入了中斷程序后,IO口配置又將IO口配置為普通引腳,接着進入低功耗。再按按鍵怎么也不能喚醒了。如果你也遇到這樣的問題,請參照上面的進入低功耗的代碼,在配置IO口為中斷引腳后,延時一會,再開中斷。
使用stm8的停機模式后,在3.0V供電的情況下,電路板整體功耗為5.6uA。使用電池供電,待機也能使用1年以上。