/**----------------------------------------------------------------------------- * @brief Initialisation du watchdog Windows. * * param[in] Timeout_ms Duree du timeout watchdog en ms. */ void WDG_InitWWDG(uint16_t Timeout_ms){ RCC_ClocksTypeDef xRCC_Clocks; uint32_t ulClock_kHz; WWDG_DeInit(); // Initialisation des variables WWDG_Reload = Timeout_ms; WWDG_Cnt = Timeout_ms; // Activation horloges RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // Configuration interruption WWDG_EnableIT(); #ifdef configLIBRARY_KERNEL_INTERRUPT_PRIORITY NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); #else NVIC_EnableIRQ(WWDG_IRQn); #endif // Configuration timeout WWDG_SetPrescaler(WWDG_Prescaler_8); WWDG_SetWindowValue(0x7F); // Activation WWDG_Enable(0x7F); WDG_Refresh(); }
static void wd_reset(void) { // Init WD if(!wd_init_enabled) { // Start watchdog WWDG_Enable(WD_REFRESH_COUNTER); // Reset wd_init_enabled = 1; TimingDelay = 0; return; } // 40mS flag for WD reset if(TimingDelay > 40) { TimingDelay = 0; //GREEN_LED_PIO->ODR ^= RED_LED; // Update WWDG counter WWDG_SetCounter(WD_REFRESH_COUNTER); } }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* Initialize LED1 and Key Button mounted on STM3210X-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_EXTI); /* Check if the system has resumed from WWDG reset */ if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set */ /* Turn on LED1 */ STM_EVAL_LEDOn(LED1); /* Clear reset flags */ RCC_ClearFlag(); } else { /* WWDGRST flag is not set */ /* Turn off LED1 */ STM_EVAL_LEDOff(LED1); } /* NVIC configuration */ NVIC_Configuration(); /* WWDG configuration */ /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* On Value line devices, WWDG clock counter = (PCLK1 (24MHz)/4096)/8 = 732 Hz (~1366 æs) */ /* On other devices, WWDG clock counter = (PCLK1(36MHz)/4096)/8 = 1099 Hz (~910 æs) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 65 */ WWDG_SetWindowValue(65); /* On Value line devices, Enable WWDG and set counter value to 127, WWDG timeout = ~1366 æs * 64 = 87.42 ms */ /* On other devices, Enable WWDG and set counter value to 127, WWDG timeout = ~910 æs * 64 = 58.25 ms */ WWDG_Enable(127); /* Clear EWI flag */ WWDG_ClearFlag(); /* Enable EW interrupt */ WWDG_EnableIT(); while (1) { } }
void PhotonWdgs::begin(bool _enableWwdg,bool _enableIwdg,unsigned long _timeout, TIMid id) { if(!_enableWwdg && !_enableIwdg) { // nothing to do ... return; } PhotonWdgs::_aliveCount = 0; PhotonWdgs::_timeoutval = _timeout / 10; RCC_LSICmd(ENABLE); //LSI is needed for Watchdogs PhotonWdgs::_wdgTimer.begin(PhotonWdgs::_tickleWDGs, 20, hmSec, id); // OTA updates won't work with watchdog enabled System.disableUpdates(); PhotonWdgs::_wwdgRunning = _enableWwdg; if(_enableWwdg) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); WWDG_SetPrescaler(WWDG_Prescaler_8); WWDG_SetWindowValue(0x7F); WWDG_Enable(0x7F); } PhotonWdgs::_iwdgRunning = _enableIwdg; if(_enableIwdg) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_256); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetReload(0xFFF); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_Enable(); } }
/************************************************************* * WWDT Initialization **************************************************************/ void WWDG_Init() { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // Deinitializes WWDG peripheral registers #if(STRCMP($ResetEn$, DISABLE) == 0) WWDG_DeInit(); #endif // Sets Prescaler value of the WWDG. WWDG_SetPrescaler($PreValue$); // Sets Window value of the WWDG. WWDG_SetWindowValue($WindowValue$); // Sets Counter value of the WWDG. WWDG_SetCounter($CounterValue$); // Enable WWDG and set counter value WWDG_Enable($CounterValue$); //Enable EW interrupt #if((STRCMP($IntEn$,DISABLE)) == 0) WWDG_ClearFlag(); WWDG_EnableIT(); #endif }
THD_FUNCTION(Thread0, arg) { (void)arg; if (RCC->CSR & RCC_CSR_WWDGRSTF) { /* WWDGRST flag set */ serDbg("\r\n**WWDG Reset!**\r\n\r\n"); /* Clear reset flags */ RCC->CSR |= RCC_CSR_RMVF; } /* WWDG clock counter = (PCLK1 (48MHz)/4096)/8 = 1464Hz (~683 us) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 126; WWDG counter should be refreshed only when the counter is below 126 (and greater than 64) otherwise a reset will be generated */ WWDG_SetWindowValue(126); /* Freeze WWDG while core is stopped */ DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_WWDG_STOP; /* Enable WWDG and set counter value to 127, WWDG timeout = ~683 us * 64 = 43.7 ms In this case the refresh window is: ~683 * (127-126)= 0.683ms < refresh window < ~683 * 64 = 43.7ms */ WWDG_Enable(127); serDbg("WWDG Started\r\n"); while (true) { chThdSleepMilliseconds(25); palTogglePad(GPIOC, GPIOC_LED3); /* Watchdog heartbeat */ WWDG_SetCounter(127); } }
/* ********************************************************************************************************* * 函 数 名: bsp_InitWwdg * 功能说明: 初始化窗口看门狗。 * 形 参: * 返 回 值: 无 ********************************************************************************************************* */ static void bsp_InitWwdg(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 打开窗口看门狗时钟,APB1低速时钟36MHz*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG , ENABLE); /* 使能看门狗中断 */ NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 10; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 设置窗口看门狗时钟为 WWDG_CLK = (PCLK1 (36MHz)/4096)/8 = 1152 Hz (~868 us), 最大超时时间: 780 * 64 = 58.25ms */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* 设置窗口看门狗窗口上限, 计数器小于0x50时,才能重装载计数器 */ /* Enable WWDG and set counter value to 127。In this case the refresh window is: WWDG_FRQ = 1/WWDG_CLK; ~WWDG_FRQ * (WWDG_RELOAD_VALUE-WWDG_RELOAD_WTIME_VALUE) < refresh window < ~WWDG_FRQ * (WWDG_RELOAD_VALUE-0x3F) */ WWDG_SetWindowValue(WWDG_RELOAD_WTIME_VALUE); /* 使能窗口看门狗计数器,并设置计数初值为0x7F */ WWDG_Enable(WWDG_RELOAD_VALUE); /* 清除窗口看门狗标志 */ WWDG_ClearFlag(); /* 使能窗口看门狗中断 */ WWDG_EnableIT(); /* 置位窗口看门口标志 */ WWDG_EN_MARK = 1; }
void WWDG_Configuration(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); WWDG_SetPrescaler(WWDG_Prescaler_8); // WWDG clock counter = (PCLK1/4096)/8 = 244 Hz (~4 ms) WWDG_SetWindowValue(0x41); // Set Window value to 0x41 WWDG_Enable(0x50); // Enable WWDG and set counter value to 0x7F, WWDG timeout = ~4 ms * 64 = 262 ms WWDG_ClearFlag(); // Clear EWI flag WWDG_EnableIT(); // Enable EW interrupt }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /* Setup the microcontroller system. Initialize the Embedded Flash Interface, initialize the PLL and update the SystemFrequency variable. */ SystemInit(); /* Initialize LED1 and Key Button mounted on STM3210X-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_PBInit(Button_KEY, Mode_EXTI); /* Check if the system has resumed from WWDG reset */ if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set */ /* Turn on LED1 */ STM_EVAL_LEDOn(LED1); /* Clear reset flags */ RCC_ClearFlag(); } else { /* WWDGRST flag is not set */ /* Turn off LED1 */ STM_EVAL_LEDOff(LED1); } /* NVIC configuration */ NVIC_Configuration(); /* WWDG configuration */ /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* WWDG clock counter = (PCLK1/4096)/8 = 1099 Hz (~910 µs) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 65 */ WWDG_SetWindowValue(65); /* Enable WWDG and set counter value to 127, WWDG timeout = ~910 µs * 64 = 58.25 ms */ WWDG_Enable(127); /* Clear EWI flag */ WWDG_ClearFlag(); /* Enable EW interrupt */ WWDG_EnableIT(); while (1) { } }
static void s_hal_watchdog_window_start(hal_watchdog_internal_item_t *intitem) { // NVIC_InitTypeDef NVIC_InitStructure; // do something using s_hal_watchdog_theinternals.items[0].countdown etc. // acemor on 21oct11: taken from STM32F10x_StdPeriph_Lib_V3.2.0\Project\STM32F10x_StdPeriph_Examples\WWDG // // 1. init nvic // /* 1 bits for pre-emption priority and 3 bits for subpriority */ //// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // //// NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0,0)); // // /* Set WWDG interrupt vector Preemption Priority to 1 */ // NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // 1b. wwdg clock /* WWDG configuration */ /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // 2. set prescaler /* On other devices, WWDG clock counter = (PCLK1(36MHz)/4096)/8 = 1099 Hz (909.918 us) */ WWDG_SetPrescaler(WWDG_Prescaler_8); // 3. set window /* Set Window value to 65 */ WWDG_SetWindowValue(intitem->reload); //WWDG_SetWindowValue(65); // 4. set counter value and clear /* On Value line devices, Enable WWDG and set counter value to 127, WWDG timeout = ~1366 æs * 64 = 87.42 ms */ /* On other devices, Enable WWDG and set counter value to 127, WWDG timeout = ~910 æs * 64 = 58.25 ms */ WWDG_Enable(intitem->reload); /* Clear EWI flag */ WWDG_ClearFlag(); // 5. enable interrupt if(hal_int_priorityNONE != intitem->cfg.priority) { // enable irqs in nvic hal_sys_irqn_priority_set(WWDG_IRQn, intitem->cfg.priority); hal_sys_irqn_enable(WWDG_IRQn); /* Enable EW interrupt */ WWDG_EnableIT(); } }
/******************************************************************************* * Function Name : main * Description : Main program. * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { #ifdef DEBUG debug(); #endif /* System Clocks Configuration */ RCC_Configuration(); /* GPIO configuration */ GPIO_Configuration(); /* Check if the system has resumed from WWDG reset */ if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set */ /* Set GPIO_LED pin 6 */ GPIO_SetBits(GPIO_LED, GPIO_Pin_6); /* Clear reset flags */ RCC_ClearFlag(); } else { /* WWDGRST flag is not set */ /* Reset GPIO_LED pin 6 */ GPIO_ResetBits(GPIO_LED, GPIO_Pin_6); } /* Configure Key Button EXTI Line to generate an interrupt on falling edge */ EXTI_Configuration(); /* NVIC configuration */ NVIC_Configuration(); /* WWDG configuration */ /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* WWDG clock counter = (PCLK1/4096)/8 = 244 Hz (~4 ms) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 65 */ WWDG_SetWindowValue(65); /* Enable WWDG and set counter value to 127, WWDG timeout = ~4 ms * 64 = 262 ms */ WWDG_Enable(127); /* Clear EWI flag */ WWDG_ClearFlag(); /* Enable EW interrupt */ WWDG_EnableIT(); while (1) {} }
/** * @brief 初始化窗口看门狗 * @param tr :T[6:0],计数器值 , wr :W[6:0],窗口值 @param fprer:分频系数(WDGTB),仅最低2位有效 , Fwwdg=PCLK1/(4096*2^fprer). * @retval None */ void WWDG_Init(u8 tr, u8 wr, u32 fprer) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能 WWDG_CNT = tr & WWDG_CNT; //初始化WWDG_CNT. WWDG_SetPrescaler(fprer);////设置IWDG预分频值 WWDG_SetWindowValue(wr);//设置窗口值 WWDG_Enable(WWDG_CNT); //使能看门狗 , 设置 counter . WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_NVIC_Init();//初始化窗口看门狗 NVIC WWDG_EnableIT(); //开启窗口看门狗中断 }
/******************************************************************************* * Function Name : FLASH_DisableWriteProtectionPages * Description : Disable the write protection of desired pages * Input : None * Output : None * Return : None *******************************************************************************/ void FLASH_DisableWriteProtectionPages(void) { u32 useroptionbyte = 0, WRPR = 0; u16 var1 = OB_IWDG_SW, var2 = OB_STOP_NoRST, var3 = OB_STDBY_NoRST; FLASH_Status status = FLASH_BUSY; WRPR = FLASH_GetWriteProtectionOptionByte(); /* Test if user memory is write protected */ if ((WRPR & UserMemoryMask) != UserMemoryMask){ useroptionbyte = FLASH_GetUserOptionByte(); UserMemoryMask |= WRPR; status = FLASH_EraseOptionBytes(); if(UserMemoryMask != 0xFFFFFFFF){ status = FLASH_EnableWriteProtection((u32)~UserMemoryMask); } /* Test if user Option Bytes are programmed */ if((useroptionbyte & 0x07) != 0x07){ /* Restore user Option Bytes */ if((useroptionbyte & 0x01) == 0x0){ var1 = OB_IWDG_HW; } if((useroptionbyte & 0x02) == 0x0){ var2 = OB_STOP_RST; } if((useroptionbyte & 0x04) == 0x0){ var3 = OB_STDBY_RST; } FLASH_UserOptionByteConfig(var1, var2, var3); } if (status == FLASH_COMPLETE){ SerialPutString("Write Protection disabled...\r\n"); SerialPutString("...and a System Reset will be generated to re-load the new option bytes\r\n"); /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* Generate a system Reset to re-load the new option bytes: enable WWDG and set counter value to 0x4F, as T6 bit is cleared this will generate a WWDG reset */ WWDG_Enable(0x4F); }else{ SerialPutString("Error: Flash write unprotection failed...\r\n"); } }else{ SerialPutString("Flash memory not write protected\r\n"); } }
/* ********************************************************************************************************* * 函 数 名: bsp_InitWwdg * 功能说明: 窗口看门狗配置 * 形 参: * _ucTreg : T[6:0],计数器值 范围0x40 到 0x7F * _ucWreg : W[6:0],窗口值 必须小于 0x80 * WWDG_Prescaler : 窗口看门狗分频 PCLK1 = 42MHz * WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 * WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 * WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 * WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_InitWwdg(uint8_t _ucTreg, uint8_t _ucWreg, uint32_t WWDG_Prescaler) { NVIC_InitTypeDef NVIC_InitStructure; /* 检测系统是否从窗口看门狗复位中恢复 */ if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* 清除复位标志 */ RCC_ClearFlag(); } else { /* WWDGRST 标志没有设置 */ } /* 使能WWDG时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* 窗口看门狗分频设置: 比如选择WWDG_Prescaler_8 (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us) */ WWDG_SetPrescaler(WWDG_Prescaler); /* 设置窗口值是_ucWreg,用户必须在小于_ucWreg且大于0x40时刷新计数 器,要不会造成系统复位。 */ WWDG_SetWindowValue(_ucWreg); /* 使能WWDG,设置计数器 比如设置_ucTreg=127 8分频时,那么溢出时间就是= ~780 us * 64 = 49.92 ms 窗口看门狗的刷新时间段是: ~780 * (127-80) = 36.6ms < 刷新窗口看门狗 < ~780 * 64 = 49.9ms */ WWDG_Enable(_ucTreg); /* 清除EWI中断标志 */ WWDG_ClearFlag(); /* 使能EW中断 */ WWDG_EnableIT(); /* 设置 WWDG 的NVIC */ NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
void main(void) #endif { /* Enables the HSI clock for PORTB */ RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTB, ENABLE); /* Configure all unused PORT pins to low power consumption */ PORT_StructInit(&PORT_InitStructure); PORT_InitStructure.PORT_Pin = (PORT_Pin_All & ~(PORT_Pin_0)); PORT_Init(MDR_PORTB, &PORT_InitStructure); /* Configure PORTB pin 10 for output to switch LEDs on/off */ PORT_InitStructure.PORT_Pin = PORT_Pin_0; PORT_InitStructure.PORT_OE = PORT_OE_OUT; PORT_InitStructure.PORT_FUNC = PORT_FUNC_PORT; PORT_InitStructure.PORT_MODE = PORT_MODE_DIGITAL; PORT_InitStructure.PORT_SPEED = PORT_SPEED_SLOW; PORT_Init(MDR_PORTB, &PORT_InitStructure); /* Enables the HSI clock for WWDG */ RST_CLK_PCLKcmd(RST_CLK_PCLK_WWDG,ENABLE); NVIC_EnableIRQ(WWDG_IRQn); /* Set WWDG Prescaler value*/ WWDG_SetPrescaler (WWDG_Prescaler_8); /* Enable WWDG and load start counter value*/ WWDG_Enable(0x7F); /* Enables the WWDG Early Wakeup interrupt */ WWDG_EnableIT(); /* Infinite loop */ for(NumBlink = 0; NumBlink < 15;) { if (wwdg_flag == SET) { BlinkLED1(1,30000); wwdg_flag = RESET; } } LEDOn(LED1); NVIC_DisableIRQ(WWDG_IRQn); while(1); }
/** * @brief WWDG configuration * @param None * @retval None */ static void WWDG_Config(void) { /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* WWDG clock counter = (PCLK1 (48MHz)/4096)/8 = 1464Hz (~683 us) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 80; WWDG counter should be refreshed only when the counter is below 80 (and greater than 64) otherwise a reset will be generated */ WWDG_SetWindowValue(80); /* Enable WWDG and set counter value to 127, WWDG timeout = ~683 us * 64 = 43.7 ms In this case the refresh window is: ~683 * (127-80)= 32.1ms < refresh window < ~683 * 64 = 43.7ms */ WWDG_Enable(127); }
void Wwdg_irq_test(void) { NVIC_InitTypeDef NVIC_InitStructure; unsigned short value = 0; NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); uart_printf("RCC->CSR=0x%x\r\n",RCC->CSR); WWDG_EnableIT(); WWDG_Enable(0x66); }
void Wwdg_reset_test(void) { unsigned short value = 0; RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); uart_printf("RCC->CSR=0x%x\r\n",RCC->CSR); uart_printf("WWDG->CR=0x%x\r\n",WWDG->CR); uart_printf("WWDG->CFR=0x%x\r\n",WWDG->CFR); uart_printf("WWDG->SR=0x%x\r\n",WWDG->SR); uart_printf("IWDG->PR=0x%x\r\n",IWDG->PR); uart_printf("IWDG->RLR=0x%x\r\n",IWDG->RLR); uart_printf("IWDG->SR=0x%x\r\n",IWDG->SR); WWDG_Enable(0x66); value = WWDG->CR; uart_printf("WWDG->CR=0x%x\r\n",WWDG->CR); uart_printf("RCC1->CSR=0x%x\r\n",RCC->CSR); uart_printf("RCC2->CSR=0x%x\r\n",RCC->CSR); }
//初始化窗口看门狗 //tr :T[6:0],计数器值 //wr :W[6:0],窗口值 //fprer:分频系数(WDGTB),仅最低2位有效 //Fwwdg=PCLK1/(4096*2^fprer). 一般PCLK1=42Mhz void WWDG_Init(u8 tr,u8 wr,u32 fprer) { NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟 WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT. WWDG_SetPrescaler(fprer); //设置分频值 WWDG_SetWindowValue(wr); //设置窗口值 WWDG_Enable(WWDG_CNT); //开启看门狗 NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x03; //抢占优先级为2 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级为3 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗 NVIC_Init(&NVIC_InitStructure); WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_EnableIT();//开启提前唤醒中断 }
/** * @brief Processes data transfers after a TFTP write request * @param _args: used as pointer on TFTP connection args * @param upcb: pointer on udp_pcb structure * @param pkt_buf: pointer on a pbuf stucture * @param ip_addr: pointer on the receive IP_address structure * @param port: receive port address * @retval none */ static void IAP_wrq_recv_callback(void *_args, struct udp_pcb *upcb, struct pbuf *pkt_buf, struct ip_addr *addr, u16_t port) { tftp_connection_args *args = (tftp_connection_args *)_args; uint32_t data_buffer[128]; char message[20]; u16 count=0; if (pkt_buf->len != pkt_buf->tot_len) { return; } /* Does this packet have any valid data to write? */ if ((pkt_buf->len > TFTP_DATA_PKT_HDR_LEN) && (IAP_tftp_extract_block(pkt_buf->payload) == (args->block + 1))) { /* copy packet payload to data_buffer */ pbuf_copy_partial(pkt_buf, data_buffer, pkt_buf->len - TFTP_DATA_PKT_HDR_LEN, TFTP_DATA_PKT_HDR_LEN); total_count += pkt_buf->len - TFTP_DATA_PKT_HDR_LEN; count = (pkt_buf->len - TFTP_DATA_PKT_HDR_LEN)/4; if (((pkt_buf->len - TFTP_DATA_PKT_HDR_LEN)%4)!=0) count++; /* Write received data in Flash */ FLASH_If_Write(&Flash_Write_Address, data_buffer ,count); /* update our block number to match the block number just received */ args->block++; /* update total bytes */ (args->tot_bytes) += (pkt_buf->len - TFTP_DATA_PKT_HDR_LEN); /* This is a valid pkt but it has no data. This would occur if the file being written is an exact multiple of 512 bytes. In this case, the args->block value must still be updated, but we can skip everything else. */ } else if (IAP_tftp_extract_block(pkt_buf->payload) == (args->block + 1)) { /* update our block number to match the block number just received */ args->block++; } /* Send the appropriate ACK pkt*/ IAP_tftp_send_ack_packet(upcb, addr, port, args->block); /* If the last write returned less than the maximum TFTP data pkt length, * then we've received the whole file and so we can quit (this is how TFTP * signals the EndTransferof a transfer!) */ if (pkt_buf->len < TFTP_DATA_PKT_LEN_MAX) { IAP_tftp_cleanup_wr(upcb, args); pbuf_free(pkt_buf); #ifdef USE_LCD LCD_SetTextColor(White); LCD_DisplayStringLine(Line5, (char*)"Tot bytes Received:"); sprintf(message, "%u bytes ",total_count); LCD_DisplayStringLine(Line6, (uint8_t*)message); LCD_SetTextColor(Red); LCD_DisplayStringLine(Line9, (char*)"State: Prog Finished "); #endif BKP_WriteBackupRegister(BKP_DR11,0); /* generate a watchdog reset */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //SerialPutString("\r\nENABLE WTD! \n"); WWDG_Enable(0x40); while(1); } else { pbuf_free(pkt_buf); return; } }
/** * @brief Main program. * @param None * @retval None */ void WWDG_Example(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f30x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f30x.c file */ /* Initialize LEDs and Key Button mounted on STM32303C-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_EXTI); /* Check if the system has resumed from WWDG reset */ if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set */ /* Turn on LED1 */ STM_EVAL_LEDOn(LED1); /* Clear reset flags */ RCC_ClearFlag(); } else { /* WWDGRST flag is not set */ /* Turn off LED1 */ STM_EVAL_LEDOff(LED1); } /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(SystemCoreClock / 1000)) { /* Capture error */ while (1) {} } /* WWDG configuration */ /* Enable WWDG clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); /* WWDG clock counter = (PCLK1 (36MHz)/4096)/8 = 1098Hz (~910 us) */ WWDG_SetPrescaler(WWDG_Prescaler_8); /* Set Window value to 80; WWDG counter should be refreshed only when the counter is below 80 (and greater than 64) otherwise a reset will be generated */ WWDG_SetWindowValue(80); /* Enable WWDG and set counter value to 127, WWDG timeout = ~910 us * 64 = 58.24 ms In this case the refresh window is: ~910 * (127-80) = 42.7ms < refresh window < ~910 * 64 = 58.2ms */ WWDG_Enable(127); while (1) { /* Toggle LED2 */ STM_EVAL_LEDToggle(LED2); /* Insert 43 ms delay */ Delay(43); /* Update WWDG counter */ WWDG_SetCounter(127); } }
//重设置WWDG计数器的值 void WWDG_Set_Counter(u8 cnt) { WWDG_Enable(cnt);//使能看门狗 , 设置 counter . }
void WWDG_init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); WWDG_SetPrescaler(WWDG_Prescaler_8); /* WWDG clock counter = (PCLK1/4096)/8 = 244 Hz (~4 ms) */ WWDG_SetWindowValue(0x41); WWDG_Enable(0x7F); /* Enable WWDG and set counter value to 0x7F, WWDG timeout = ~4 ms * 64 = 262 ms */ }
//重设置WWDG计数器的值 void WWDG_Set_Counter(u8 cnt) { WWDG_Enable(cnt); }