之所以寫(xiě)這篇博客,是因?yàn)樽罱鲆粋€(gè)項(xiàng)目,需要用到單片機(jī)的低功耗模式。第一次用stm8,我在網(wǎng)上看了很多資料,雖然有些寫(xiě)的還是挺詳細(xì)的,但是我自己實(shí)際調(diào)試的時(shí)候還是出了不少意外,花了不少時(shí)間,因此想寫(xiě)一篇文章讓你們少走一些彎路。語(yǔ)文水平有限,寫(xiě)的不好勿怪。
在講程序之前先說(shuō)明幾點(diǎn):
1.STM8低功耗的幾種模式我不多說(shuō)了,這方面的資料很多,自己可以先去了解一下。
2. 我測(cè)試用的主控芯片是STM8L151G6。(其他L系列程序上沒(méi)有什么區(qū)別,至于功耗是不是一樣我就不知道了)
3. 程序用的是庫(kù)函數(shù)的寫(xiě)法。
4. 低功耗模式用的是Halt模式,也就是停機(jī)模式,功耗是最低的,其他模式的功耗我沒(méi)有測(cè)過(guò),這里不說(shuō)。
5. 為了更加直觀,我下面寫(xiě)的程序盡可能簡(jiǎn)化。(外設(shè)部分的程序沒(méi)寫(xiě)進(jìn)去)
6. 如果我有哪里寫(xiě)錯(cuò)了,歡迎來(lái)指正。
好了廢話不多說(shuō),馬上開(kāi)始程序的編寫(xiě)。
//main函數(shù)
void mian(void)
{
//配置時(shí)鐘
CLK_HSICmd(ENABLE);
CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI); // 我用的是內(nèi)部時(shí)鐘
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1); //1分頻,也就是16M,實(shí)際測(cè)試,時(shí)鐘分頻對(duì)功耗沒(méi)什么影響
//下面可以寫(xiě)外設(shè)的初始化函數(shù)
//下面可以寫(xiě)外部中斷初始化,halt模式只能通過(guò)外部中斷或復(fù)位喚醒,我這里用了PB1,引腳接的是OPT3001光感芯片的中斷腳
disableInterrupts(); //先關(guān)閉總中斷(也可以不寫(xiě),如果是多個(gè)外部中斷,最好加上,不然會(huì)有個(gè)bug,具體這里不說(shuō)了)
GPIO_Init(GPIOB, GPIO_Pin_1, GPIO_Mode_In_PU_IT); //PB1 配置成上拉外部中斷
EXTI_DeInit();
EXTI_SetPinSensitivity(EXTI_Pin_1,EXTI_Trigger_Falling); //PIN1 設(shè)置為下降沿中斷(具體根據(jù)實(shí)際情況)
enableInterrupts();//使能總中斷
//下面可以控制外設(shè)進(jìn)入休眠模式
//除了單片機(jī),單片機(jī)控制的各個(gè)模塊也會(huì)耗電,如果不需要一直工作可以進(jìn)入休眠
//比如我用到的LORA模塊,不需要一直發(fā)射或接收數(shù)據(jù),所以進(jìn)入休眠模式
//比如光照傳感器,需要一直采集數(shù)據(jù),并判斷有沒(méi)有超出設(shè)置好的上限或下限,因此不能休眠
//單片機(jī)在進(jìn)入停機(jī)模式之間,關(guān)閉沒(méi)有用到的外設(shè)可以降低功耗(根據(jù)實(shí)際情況增加和刪減)
CLK_PeripheralClockConfig(CLK_Peripheral_ADC1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM3,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_SPI1,DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_USART1,DISABLE);
//把沒(méi)有接外設(shè)或者暫時(shí)不用的引腳設(shè)置為低速,輸出低(這里需要根據(jù)實(shí)際情況配置)
//千萬(wàn)別小瞧這些懸空的引腳,如果有幾個(gè)懸空的引腳沒(méi)有配置可能會(huì)多出幾百uA
//在網(wǎng)上看到一些資料說(shuō)可以設(shè)為浮空輸入,我實(shí)際測(cè)試過(guò),在引腳懸空的情況下,引腳輸出低,功耗會(huì)更低,有外設(shè)的引腳看情況而定
//比如引腳接了一個(gè)低電平點(diǎn)亮的LED燈時(shí),引腳拉高才能降低功耗
//我這里只寫(xiě)單片機(jī)引腳不接任何外設(shè)的情況,引腳全部拉低
GPIO_Init(GPIOA,GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Slow);
GPIO_Init(GPIOB,GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Slow);
GPIO_Init(GPIOC,GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Slow);
GPIO_Init(GPIOD,GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Slow);
//進(jìn)入停機(jī)模式
while(1)
{
// 下面這一句很關(guān)鍵,加上這句才能真正進(jìn)入超低功耗模式(這個(gè)函數(shù)在stm8l15x_pwr.c里面,需要把它加到工程里面)
PWR_UltraLowPowerCmd(ENABLE);
//進(jìn)入停機(jī)模式
halt();
}
}
//中斷服務(wù)函數(shù)(在stm8l15x_it.c里面)
INTERRUPT_HANDLER(EXTI1_IRQHandler, 9)
{
EXTI_ClearITPendingBit(EXTI_IT_Pin1); //清除中斷標(biāo)志
//下面可以寫(xiě)中斷喚醒單片機(jī)之后需要執(zhí)行的程序
}
功耗測(cè)試結(jié)果(僅供參考):
1.單片機(jī)引腳全部懸空,引腳全部拉低,電流為0.4uA,這個(gè)和官方手冊(cè)上面的最低功耗是一致的。
2.單片機(jī)只接一個(gè)SX1276 868MLORA模塊,LORA設(shè)置為休眠,除了LORA其他單片機(jī)引腳全部拉低,總電流為1.6uA。
3.單片機(jī)接SX1276 868MLORA模塊和OPT3001光照IC,LORA休眠,OPT3001工作,中斷不觸發(fā)的時(shí)候,電流為14uA左右。中斷喚醒后的功耗和執(zhí)行的程序相關(guān)。
測(cè)試功耗需要注意的幾點(diǎn):
2.測(cè)試的時(shí)候把單片機(jī)和下載器、仿真器、串口等斷開(kāi)連接。
3.測(cè)試的時(shí)候建議先單獨(dú)測(cè)試stm8,然后再把外設(shè)一個(gè)一個(gè)加上去測(cè)試,我一開(kāi)始測(cè)試的時(shí)候用的是一塊電路完整的模塊,測(cè)試的時(shí)候很難確定電流降不下去的原因,折騰了很久。