實(shí)驗(yàn)3:貪睡模式
在軟件待機(jī)模式下,大部分時(shí)鐘是關(guān)閉的,只有RTC,AGT,IWGT這些低功耗時(shí)鐘可以運(yùn)行。但貪睡模式下,所有時(shí)鐘都能運(yùn)行,這也包括了GPT,因此本次實(shí)驗(yàn)為了體現(xiàn)貪睡模式的特點(diǎn),并使用GPT產(chǎn)生的PWM來(lái)控制開(kāi)發(fā)板的LED亮度。
硬件設(shè)計(jì)
33.6.1.1
軟件待機(jī)模式與貪睡模式的轉(zhuǎn)變框圖

進(jìn)入貪睡模式前需要進(jìn)入軟件待機(jī)模式,在SNZCR(Snooze Control Register)寄存器的SNZE(Snooze Mode Enable)位為1的時(shí)候,再通過(guò)貪睡請(qǐng)求(Snooze requests)進(jìn)入貪睡模式。同時(shí)也
能通過(guò)貪睡結(jié)束(Snooze end)下再次進(jìn)入軟件待機(jī)模式,這兩個(gè)模式共用喚醒源(Wake Source)
進(jìn)行喚醒。
軟件設(shè)計(jì)
33.6.2.1
新建工程
工程新建好之后,我們還需要添加GPT用來(lái)進(jìn)行實(shí)驗(yàn),在例程中為了方便我們不再額外添加GPT模塊函數(shù),而是直接放到LED中使用,只需要讓PWM占空比大一些,能通過(guò)視覺(jué)看出差異即可。
33.6.2.2
FSP配置
如圖,將Low Power Mode修改為Snooze mode,名字按自己需求取即可。Wake Sources與實(shí)驗(yàn)2相同,選擇IRQ9。Snooze Request Source選擇 IRQ10,其他按照默認(rèn)設(shè)置即可。

33.6.2.3
LED_Task流水燈任務(wù)
列表6:代碼清單38-4:LED_Task流水燈任務(wù)
voidLED_Task(){/* 流水燈任務(wù) */LED2_ON;R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);LED3_ON;R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);LED2_OFF;R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);LED3_OFF;/* 貪睡前打印 */printf("MCU 進(jìn)入貪睡模式狀態(tài)\r\n");/* 執(zhí)行完流水燈任務(wù),進(jìn)入貪睡模式 */R_LPM_LowPowerModeEnter(snooze.p_ctrl);/* 被喚醒后打印 */printf("MCU 被喚醒成功\r\n");}
與實(shí)驗(yàn)1和2不同,LED_R,即紅色LED需要用于表現(xiàn)PWM輸出,因此這里的流水燈只有藍(lán)色LED和綠色LED。注意,在任務(wù)流水燈結(jié)束后進(jìn)入的是軟件待機(jī)模式,需要通過(guò)貪睡請(qǐng)求(Snooze Request)才能進(jìn)入貪睡模式,也就是我們剛剛設(shè)置的的Key2按鍵。
33.6.2.4
hal_entry函數(shù)
列表7:代碼清單38-5:hal_entry函數(shù)
voidhal_entry(void){/* TODO: add your own code here */Debug_UART4_Init(); //初始化 debug 串口Key_Init(); //初始化按鍵R_BSP_PinAccessEnable(); //啟用對(duì) PFS 寄存器的訪問(wèn), 因?yàn)楹竺鎸?xiě) IO 口都用 BSP內(nèi)聯(lián)函數(shù)R_LPM_Open(snooze.p_ctrl, snooze.p_cfg); //打開(kāi) LPMR_GPT_Open(gpt_pwm.p_ctrl, gpt_pwm.p_cfg); //打開(kāi) GPT 計(jì)時(shí)器R_GPT_Start(gpt_pwm.p_ctrl); //啟動(dòng) GPT 計(jì)時(shí)器while(1){GPT_LED1_PWM_ON_Snooze_Mode(); //LED1 呼吸燈任務(wù)LED_Task(); //led 任務(wù)}/* Enter non-secure code */R_BSP_NonSecureEnter();}
hal_entry函數(shù)中初始化外設(shè)并打開(kāi)LPM后,在while(1)中執(zhí)行LED任務(wù)。
下載驗(yàn)證
下載程序后,需要斷電再供電重啟,程序即可正常運(yùn)行。正確連接硬件并供電后,可以看見(jiàn),流水燈任務(wù)執(zhí)行完畢后,用于表現(xiàn)PWM輸出的紅色LED熄滅或者和開(kāi)發(fā)板的紅色電源LED燈一樣亮(這取決與進(jìn)入低功耗模式時(shí)紅色LED的亮滅狀態(tài)),這是因?yàn)榇藭r(shí)處于軟件待機(jī)模式,GPT時(shí)鐘是停止工作的,自然也不會(huì)產(chǎn)生PWM。按下按鍵2后,MCU收到貪睡請(qǐng)求,進(jìn)入貪睡模式,此時(shí)GPT恢復(fù)工作,因此紅色LED也恢復(fù)運(yùn)行狀態(tài)時(shí)的原本亮度。

注:
貪睡模式下也無(wú)法對(duì)MCU進(jìn)行燒寫(xiě),如果發(fā)現(xiàn)無(wú)法燒寫(xiě)程序,可以試著按一下復(fù)位鍵或者將MCU喚醒后再進(jìn)行燒寫(xiě)。
實(shí)驗(yàn)4:深度軟件待機(jī)模式
最后我們來(lái)學(xué)習(xí)深度軟件待機(jī)模式,這個(gè)模式的耗電是四種低功耗模式中最低的,能工作的外設(shè)和時(shí)鐘也是最少的。
硬件設(shè)計(jì)
所需硬件較少,兩個(gè)按鍵,一個(gè)LED和一個(gè)串口即可。
軟件設(shè)計(jì)
33.7.2.1
普通模式與深度軟件待機(jī)模式的轉(zhuǎn)換框圖

如上圖,進(jìn)入深度軟件待機(jī)模式前會(huì)先進(jìn)入軟件待機(jī)模式,若DPSBYCR(Deep Standby Control Register)寄存器的DPSBY(Deep Software Standby)位為1,則進(jìn)入深度軟件待機(jī)模式。在深度軟件待機(jī)模式下,CPU,不在備份域的寄存器和SRAM的數(shù)據(jù)都會(huì)丟失,因此無(wú)法在進(jìn)入該模式的地方喚醒,只能通過(guò)內(nèi)部復(fù)位讓程序從頭開(kāi)始運(yùn)行。
33.7.2.2
新建工程
33.7.2.3
FSP配置
將Low Power Mode配置為Deep Software Standby mode,在Deep Standby Options中配置喚醒源,因?yàn)槲覀冮_(kāi)發(fā)板的按鈕是按下后接地,默認(rèn)喚醒邊沿就是下降沿,故不需要配置喚醒邊沿,其他
配置按默認(rèn)即可。

下表為Deep Standby Options的屬性描述。

表5:Deep Standby Options屬性描述
33.7.2.4
hal_entry函數(shù)
列表8:代碼清單38-6:hal_entry函數(shù)
voidhal_entry(void){/* TODO: add your own code here */Debug_UART4_Init (); //初始化 debug 串口IRQ_Init (); //按鍵中斷初始化R_BSP_PinAccessEnable (); //啟用對(duì) PFS 寄存器的訪問(wèn), 因?yàn)楹竺鎸?xiě) IO 口都用 BSP內(nèi)聯(lián)函數(shù)/* 判斷是否在深度軟件待機(jī)模式下被喚醒 */if (1U == R_SYSTEM->RSTSR0_b.DPSRSTF){/* 從深度軟件待機(jī)模式喚醒后清除 IOkeep 位,以允許使用 IO 端口 */R_LPM_IoKeepClear (NULL);/* 清除喚醒標(biāo)志位 */R_SYSTEM->RSTSR0_b.DPSRSTF = 0;/* 判斷喚醒源是 IRQ-9 還是 IRQ-10,并將判斷結(jié)果打印出來(lái) */if (R_SYSTEM->DPSIFR1 >> 1 & 0x01U){printf("MCU 喚醒源為 IRQ-9\r\n");}elseif (R_SYSTEM->DPSIFR1 >> 2 & 0x01U){printf("MCU 喚醒源為 IRQ-10\r\n");}}LED_Flicker (10); //LED 閃爍 10 次while (1){if (key_flag == true){/* 標(biāo)志位置 0,防止程序不斷進(jìn)入 if 的代碼塊里面 */key_flag = false;/*LED 閃爍 2 次 */LED_Flicker (2);/* 進(jìn)入低功耗模式前打印 */printf("MCU 進(jìn)入深度軟件待機(jī)狀態(tài)\r\n");/* 打開(kāi) LPM, 進(jìn)入深度軟件待機(jī)狀態(tài) */R_LPM_Open (deep_sw_standby.p_ctrl, deep_sw_standby.p_cfg);R_LPM_LowPowerModeEnter (deep_sw_standby.p_ctrl);/* 喚醒后打印,但是在進(jìn)入深度軟件待機(jī)模式后不能保存上下文,故這里正常來(lái)說(shuō)無(wú)法被執(zhí)行, 如果執(zhí)行了則說(shuō)明進(jìn)入的是睡眠模式,也就是程序出現(xiàn)了問(wèn)題,一般剛燒寫(xiě)程序會(huì)導(dǎo)致這個(gè)問(wèn)題,重新上電即可恢復(fù)正常 */printf("MCU 被喚醒(出現(xiàn)本消息說(shuō)明程序出錯(cuò))\r\n");}}#if BSP_TZ_SECURE_BUILD/* Enter non-secure code */R_BSP_NonSecureEnter();#endif}
hal_entry函數(shù)首先初始化外設(shè),并檢測(cè)RSTSR0(Reset Status Register)寄存器的DPSRSTF(Deep Software Standby Reset Flag)位,判斷MCU是否從深度軟件待機(jī)模式中喚醒,若該位為1,則清除IOkeep位和DPSRSTF位,允許使用IO口,并通過(guò)串口打印喚醒源。在進(jìn)入while(1)循環(huán)前再次讓LED閃爍。注意,LED閃爍和打印前必須清除IOkeep位,否則IO口無(wú)法工作。在while(1)中,通過(guò)key_flag標(biāo)志位判斷按鈕是否按下,按下后,LED閃爍兩次,通過(guò)串口打印信息并進(jìn)入深度軟件待機(jī)模式。
33.7.2.5
按鍵外部中斷回調(diào)函數(shù)
列表9:代碼清單38-7:按鍵外部中斷回調(diào)函數(shù)
volatile_Bool key_flag = false; //設(shè)置標(biāo)志位/* 按鍵 1 中斷回調(diào),用于進(jìn)入深度睡眠或喚醒 */voidkey1_irq_callback(external_irq_callback_args_t *p_args){/* 防止編譯器產(chǎn)生沒(méi)有使用形參的警告 */FSP_PARAMETER_NOT_USED(p_args);key_flag = true;}/* 按鍵 2 中斷回調(diào),用于喚醒 */voidkey2_irq_callback(external_irq_callback_args_t *p_args){/* 防止編譯器產(chǎn)生沒(méi)有使用形參的警告 */FSP_PARAMETER_NOT_USED(p_args);}
key_flag是一個(gè)volatile修飾的全局變量,用于hal_entry函數(shù)判斷按鍵是否被按下。
33.7.2.6
LED閃爍函數(shù)
列表10:代碼清單38-8:LED閃爍函數(shù)
voidLED_Flicker(int num){/*LED1 閃爍‘num’次 */for (int i = 0; i < num*2; i++){LED1_TOGGLE;R_BSP_SoftwareDelay (50, BSP_DELAY_UNITS_MILLISECONDS);}}
下載驗(yàn)證
用Type-C線連接開(kāi)發(fā)板“USB TO UART”接口跟電腦,燒寫(xiě)代碼后,給開(kāi)發(fā)板重新供電,并打開(kāi)串口調(diào)試助手。紅色LED連續(xù)閃爍10次后,按下按鍵1,LED閃爍兩次,并進(jìn)入深度軟件待機(jī)模式。然后再按下按鈕2或1,紅色LED再次連續(xù)10次閃爍,并在串口調(diào)試助手中看見(jiàn)喚醒信息,說(shuō)明喚醒成功。

注:
深度軟件待機(jī)模式下也是無(wú)法燒寫(xiě)代碼的,可以參考上述方法燒寫(xiě)。
如您在使用瑞薩MCU/MPU產(chǎn)品中有任何問(wèn)題,可識(shí)別下方二維碼或復(fù)制網(wǎng)址到瀏覽器中打開(kāi),進(jìn)入瑞薩MCU/MPU官方技術(shù)論壇尋找答案或獲取在線技術(shù)支持。
https://bbs.21ic.com/renesas
未完待續(xù)
推薦閱讀
瑞薩RA6M5低功耗實(shí)戰(zhàn):睡眠+軟件待機(jī)模式——瑞薩RA系列FSP庫(kù)實(shí)戰(zhàn)指南(120)
四大法門(mén):瑞薩RA MCU如何助你降功耗——瑞薩RA系列FSP庫(kù)開(kāi)發(fā)實(shí)戰(zhàn)指南(119)
如何搞定FreeRTOS+TCP移植——瑞薩RA系列FSP庫(kù)開(kāi)發(fā)實(shí)戰(zhàn)指南(118)

