本帖最后由 Peixu 于 2024-1-29 18:04 编辑
关闭全局中断 & RTC计时中断试验。
在MCU微控制器的应用中,全局中断的管理是一项至关重要的任务。全局中断是一种机制,它允许或禁止所有中断的触发,是确保关键代码段原子性执行的重要手段。在一些实时系统中,时钟和定时功能的正常运行对于整个系统的稳定性和准确性至关重要。
本文将验证在使用APM32F103时全局中断的开启或关闭会不会影响RTC(Real-Time Clock)计时中断的正常运行,将MCU进入低功耗模式,然后配置3秒钟的RTC闹钟来进行唤醒。
1. MCU初始化和系统配置
在开始任何应用程序时,首先需要进行GPIO、低功耗、RTC库的初始化以及系统时钟的配置。这确保了后续的代码能够正常的运行。
<article data-content="[{"type":"block","id":"hfRN-1706518417671","name":"code","data":{"version":1,"language":"c","theme":"default"},"nodes":[{"type":"block","id":"1uB9-1706518417666","name":"code-line","data":{},"nodes":[{"type":"text","id":"0A3X-1706518417665","leaves":[{"text":" int main(void)\r","marks":[]}]}]},{"type":"block","id":"5eSY-1706520578387","name":"code-line","data":{},"nodes":[{"type":"text","id":"fc0W-1706520578386","leaves":[{"text":"{ ","marks":[]}]}]},{"type":"block","id":"A7R4-1706520575090","name":"code-line","data":{},"nodes":[{"type":"text","id":"6gq7-1706520575089","leaves":[{"text":" RCM_EnableAPB1PeriphClock((RCM_APB1_PERIPH_T)(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR));\r \r","marks":[]}]}]},{"type":"block","id":"Mjop-1706520267405","name":"code-line","data":{},"nodes":[{"type":"text","id":"GlWx-1706520267404","leaves":[{"text":" APM_MINI_PBInit(BUTTON_KEY1, BUTTON_MODE_EINT);//按下KEY1进入低功耗\r\r\r \r","marks":[]}]}]},{"type":"block","id":"Wipa-1706520267421","name":"code-line","data":{},"nodes":[{"type":"text","id":"L7rr-1706520267420","leaves":[{"text":" PMU_EnableBackupAccess();\r \r","marks":[]}]}]},{"type":"block","id":"0BFg-1706520267425","name":"code-line","data":{},"nodes":[{"type":"text","id":"DJwz-1706520267424","leaves":[{"text":" RTC_Init();\r \r","marks":[]}]}]},{"type":"block","id":"PLcY-1706520267429","name":"code-line","data":{},"nodes":[{"type":"text","id":"SkE7-1706520267428","leaves":[{"text":" SysTick_Init();","marks":[]}]}]}],"state":{}}]"><div yne-bulb-block="code" data-theme="default" style="white-space-collapse: preserve;" data-language="c"> int main(void)
{
RCM_EnableAPB1PeriphClock((RCM_APB1_PERIPH_T)(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR));
APM_MINI_PBInit(BUTTON_KEY1, BUTTON_MODE_EINT);//按下KEY1进入低功耗
PMU_EnableBackupAccess();
RTC_Init();
SysTick_Init();</div></article>
2. RTC模块初始化和配置
RTC是用于实时时钟的模块,用于处理时间和日期的相关功能。在系统中配置RTC并设置RTC闹钟,以便在特定时间触发中断。
<article data-content="[{"type":"block","id":"kbHQ-1706518417680","name":"code","data":{"version":1,"language":"c","theme":"default"},"nodes":[{"type":"block","id":"EdJz-1706518417677","name":"code-line","data":{},"nodes":[{"type":"text","id":"oATG-1706518417676","leaves":[{"text":"void RTC_Init(void)\r","marks":[]}]}]},{"type":"block","id":"OF3g-1706520619943","name":"code-line","data":{},"nodes":[{"type":"text","id":"zYLX-1706520619942","leaves":[{"text":"{\r","marks":[]}]}]},{"type":"block","id":"9Ulb-1706520619965","name":"code-line","data":{},"nodes":[{"type":"text","id":"JTPs-1706520619964","leaves":[{"text":" BAKPR_Reset();\r\r","marks":[]}]}]},{"type":"block","id":"rYcd-1706520619969","name":"code-line","data":{},"nodes":[{"type":"text","id":"XY3j-1706520619968","leaves":[{"text":" RCM_ConfigLSE(RCM_LSE_OPEN);\r","marks":[]}]}]},{"type":"block","id":"xMBE-1706520619971","name":"code-line","data":{},"nodes":[{"type":"text","id":"TeGe-1706520619970","leaves":[{"text":" while(RCM_ReadStatusFlag(RCM_FLAG_LSERDY) == RESET);\r","marks":[]}]}]},{"type":"block","id":"PFCz-1706520619973","name":"code-line","data":{},"nodes":[{"type":"text","id":"Em1O-1706520619972","leaves":[{"text":" RCM_ConfigRTCCLK(RCM_RTCCLK_LSE);\r","marks":[]}]}]},{"type":"block","id":"MXe1-1706520619975","name":"code-line","data":{},"nodes":[{"type":"text","id":"j9ku-1706520619974","leaves":[{"text":" RCM_EnableRTCCLK();\r\r","marks":[]}]}]},{"type":"block","id":"CcHv-1706520619979","name":"code-line","data":{},"nodes":[{"type":"text","id":"n9hA-1706520619978","leaves":[{"text":" RTC_WaitForSynchro();\r","marks":[]}]}]},{"type":"block","id":"HsZN-1706520619981","name":"code-line","data":{},"nodes":[{"type":"text","id":"5vlk-1706520619980","leaves":[{"text":" RTC_ConfigPrescaler(32767);\r","marks":[]}]}]},{"type":"block","id":"TNgq-1706520619983","name":"code-line","data":{},"nodes":[{"type":"text","id":"nXJN-1706520619982","leaves":[{"text":" RTC_WaitForLastTask();\r","marks":[]}]}]},{"type":"block","id":"KkRl-1706520733991","name":"code-line","data":{},"nodes":[{"type":"text","id":"I94P-1706520733990","leaves":[{"text":" \r","marks":[]}]}]},{"type":"block","id":"opy0-1706520619989","name":"code-line","data":{},"nodes":[{"type":"text","id":"Rimq-1706520619988","leaves":[{"text":" EINT_Config_T EINT_configStruct;\r\r","marks":[]}]}]},{"type":"block","id":"cZCf-1706520620024","name":"code-line","data":{},"nodes":[{"type":"text","id":"i7gq-1706520620023","leaves":[{"text":" /* Configure Button EINT line */\r","marks":[]}]}]},{"type":"block","id":"y900-1706520620026","name":"code-line","data":{},"nodes":[{"type":"text","id":"EWPs-1706520620025","leaves":[{"text":" EINT_configStruct.line = EINT_LINE_0;\r","marks":[]}]}]},{"type":"block","id":"eyd9-1706520620028","name":"code-line","data":{},"nodes":[{"type":"text","id":"bfH5-1706520620027","leaves":[{"text":" EINT_configStruct.mode = EINT_MODE_INTERRUPT;//此示例中,把PA0 EINT0配置为中断\r","marks":[]}]}]},{"type":"block","id":"iHrQ-1706520620030","name":"code-line","data":{},"nodes":[{"type":"text","id":"gjFk-1706520620029","leaves":[{"text":" EINT_configStruct.trigger = EINT_TRIGGER_FALLING;//注意需要是此处需要 FALLING\r","marks":[]}]}]},{"type":"block","id":"K3k7-1706520620032","name":"code-line","data":{},"nodes":[{"type":"text","id":"TnDX-1706520620031","leaves":[{"text":" EINT_configStruct.lineCmd = ENABLE;\r","marks":[]}]}]},{"type":"block","id":"1cEQ-1706520620034","name":"code-line","data":{},"nodes":[{"type":"text","id":"WqS0-1706520620033","leaves":[{"text":" EINT_Config(&EINT_configStruct);\r","marks":[]}]}]},{"type":"block","id":"EsSi-1706520620036","name":"code-line","data":{},"nodes":[{"type":"text","id":"1ObH-1706520620035","leaves":[{"text":" \r","marks":[]}]}]},{"type":"block","id":"1yEz-1706520620038","name":"code-line","data":{},"nodes":[{"type":"text","id":"nJh9-1706520620037","leaves":[{"text":" /* Configure Button EINT line */\r","marks":[]}]}]},{"type":"block","id":"DMny-1706520620040","name":"code-line","data":{},"nodes":[{"type":"text","id":"Ir3h-1706520620039","leaves":[{"text":" EINT_configStruct.line = EINT_LINE_17;//RTC Alarm唤醒. 需要开启EINT17\r","marks":[]}]}]},{"type":"block","id":"vFJt-1706520620042","name":"code-line","data":{},"nodes":[{"type":"text","id":"Y7wg-1706520620041","leaves":[{"text":" EINT_configStruct.mode = EINT_MODE_INTERRUPT;//中断\r","marks":[]}]}]},{"type":"block","id":"tvgu-1706520620044","name":"code-line","data":{},"nodes":[{"type":"text","id":"JTQx-1706520620043","leaves":[{"text":" EINT_configStruct.trigger = EINT_TRIGGER_RISING;\r","marks":[]}]}]},{"type":"block","id":"6ish-1706520620046","name":"code-line","data":{},"nodes":[{"type":"text","id":"wfWr-1706520620045","leaves":[{"text":" EINT_configStruct.lineCmd = ENABLE;\r","marks":[]}]}]},{"type":"block","id":"koxx-1706520620048","name":"code-line","data":{},"nodes":[{"type":"text","id":"myJy-1706520620047","leaves":[{"text":" EINT_Config(&EINT_configStruct);\r","marks":[]}]}]},{"type":"block","id":"EYRd-1706520620050","name":"code-line","data":{},"nodes":[{"type":"text","id":"C69Q-1706520620049","leaves":[{"text":" \r","marks":[]}]}]},{"type":"block","id":"AjTt-1706520620052","name":"code-line","data":{},"nodes":[{"type":"text","id":"XL2y-1706520620051","leaves":[{"text":" NVIC_SetPriority(EINT0_IRQn, 0X02);\r\r","marks":[]}]}]},{"type":"block","id":"fn8E-1706520620060","name":"code-line","data":{},"nodes":[{"type":"text","id":"H8eh-1706520620059","leaves":[{"text":" }\r","marks":[]}]}]},{"type":"block","id":"QaBJ-1706520620062","name":"code-line","data":{},"nodes":[{"type":"text","id":"YVOy-1706520620061","leaves":[{"text":"}","marks":[]}]}]}],"state":{}}]"><div yne-bulb-block="code" data-theme="default" style="white-space-collapse: preserve;" data-language="c">void RTC_Init(void)
{
BAKPR_Reset();
RCM_ConfigLSE(RCM_LSE_OPEN);
while(RCM_ReadStatusFlag(RCM_FLAG_LSERDY) == RESET);
RCM_ConfigRTCCLK(RCM_RTCCLK_LSE);
RCM_EnableRTCCLK();
RTC_WaitForSynchro();
RTC_ConfigPrescaler(32767);
RTC_WaitForLastTask();
EINT_Config_T EINT_configStruct;
/* Configure Button EINT line */
EINT_configStruct.line = EINT_LINE_0;
EINT_configStruct.mode = EINT_MODE_INTERRUPT;//此示例中,把PA0 EINT0配置为中断
EINT_configStruct.trigger = EINT_TRIGGER_FALLING;//注意需要是此处需要 FALLING
EINT_configStruct.lineCmd = ENABLE;
EINT_Config(&EINT_configStruct);
/* Configure Button EINT line */
EINT_configStruct.line = EINT_LINE_17;//RTC Alarm唤醒. 需要开启EINT17
EINT_configStruct.mode = EINT_MODE_INTERRUPT;//中断
EINT_configStruct.trigger = EINT_TRIGGER_RISING;
EINT_configStruct.lineCmd = ENABLE;
EINT_Config(&EINT_configStruct);
NVIC_SetPriority(EINT0_IRQn, 0X02);
}
}</div></article>
3. 低功耗种加入全局中断的禁用和启用
在进入低功耗前使用__disable_irq()函数禁用全局中断
<article data-content="[{"type":"block","id":"S0YB-1706518417798","name":"code","data":{"version":1,"language":"c","theme":"default"},"nodes":[{"type":"block","id":"G088-1706518417783","name":"code-line","data":{},"nodes":[{"type":"text","id":"l4dr-1706518417782","leaves":[{"text":" if(LPW_Flag==1)\r","marks":[]}]}]},{"type":"block","id":"ugr4-1706521446445","name":"code-line","data":{},"nodes":[{"type":"text","id":"mwZL-1706521446444","leaves":[{"text":" { \r","marks":[]}]}]},{"type":"block","id":"ys36-1706521446447","name":"code-line","data":{},"nodes":[{"type":"text","id":"isJ5-1706521446446","leaves":[{"text":" RTC_ClearStatusFlag(RTC_FLAG_SEC); \r","marks":[]}]}]},{"type":"block","id":"oK3R-1706521446449","name":"code-line","data":{},"nodes":[{"type":"text","id":"rcHa-1706521446448","leaves":[{"text":" while(RTC_ReadStatusFlag(RTC_FLAG_SEC) == RESET); \r","marks":[]}]}]},{"type":"block","id":"MoQA-1706521446451","name":"code-line","data":{},"nodes":[{"type":"text","id":"oTwW-1706521446450","leaves":[{"text":" \r","marks":[]}]}]},{"type":"block","id":"SfYa-1706521446453","name":"code-line","data":{},"nodes":[{"type":"text","id":"nLGQ-1706521446452","leaves":[{"text":" RTC_ConfigAlarm(RTC_ReadCounter()+ 3); //此处配置的\"3秒\"闹钟有设置误差, 可理解为\"一段时间\"后有RTC闹钟唤醒就好 \r","marks":[]}]}]},{"type":"block","id":"B80x-1706521446455","name":"code-line","data":{},"nodes":[{"type":"text","id":"3ZLK-1706521446454","leaves":[{"text":" RTC_WaitForLastTask();","marks":[]}]}]},{"type":"block","id":"aC0y-1706521840726","name":"code-line","data":{},"nodes":[{"type":"text","id":"pW2R-1706521840725","leaves":[{"text":" ","marks":[]}]}]},{"type":"block","id":"ltoB-1706521547498","name":"code-line","data":{},"nodes":[{"type":"text","id":"2n7G-1706521547496","leaves":[{"text":" __disable_irq();","marks":[]}]}]},{"type":"block","id":"lqfz-1706521838151","name":"code-line","data":{},"nodes":[{"type":"text","id":"i035-1706521838150","leaves":[{"text":" // 在这里执行关键代码,确保不被其他中断打断","marks":[]}]}]},{"type":"block","id":"w4Fg-1706521838940","name":"code-line","data":{},"nodes":[{"type":"text","id":"suQO-1706521838939","leaves":[{"text":" ","marks":[]}]}]},{"type":"block","id":"zogn-1706518417791","name":"code-line","data":{},"nodes":[{"type":"text","id":"Ux6c-1706518417790","leaves":[{"text":" PMU_EnableWakeUpPin();\r","marks":[]}]}]},{"type":"block","id":"iUFt-1706521421403","name":"code-line","data":{},"nodes":[{"type":"text","id":"SOkL-1706521421402","leaves":[{"text":" PMU_EnterSTANDBYMode();","marks":[]}]}]},{"type":"block","id":"d2eS-1706518417797","name":"code-line","data":{},"nodes":[{"type":"text","id":"xhVA-1706518417796","leaves":[{"text":"}","marks":[]}]}]}],"state":{}}]"><div yne-bulb-block="code" data-theme="default" style="white-space-collapse: preserve;" data-language="c"> if(LPW_Flag==1)
{
RTC_ClearStatusFlag(RTC_FLAG_SEC);
while(RTC_ReadStatusFlag(RTC_FLAG_SEC) == RESET);
RTC_ConfigAlarm(RTC_ReadCounter()+ 3); //此处配置的"3秒"闹钟有设置误差, 可理解为"一段时间"后有RTC闹钟唤醒就好
RTC_WaitForLastTask();
__disable_irq();
// 在这里执行关键代码,确保不被其他中断打断
PMU_EnableWakeUpPin();
PMU_EnterSTANDBYMode();
}</div></article>
通过以上步骤,当进入低功耗模式前__disable_irq()函数禁用全局中断, 仍然不会影响RTC的使用,由于RTC计时中断是由RTC模块内部产生和触发的,与全局中断的状态无关。
|
|