2012-02-02 09:07 AM
I need a ''watchdog timer'' that automatically sets a port pin when it times out and not reset the processor. I don't think the IWDG or WWDG do this since they just reset the processor on time-out.
Therefore, I think the use of a timer such as TIM4 is needed to do this. I have TIM4_CH2 going to Pin PD13 (remapped). I want TIM4_CH2 to remain low as long as TIM4 remains not timed-out, which can be done by resetting the timer often enough during runtime using the ''UG'' bit. However, when it does time out, the output signal starts putting out repetitive pulses. Alternatively, I can set it to ''one pulse'' mode and it puts out a single pulse (low to high then back low), but this seems to require an additional reset step to re-enable the timer after setting the UG bit. Is there a way to cause the time out condition to cause the output signal (TIM4_CH2) to just transition from low to high and just stay high?2012-02-03 06:48 AM
1) I hope the use of ''watchdog'' is erroneous, anything that can be stopped by runaway code is not a ''watchdog''
2) why noy just do it in an ISR? Erik2012-02-03 10:15 AM
>1) I hope the use of ''watchdog'' is erroneous, anything that can be stopped by runaway code is not a ''watchdog''
Well, technically not a watchdog (that's why its in quotes). The idea is to have two processors working together and running the same program. If one fails or s/w crashes, its ''watchdog'' timer times out and sets and output that interrupts (ideally NMI) the other processor. Granted there are holes in this scheme: TIM4 might get disabled by errant code, no external NMI pin on STM32 that I can find, etc.>2) why not just do it in an ISR?
Do you mean let TIM4 generate that interrupt and then in the ISR set the output pin? Others here have ''specified'' that the hardware should directly set the output pin to interrupt the other processor.2012-02-03 12:26 PM
2012-02-03 12:54 PM
Well you could certainly achieve this with OCMode Toggle, with a stupidly long time base.
With a prescale and period of 65535, on a 168MHz STM32F4, one could get out close to 25 seconds before it wraps. The timeout could be set to occur anywhere between 0 and 25 seconds. You can get it low initially, and then program the channel CCR 5 or 10 seconds into the future. Resetting should be a matter of pulling CNT back. Now, sure it will toggle low again if left alone, but if you can't cause a reset/interrupt with a 1+ second width pulse then you'd need to reassess the problem.2012-02-03 04:26 PM
>Well you could certainly achieve this with OCMode Toggle, with a stupidly long time base.
>With a prescale and period of 65535, on a 168MHz STM32F4, one could get out close to 25 seconds before it wraps. The timeout could be set to occur anywhere between 0 and 25 seconds. Set prescale to 10000, ARR to 65535 and with CCR at 72 (with TIMXCLK at 72e6) my watchdog timeout is 10ms and when it times out I see a 10 second high pulse. So it seems to work exactly as you describe. >You can get it low initially, and then program the channel CCR 5 or 10 seconds into the future. Resetting should be a matter of pulling CNT back. I set CCR 10ms ''into the future''. Just writing CNT to 0 stops the timer so have to also set CEN bit in CR1 too. Is there a way to avoid having to re-enable the timer? >Now, sure it will toggle low again if left alone, but if you can't cause a reset/interrupt with a 1+ second width pulse then you'd need to reassess the problem. Can't argue with that!2013-07-17 11:08 PM
In WWDG i m not getting set time value is there i miss something using default reset i am getting 4 sec time(i.e 40h reset)
this is my code. my calculated pclk1 clock is 281 khz but i m not getting it. void RCC_Configuration(void) { /* RCC system reset(for debug purpose) */ RCC_DeInit(); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div2); //AHB//AHB clock = SYSCLK /* PCLK2 = HCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); //APB2 clock = HCLK /* PCLK1 = HCLK/2 */ RCC_PCLK1Config(RCC_HCLK_Div16);//APB1 clock = HCLK /* PLLCLK = 8MHz * 9 = 72 MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* 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); void init_watchdog(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); WWDG_SetPrescaler(WWDG_Prescaler_8); // WWDG_SetWindowValue(65);//the window value to be compared to the downcounter WWDG_Enable(127); } void main void { while(1) { WWDG_SetCounter(127);//Refill watchdog counter } }