久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5435|回復: 0
打印 上一主題 下一主題
收起左側

STM32 休眠模式下如何喂狗?

[復制鏈接]
跳轉到指定樓層
樓主
ID:105323 發表于 2016-3-4 17:51 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
       在STM32開發中經常會用到獨立看門狗(IWDG)和低功耗模式,看門狗是為了檢測和解決由軟件錯誤引起的故障,低功耗模式是為了在CPU不需要繼續運行時進入到休眠模式用以節省電能。其中獨立看門狗的時鐘由獨立的RC振蕩器(STM32F10x一般為40kHz)提供,即使在主時鐘出現故障時,也仍然有效,因此可以在停止和待機模式下工作。而且獨立看門狗一旦啟動,除了系統復位,它不能再被停止。但這樣引發的一個問題是當MCU進入到低功耗模式后由于CPU停止運行無法喂狗,會導致系統頻繁復位。那如何解決這個問題呢,難道獨立看門狗和低功耗模式沒法同時使用?

        一個很好的方式是在休眠模式下通過RTC定時喚醒來喂狗,喂完夠在進入繼續進入到休眠模式。比如看門狗復位的時間間隔為10s。那么在進入休眠模式前設置RTC鬧鐘中斷時間為5s。這樣每隔5s喚醒一次喂一次狗。便可以很好的解決這個問題。
  1.     while(1)  
  2.       {  
  3.         // 執行任務  
  4.         Task1();  
  5.         Task2();  
  6.         // ..  
  7.       
  8.         // 喂狗  
  9.         dev_iwdg_feed();  
  10.       
  11.         // 進入待機模式開關  
  12.         if(m_bEnterStandByMode)  
  13.         {     
  14.             // 使能外部中斷,GPIOB3,用以MCU從待機模式喚醒  
  15.             dev_exti_enable(TRUE);  
  16.     ENTERSTOPMODE:   
  17.             // 設置RTC鬧鐘,5秒鐘產生一次RTC鬧鐘中斷*/  
  18.             dev_rtc_setAlarm(5);  
  19.          
  20.             // 進入停止模式(低功耗),直至外部中斷觸發時被喚醒  
  21.             PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);  
  22.          
  23.             // 是否是RTC鬧鐘中斷喚醒  
  24.             if(dev_rtc_isAlarm())  
  25.             {  
  26.                 // 喂狗  
  27.                 dev_iwdg_feed();  
  28.                 // 喂完狗繼續進入停止模式  
  29.                 goto ENTERSTOPMODE;   
  30.             }  
  31.             // 禁止外部中斷   
  32.             dev_exti_enable(FALSE);  
  33.             // 從停止模式喚醒后恢復系統時鐘  
  34.             dev_clk_restore();  
  35.         }               
  36.       }  
復制代碼



以下是完整的參考代碼:
  1.     //**********************************************************************************************      
  2.     //  STM32F10x StopMode RTC Feed Dog   
  3.     //  compiler: Keil UV3      
  4.     //  2013-01-04 , By friehood      
  5.     //**********************************************************************************************   
  6.     #include "stm32f10x_lib.h"  
  7.     #include "platform_config.h"  
  8.     static Boolean g_bRTCAlarm = FALSE;  
  9.       
  10.     /*******************************************************************************  
  11.     * Function Name  : RCC_Configuration  
  12.     * Description    : Configures the different system clocks.  
  13.     * Input          : None  
  14.     * Output         : None  
  15.     * Return         : None  
  16.     *******************************************************************************/  
  17.     void RCC_Configuration(void)  
  18.     {  
  19.         /* RCC system reset(for debug purpose) */  
  20.         RCC_DeInit();  
  21.       
  22.         /* Enable HSE */  
  23.         RCC_HSEConfig(RCC_HSE_ON);  
  24.       
  25.         /* Wait till HSE is ready */  
  26.         if(RCC_WaitForHSEStartUp() == SUCCESS)  
  27.         {  
  28.             /* Enable Prefetch Buffer */  
  29.             FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
  30.       
  31.             //FLASH時序控制   
  32.             //推薦值:SYSCLK = 0~24MHz   Latency=0   
  33.             //        SYSCLK = 24~48MHz  Latency=1   
  34.             //        SYSCLK = 48~72MHz  Latency=2  
  35.             //FLASH_SetLatency(FLASH_Latency_1);        //警告:修改為1會對DMA值有影響(如ADC采集值會錯位)  
  36.             FLASH_SetLatency(FLASH_Latency_2);  
  37.       
  38.             /* HCLK = SYSCLK */  
  39.             RCC_HCLKConfig(RCC_SYSCLK_Div1);   
  40.       
  41.             /* PCLK2 = HCLK */  
  42.             RCC_PCLK2Config(RCC_HCLK_Div1);   
  43.       
  44.             /* PCLK1 = HCLK/2 */  
  45.             RCC_PCLK1Config(RCC_HCLK_Div2);  
  46.       
  47.             /* PLLCLK = 12MHz * 3 = 36 MHz */  
  48.             RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);  
  49.       
  50.             /* Enable PLL */   
  51.             RCC_PLLCmd(ENABLE);  
  52.       
  53.             /* Wait till PLL is ready */  
  54.             while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  
  55.             {  
  56.             }  
  57.       
  58.             /* Select PLL as system clock source */  
  59.             RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
  60.       
  61.             /* Wait till PLL is used as system clock source */  
  62.             while(RCC_GetSYSCLKSource() != 0x08)  
  63.             {  
  64.             }  
  65.         }  
  66.         /* Enable PWR and BKP clock */  
  67.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);  
  68.       
  69.         /* Enable AFIO clock */  
  70.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);  
  71.     }  
  72.       
  73.     /*******************************************************************************
  74.     * Function Name  : NVIC_Configuration
  75.     * Description    : Configures the nested vectored interrupt controller.
  76.     * Input          : None
  77.     * Output         : None
  78.     * Return         : None
  79.     *******************************************************************************/  
  80.     void NVIC_Configuration(void)  
  81.     {  
  82.       NVIC_InitTypeDef NVIC_InitStructure;  
  83.       
  84.     #ifdef  VECT_TAB_RAM  
  85.       /* Set the Vector Table base location at 0x20000000 */  
  86.       NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);  
  87.     #else  /* VECT_TAB_FLASH  */  
  88.       /* Set the Vector Table base location at 0x08000000 */  
  89.       NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
  90.     #endif  
  91.       
  92.       /* Configure one bit for preemption priority */  
  93.       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  94.     }  
  95.       
  96.     /*******************************************************************************
  97.     * Function Name  : SysTick_Configuration
  98.     * Description    : Configures the SysTick to generate an interrupt each 1 millisecond.
  99.     * Input          : None
  100.     * Output         : None
  101.     * Return         : None
  102.     *******************************************************************************/  
  103.     void SysTick_Configuration(void)  
  104.     {  
  105.       /* Select AHB clock(HCLK) as SysTick clock source */  
  106.       SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);  
  107.       
  108.       /* Set SysTick Priority to 3 */  
  109.       NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 3, 0);  
  110.          
  111.       /* SysTick interrupt each 1ms with HCLK equal to 72MHz */  
  112.       SysTick_SetReload(72000);  
  113.       
  114.       /* Enable the SysTick Interrupt */  
  115.       SysTick_ITConfig(ENABLE);  
  116.     }  
  117.       
  118.     /*******************************************************************************
  119.     * Function Name  : Delay
  120.     * Description    : Inserts a delay time.
  121.     * Input          : nTime: specifies the delay time length, in milliseconds.
  122.     * Output         : None
  123.     * Return         : None
  124.     *******************************************************************************/  
  125.     void Delay(u32 nTime)  
  126.     {  
  127.       /* Enable the SysTick Counter */  
  128.       SysTick_CounterCmd(SysTick_Counter_Enable);  
  129.         
  130.       TimingDelay = nTime;  
  131.       
  132.       while(TimingDelay != 0);  
  133.       
  134.       /* Disable the SysTick Counter */  
  135.       SysTick_CounterCmd(SysTick_Counter_Disable);  
  136.       /* Clear the SysTick Counter */  
  137.       SysTick_CounterCmd(SysTick_Counter_Clear);  
  138.     }  
  139.       
  140.       
  141.     /*******************************************************************************
  142.     * Function Name  : RTC_Configuration
  143.     * Description    : Configures RTC clock source and prescaler.
  144.     * Input          : None
  145.     * Output         : None
  146.     * Return         : None
  147.     *******************************************************************************/  
  148.     void RTC_Configuration(void)  
  149.     {  
  150.         EXTI_InitTypeDef EXTI_InitStructure;  
  151.         NVIC_InitTypeDef NVIC_InitStructure;  
  152.          
  153.         /* RTC clock source configuration ------------------------------------------*/  
  154.         /* Allow access to BKP Domain */  
  155.         PWR_BackupAccessCmd(ENABLE);  
  156.       
  157.         /* Reset Backup Domain */  
  158.         BKP_DeInit();  
  159.       
  160.         /* Enable the LSI OSC */  
  161.         RCC_LSICmd(ENABLE);  
  162.       
  163.         /* Wait till LSI is ready */  
  164.         while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET){}  
  165.          
  166.         /* Select the RTC Clock Source */  
  167.         RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);  
  168.       
  169.         /* Enable the RTC Clock */  
  170.         RCC_RTCCLKCmd(ENABLE);  
  171.       
  172.         /* RTC configuration -------------------------------------------------------*/  
  173.         /* Wait for RTC APB registers synchronisation */  
  174.         RTC_WaitForSynchro();  
  175.       
  176.         /* Set RTC prescaler: set RTC period to 1sec */  
  177.         RTC_SetPrescaler(40000);  
  178.          
  179.         /* Wait until last write operation on RTC registers has finished */  
  180.         RTC_WaitForLastTask();  
  181.       
  182.         /* Enable the RTC Alarm interrupt */  
  183.         RTC_ITConfig(RTC_IT_ALR, ENABLE);  
  184.          
  185.         /* Wait until last write operation on RTC registers has finished */  
  186.         RTC_WaitForLastTask();  
  187.       
  188.         /* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */  
  189.         EXTI_ClearITPendingBit(EXTI_Line17);  
  190.         EXTI_InitStructure.EXTI_Line = EXTI_Line17;  
  191.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
  192.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
  193.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
  194.         EXTI_Init(&EXTI_InitStructure);  
  195.       
  196.         /* Enable the RTC Interrupt */  
  197.         NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQChannel;  
  198.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  199.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  200.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  201.         NVIC_Init(&NVIC_InitStructure);  
  202.     }  
  203.       
  204.     /*******************************************************************************
  205.     * Function Name  : RTCAlarm_IRQHandler
  206.     * Description    : This function handles RTC Alarm interrupt request.
  207.     * Input          : None
  208.     * Output         : None
  209.     * Return         : None
  210.     *******************************************************************************/  
  211.     void RTCAlarm_IRQHandler(void)  
  212.     {  
  213.         if(RTC_GetITStatus(RTC_IT_ALR) != RESET)  
  214.         {  
  215.             /* Set the RTC alarm flag */  
  216.             g_bRTCAlarm = TRUE;  
  217.       
  218.             /* Clear EXTI line17 pending bit */  
  219.             EXTI_ClearITPendingBit(EXTI_Line17);  
  220.       
  221.             /* Check if the Wake-Up flag is set */  
  222.             if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)  
  223.             {  
  224.                 /* Clear Wake Up flag */  
  225.                 PWR_ClearFlag(PWR_FLAG_WU);  
  226.             }                                                                        
  227.                                                                
  228.             /* Wait until last write operation on RTC registers has finished */  
  229.             RTC_WaitForLastTask();     
  230.             /* Clear RTC Alarm interrupt pending bit */  
  231.             RTC_ClearITPendingBit(RTC_IT_ALR);  
  232.             /* Wait until last write operation on RTC registers has finished */  
  233.             RTC_WaitForLastTask();  
  234.         }  
  235.     }  
  236.       
  237.     /*******************************************************************************
  238.     * Function Name  : dev_rtc_setAlarm
  239.     * Description    : 設置RTC鬧鐘.
  240.     * Input          : 鬧鐘時間
  241.     * Output         : None
  242.     * Return         : None
  243.     *******************************************************************************/  
  244.     void dev_rtc_setAlarm(u32 AlarmValue)  
  245.     {  
  246.         /* Clear the RTC SEC flag */  
  247.         RTC_ClearFlag(RTC_FLAG_SEC);  
  248.         /* Wait clear RTC flag sccess */  
  249.         while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);  
  250.         /* Wait until last write operation on RTC registers has finished */  
  251.         RTC_WaitForLastTask();   
  252.       
  253.         /* Sets the RTC alarm value */  
  254.         RTC_SetAlarm(RTC_GetCounter() + AlarmValue);  
  255.         /* Wait until last write operation on RTC registers has finished */  
  256.         RTC_WaitForLastTask();   
  257.     }  
  258.       
  259.     /*******************************************************************************
  260.     * Function Name  : dev_rtc_isAlarm
  261.     * Description    : RTC鬧鐘是否觸發
  262.     * Input          : None
  263.     * Output         : None
  264.     * Return         : TRUE:已觸發,FALSE,未觸發
  265.     *******************************************************************************/  
  266.     Boolean dev_rtc_isAlarm(void)  
  267.     {  
  268.         if(g_bRTCAlarm)  
  269.         {  
  270.             /* Clear the RTC alarm flag */  
  271.             g_bRTCAlarm = FALSE;  
  272.             return TRUE;  
  273.         }  
  274.         return FALSE;            
  275.     }  
  276.       
  277.     void dev_iwdg_init(void)  
  278.     {  
  279.         /* Enable write access to IWDG_PR and IWDG_RLR registers */  
  280.         IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);  
  281.         /* IWDG counter clock: 40KHz(LSI) / 256 = 0.15625 KHz */  
  282.         IWDG_SetPrescaler(IWDG_Prescaler_256);  
  283.         /* Set counter reload value to 1562 */  
  284.         IWDG_SetReload(1562);   // 10s  
  285.         /* Reload IWDG counter */  
  286.         IWDG_ReloadCounter();  
  287.         /* Enable IWDG (the LSI oscillator will be enabled by hardware) */  
  288.         IWDG_Enable();  
  289.     }  
  290.       
  291.     void dev_iwdg_feed(void)  
  292.     {  
  293.         IWDG_ReloadCounter();  
  294.     }  
  295.       
  296.     /*******************************************************************************
  297.     * Function Name  : dev_clk_restore
  298.     * Description    : Restore system clock after wake-up from STOP: enable HSE, PLL
  299.     *                  and select PLL as system clock source.
  300.     * Input          : None
  301.     * Output         : None
  302.     * Return         : None
  303.     *******************************************************************************/  
  304.     void dev_clk_restore(void)  
  305.     {  
  306.       /* Enable HSE */  
  307.       RCC_HSEConfig(RCC_HSE_ON);  
  308.       
  309.       /* Wait till HSE is ready */  
  310.       HSEStartUpStatus = RCC_WaitForHSEStartUp();  
  311.       
  312.       if(HSEStartUpStatus == SUCCESS)  
  313.       {  
  314.         /* Enable PLL */   
  315.         RCC_PLLCmd(ENABLE);  
  316.       
  317.         /* Wait till PLL is ready */  
  318.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  
  319.         {  
  320.         }  
  321.       
  322.         /* Select PLL as system clock source */  
  323.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
  324.       
  325.         /* Wait till PLL is used as system clock source */  
  326.         while(RCC_GetSYSCLKSource() != 0x08)  
  327.         {  
  328.         }  
  329.       }  
  330.     }  
  331.       
  332.     /*******************************************************************************
  333.     * Function Name  : EXTI_Configuration
  334.     * Description    : Configures EXTI Line3.
  335.     * Input          : None
  336.     * Output         : None
  337.     * Return         : None
  338.     *******************************************************************************/  
  339.     void EXIT_Configuration(void)  
  340.     {  
  341.         EXTI_InitTypeDef EXTI_InitStructure;  
  342.       
  343.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource3);  
  344.         EXTI_ClearITPendingBit(EXTI_Line3);  
  345.         EXTI_InitStructure.EXTI_Line = EXTI_Line3;  
  346.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                                         
  347.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   
  348.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
  349.         EXTI_Init(&EXTI_InitStructure);  
  350.     }  
  351.       
  352.     void dev_exti_enable(Boolean bEnable)  
  353.     {  
  354.         NVIC_InitTypeDef NVIC_InitStructure;  
  355.       
  356.         /* Clear the Key Button EXTI line pending bit */  
  357.         EXTI_ClearITPendingBit(EXTI_Line3);  
  358.       
  359.         NVIC_ClearIRQChannelPendingBit(EXTI3_IRQChannel);  
  360.         NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel;  
  361.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  362.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  363.         NVIC_InitStructure.NVIC_IRQChannelCmd = bEnable ? ENABLE : DISABLE;  
  364.         NVIC_Init(&NVIC_InitStructure);   
  365.     }  
  366.       
  367.     /*******************************************************************************
  368.     * Function Name  : main
  369.     * Description    : Main program.
  370.     * Input          : None
  371.     * Output         : None
  372.     * Return         : None
  373.     *******************************************************************************/  
  374.     int main(void)  
  375.     {  
  376.       /* System Clocks Configuration */  
  377.       RCC_Configuration();  
  378.       
  379.       /* NVIC configuration */  
  380.       NVIC_Configuration();  
  381.       
  382.       /* Configure RTC clock source and prescaler */  
  383.       RTC_Configuration();  
  384.       
  385.       /* Configure the SysTick to generate an interrupt each 1 millisecond */  
  386.       SysTick_Configuration();  
  387.       
  388.       /* Configures EXTI Line3 */  
  389.       EXIT_Configuration();  
  390.       
  391.       /* IWDG initialize*/  
  392.       dev_iwdg_init();  
  393.       
  394.       while(1)  
  395.       {  
  396.         // 執行任務  
  397.         Task1();  
  398.         Task2();  
  399.         // ..  
  400.       
  401.         // 喂狗  
  402.         dev_iwdg_feed();  
  403.       
  404.         // 進入待機模式開關  
  405.         if(m_bEnterStandByMode)  
  406.         {     
  407.             // 使能外部中斷,GPIOB3,用以MCU從待機模式喚醒  
  408.             dev_exti_enable(TRUE);  
  409.     ENTERSTOPMODE:   
  410.             // 設置RTC鬧鐘,5秒鐘產生一次RTC鬧鐘中斷*/  
  411.             dev_rtc_setAlarm(5);  
  412.          
  413.             // 進入停止模式(低功耗),直至外部中斷觸發時被喚醒  
  414.             PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);  
  415.          
  416.             // 是否是RTC鬧鐘中斷喚醒  
  417.             if(dev_rtc_isAlarm())  
  418.             {  
  419.                 // 喂狗  
  420.                 dev_iwdg_feed();  
  421.                 // 喂完狗繼續進入停止模式  
  422.                 goto ENTERSTOPMODE;   
  423.             }  
  424.             // 禁止外部中斷   
  425.             dev_exti_enable(FALSE);  
  426.             // 從停止模式喚醒后恢復系統時鐘  
  427.             dev_clk_restore();  
  428.         }               
  429.       }  
  430.     }  
復制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩精品久久一区二区三区 | 999久久| 国产精品视频网 | 亚洲性在线 | 成人高清在线 | 一区二区在线免费播放 | 国产精品国产精品国产专区不片 | 一区二区三区免费 | 99精品一区 | 国产精品国产三级国产aⅴ原创 | 欧美日韩久久精品 | 成人精品一区二区三区 | 91精品国产高清一区二区三区 | 一本大道久久a久久精二百 欧洲一区二区三区 | 欧美综合在线视频 | av日韩精品 | 日韩电影一区二区三区 | 中文字幕一区二区三区四区不卡 | 欧美日韩不卡 | 欧美激情一区 | 欧美精品在线播放 | 中文字字幕在线中文乱码范文 | 91视频在线网站 | 久久久久久久久国产成人免费 | 午夜电影网站 | 欧美黑人国产人伦爽爽爽 | 午夜精品一区二区三区免费视频 | 日韩欧美中文字幕在线观看 | 国产999精品久久久久久 | 欧美成人手机视频 | 欧美视频免费 | 国产欧美日韩一区二区三区在线观看 | 性色综合 | 国产色片在线 | 久久久久久久久久久久91 | 精品一区二区在线视频 | 久久三级影院 | 国产精品久久久久久福利一牛影视 | 国产精品第2页 | 羞羞免费网站 | 久久美女网|