STM32 independent watchdog and low power mode _RTC wake up regularly to feed the dog

Independent watchdog (IWDG) and low-power mode are often used in STM32 development. The watchdog is designed to detect and resolve faults caused by software errors. The low-power mode is for entering when the CPU does not need to continue running. To sleep mode to save power. The independent watchdog clock is provided by an independent RC oscillator (typically 40kHz for STM32F10x) and is still valid even if the master clock fails. Therefore, it can operate in stop and standby modes. And once the independent watchdog starts, it cannot be stopped except for a system reset. However, a problem caused by this is that when the MCU enters the low-power mode, the dog cannot be fed due to the CPU stopping operation, which may cause the system to be frequently reset. How to solve this problem? Can independent watchdog and low-power mode be used together?

A good way is to feed the dog in sleep mode with the RTC wake-up at a regular time, feed it enough to continue entering sleep mode. For example, the watchdog reset interval is 10s. Then set the RTC alarm interrupt time to 5s before entering sleep mode. In this way, the dog is fed once every 5s. This can be a good solution to this problem.

While(1)

{

// Execute the task

Task1();

Task2();

//..

// feed the dog

Dev_iwdg_feed();

// Enter standby mode switch

If(m_bEnterStandByMode)

{

// Enable external interrupt, GPIOB3, to wake the MCU from standby mode

dev_exTI_enable(TRUE);

ENTERSTOPMODE:

// Set RTC alarm, generate RTC alarm interrupt in 5 seconds */

dev_rtc_setAlarm(5);

// Enter stop mode (low power consumption) until wake-up triggered by external interrupt

PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

// Whether it is an RTC alarm interrupt

If(dev_rtc_isAlarm())

{

// feed the dog

Dev_iwdg_feed();

// Feeding the dog continues into stop mode

Goto ENTERSTOPMODE;

}

// Disable external interrupts

dev_exTI_enable(FALSE);

// Resume system clock after wake-up from stop mode

Dev_clk_restore();

}

}

The following is a complete reference code:

//************************************************ **********************************************

// STM32F10x StopMode RTC Feed Dog

// compiler: Keil UV3

// 2013-01-04 , By friehood

//************************************************ **********************************************

#include "stm32f10x_lib.h"

#include "platform_config.h"

staTIc Boolean g_bRTCAlarm = FALSE;

/************************************************* ******************************

* FuncTIon Name : RCC_Configuration

* Description : Configures the different system clocks.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Void RCC_Configuration(void)

{

/* RCC system reset(for debug purpose) */

RCC_DeInit();

/* Enable HSE */

RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */

If(RCC_WaitForHSEStartUp() == SUCCESS)

{

/* Enable Prefetch Buffer */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

//Flash timing control

//Recommended value: SYSCLK = 0~24MHz Latency=0

// SYSCLK = 24~48MHz Latency=1

// SYSCLK = 48~72MHz Latency=2

//FLASH_SetLatency(FLASH_Latency_1); //Warning: Changing to 1 will have an effect on the DMA value (if the ADC acquisition value will be misaligned)

FLASH_SetLatency(FLASH_Latency_2);

/* HCLK = SYSCLK */

RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* PCLK2 = HCLK */

RCC_PCLK2Config(RCC_HCLK_Div1);

/* PCLK1 = HCLK/2 */

RCC_PCLK1Config(RCC_HCLK_Div2);

/* PLLCLK = 12MHz * 3 = 36 MHz */

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);

/* Enable PLL */

RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */

While(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}

/* Select PLL as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */

While(RCC_GetSYSCLKSource() != 0x08)

{

}

}

/* Enable PWR and BKP clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

/* Enable AFIO clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

}

/************************************************* ******************************

* Function Name : NVIC_Configuration

* Description : Configures the nested vectored interrupt controller.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else /* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

/* Configure one bit for preemption priority */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

}

/************************************************* ******************************

* Function Name : SysTick_Configuration

* Description : Configures the SysTick to generate an interrupt each 1 millisecond.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Void SysTick_Configuration(void)

{

/* Select AHB clock(HCLK) as SysTick clock source */

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

/* Set SysTick Priority to 3 */

NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 3, 0);

/* SysTick interrupt each 1ms with HCLK equal to 72MHz */

SysTick_SetReload(72000);

/* Enable the SysTick Interrupt */

SysTick_ITConfig(ENABLE);

}

/************************************************* ******************************

* Function Name : Delay

* Description : Inserts a delay time.

* Input : nTime: specifies the delay time length, in milliseconds.

* Output : None

* Return : None

************************************************** *****************************/

Void Delay(u32 nTime)

{

/* Enable the SysTick Counter */

SysTick_CounterCmd(SysTick_Counter_Enable);

TimingDelay = nTime;

While(TimingDelay != 0);

/* Disable the SysTick Counter */

SysTick_CounterCmd(SysTick_Counter_Disable);

/* Clear the SysTick Counter */

SysTick_CounterCmd(SysTick_Counter_Clear);

}

/************************************************* ******************************

* Function Name : RTC_Configuration

* Description : Configures RTC clock source and prescaler.

* Input : None

* Output : None

Void RTC_Configuration(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

/* RTC clock source configuration ------------------------------------------*/

/* Allow access to BKP Domain */

PWR_BackupAccessCmd(ENABLE);

/* Reset Backup Domain */

BKP_DeInit();

/* Enable the LSI OSC */

RCC_LSICmd(ENABLE);

/* Wait till LSI is ready */

While (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET){}

/* Select the RTC Clock Source */

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

/* Enable the RTC Clock */

RCC_RTCCLKCmd(ENABLE);

/* RTC configuration ---------------------------------------------- ---------*/

/* Wait for RTC APB registers synchronisation */

RTC_WaitForSynchro();

/* Set RTC prescaler: set RTC period to 1sec */

RTC_SetPrescaler(40000);

/* Wait until last write operation on RTC registers has finished */

RTC_WaitForLastTask();

/* Enable the RTC Alarm interrupt */

RTC_ITConfig(RTC_IT_ALR, ENABLE);

/* Wait until last write operation on RTC registers has finished */

RTC_WaitForLastTask();

/* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */

EXTI_ClearITPendingBit(EXTI_Line17);

EXTI_InitStructure.EXTI_Line = EXTI_Line17;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

/* Enable the RTC Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

/************************************************* ******************************

* Function Name : RTCAlarm_IRQHandler

* Description : This function handles RTC Alarm interrupt request.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Void RTCAlarm_IRQHandler(void)

{

If(RTC_GetITStatus(RTC_IT_ALR) != RESET)

{

/* Set the RTC alarm flag */

g_bRTCAlarm = TRUE;

/* Clear EXTI line17 pending bit */

EXTI_ClearITPendingBit(EXTI_Line17);

/* Check if the Wake-Up flag is set */

If(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)

{

/* Clear Wake Up flag */

PWR_ClearFlag(PWR_FLAG_WU);

}

/* Wait until last write operation on RTC registers has finished */

RTC_WaitForLastTask();

/* Clear RTC Alarm interrupt pending bit */

RTC_ClearITPendingBit(RTC_IT_ALR);

/* Wait until last write operation on RTC registers has finished */

RTC_WaitForLastTask();

}

}

/************************************************* ******************************

* Function Name : dev_rtc_setAlarm

* Description : Set RTC alarm.

* Input : Alarm time

* Output : None

* Return : None

************************************************** *****************************/

Void dev_rtc_setAlarm(u32 AlarmValue)

{

/* Clear the RTC SEC flag */

RTC_ClearFlag(RTC_FLAG_SEC);

/* Wait clear RTC flag sccess */

While(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);

/* Wait until last write operation on RTC registers has finished */

RTC_WaitForLastTask();

/* Sets the RTC alarm value */

RTC_SetAlarm(RTC_GetCounter() + AlarmValue);

/* Wait until last write operation on RTC registers has finished */

RTC_WaitForLastTask();

}

/************************************************* ******************************

* Function Name : dev_rtc_isAlarm

* Description : RTC alarm triggered

* Input : None

* Output : None

* Return : TRUE: triggered, FALSE, not triggered

************************************************** *****************************/

Boolean dev_rtc_isAlarm(void)

{

If(g_bRTCAlarm)

{

/* Clear the RTC alarm flag */

g_bRTCAlarm = FALSE;

Return TRUE;

}

Return FALSE;

}

Void dev_iwdg_init(void)

{

/* Enable write access to IWDG_PR and IWDG_RLR registers */

IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

/* IWDG counter clock: 40KHz(LSI) / 256 = 0.15625 KHz */

IWDG_SetPrescaler(IWDG_Prescaler_256);

/* Set counter reload value to 1562 */

IWDG_SetReload(1562); // 10s

/* Reload IWDG counter */

IWDG_ReloadCounter();

/* Enable IWDG (the LSI oscillator will be enabled by hardware) */

IWDG_Enable();

}

Void dev_iwdg_feed(void)

{

IWDG_ReloadCounter();

}

/************************************************* ******************************

* Function Name : dev_clk_restore

* Description : Restore system clock after wake-up from STOP: enable HSE, PLL

* and select PLL as system clock source.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Void dev_clk_restore(void)

{

/* Enable HSE */

RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */

HSEStartUpStatus = RCC_WaitForHSEStartUp();

If(HSEStartUpStatus == SUCCESS)

{

/* Enable PLL */

RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */

While(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}

/* Select PLL as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */

While(RCC_GetSYSCLKSource() != 0x08)

{

}

}

}

/************************************************* ******************************

* Function Name : EXTI_Configuration

* Description : Configures EXTI Line3.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Void EXIT_Configuration(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource3);

EXTI_ClearITPendingBit(EXTI_Line3);

EXTI_InitStructure.EXTI_Line = EXTI_Line3;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

}

Void dev_exti_enable(Boolean bEnable)

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Clear the Key Button EXTI line pending bit */

EXTI_ClearITPendingBit(EXTI_Line3);

NVIC_ClearIRQChannelPendingBit(EXTI3_IRQChannel);

NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = bEnable ? ENABLE : DISABLE;

NVIC_Init(&NVIC_InitStructure);

}

/************************************************* ******************************

* Function Name : main

* Description : Main program.

* Input : None

* Output : None

* Return : None

************************************************** *****************************/

Int main(void)

{

/* System Clocks Configuration */

RCC_Configuration();

/* NVIC configuration */

NVIC_Configuration();

/* Configure RTC clock source and prescaler */

RTC_Configuration();

/* Configure the SysTick to generate an interrupt each 1 millisecond */

SysTick_Configuration();

/* Configures EXTI Line3 */

EXIT_Configuration();

/* IWDG initialize*/

Dev_iwdg_init();

While(1)

{

// Execute the task

Task1();

Task2();

//. .

// feed the dog

Dev_iwdg_feed();

// Enter standby mode switch

If(m_bEnterStandByMode)

{

// Enable external interrupt, GPIOB3, to wake the MCU from standby mode

Dev_exti_enable(TRUE);

ENTERSTOPMODE:

// Set RTC alarm, generate RTC alarm interrupt in 5 seconds */

dev_rtc_setAlarm(5);

// Enter stop mode (low power consumption) until wake-up triggered by external interrupt

PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

// Whether it is an RTC alarm interrupt

If(dev_rtc_isAlarm())

{

// feed the dog

Dev_iwdg_feed();

// Feeding the dog continues into stop mode

Goto ENTERSTOPMODE;

}

// Disable external interrupts

Dev_exti_enable(FALSE);

// Resume system clock after wake-up from stop mode

Dev_clk_restore();

}

}

}

Oil Filter For PEUGEOT

Oil Filter For PEUGEOT

Peugeot Oil Filter Replacement,Oil Filter For Peugeot,Peugeot Car Oil Filter,Peugeot Auto Oil Filter

Zhoushan Shenying Filter Manufacture Co., Ltd. , https://www.renkenfilter.com

Posted on