int main(void)
{
......
......
/* Enable write access to IWDG_PR and IWDG_RLR registers */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//写使能
/* IWDG counter clock: 32KHz(LSI) / 32 = 1KHz */
IWDG_SetPrescaler(IWDG_Prescaler_32);
/* Set counter reload value to 349 */
IWDG_SetReload(349);
/* Reload IWDG counter */
IWDG_ReloadCounter();
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
IWDG_Enable();//LSI时钟被强制打开
while(1)
{
......
......
}
}
循环语句里面没有IWDG_ReloadCounter()来喂狗,为何不能溢出重启呢?
STM32固件库中的例子可以用吗?
你是如何判断STM32没有重启呢?
没有开发板,固件库的例子没有试过!
设置独立就这么几个过程,文档都是这么写的,不明白,这还有什么猫腻。
stm32溢出复位了的话,程序从头开始,在程序初期有串口数据输出指明的!
没有开发板,那你是如何执行程序的?
没有什么猫腻,例子写出来就是作为参考。例子已经过验证,在任何有问题的时候可以用它检验你的环境是否有问题。
我的产品都出来了!
我产品都出来了,就差加个看门狗了,大哥,能不能阐述下独立看门狗使用原理?
固件库比较
我比较了下固件库里面的程序,启动看门就是最上面的几条语句!
独立看门狗的计数时钟用的就是LSI,与其它时钟应该没有关系吧?
独立看门狗使用原理很简单
LSI通过一个预分频器,然后驱动一个递减计数器,递减计数器由一个重加载寄存器不断地刷新。如果长时间不重新加载该递减计数器,当递减计数器减为0时,独立看门狗将产生一个复位信号,在RCC_CSR寄存器中有个标志位指示是否产生IWDG复位。
请问与keil集成开发环境下载程序有关否?
明白了你说得原理,我也是这样理解的啊,可是为什么它就不行呢,其它程序照样运行正常,我不喂狗,程序还是一如既往的运行,也不复位重来。
我也遇到同样问题
请有经验的关注一下吧。
STM32的问题实在没有地方可以问,或者问了却得不到实质的帮助,一个问题卡好长时间。从这一点上将ZLG所能做到的非其他人所能比。
有感而发。
我碰到的问题是:
用ST例程,关于WDG的试验。
可以进看门狗溢出中断的,但是如果禁止中断,死等不喂狗的话也不能复位,不知为什么???有哪位指点一下喽。谢谢
请问你做的是哪一个WDG的例程?
STM32有2个WDG,但这2个都没有看门狗溢出中断,是不是搞错了?
请看
/*******************************************************************************
* Function Name : WWDG_IRQHandler
* Description : This function handles WWDG interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void WWDG_IRQHandler(void)
{
/* Update WWDG counter */
WWDG_SetCounter(0x7F);
/* Clear EWI flag */
WWDG_ClearFlag();
}
这不是看门狗溢出中断,这是早期唤醒中断
STM32的窗口看门狗中有一个7位的递减计数器,它会在出现下述2种情况之一时产生看门狗复位:
1)当计数器的数值从0x40减到0x3F时
2)当刷新看门狗时计数器的数值大于某一设定数值时,此设定数值在WWDG_CFR寄存器定义。
为了让用户程序在看门狗复位前有最后一次机会喂狗,STM32的窗口看门狗还设置了一个早期唤醒中断,当计数器的数值从0x41减到0x40时产生这个早期唤醒中断。12楼给出的程序段正是这个中断的处理。
至于12楼提到的“死等不喂狗的话也不能复位”,是因为你根本就没有使能看门狗。芯片复位后WWDG默认是关闭的。
16.3 IWDG functional description
请13楼的朋友看看STM32的技术参考手册:
这个你关心的部分:
16.3 IWDG functional description
Figure 154 shows the functional blocks of the independent Watchdog module. When the independent watchdog is started by writing the value 0xCCCC in the Key register (IWDG_KR), the counter starts counting down from the reset value of 0xFFF. When it reaches the end of count value (0x000) a reset signal is generated (IWDG reset).
Whenever the key value 0xAAAA is written in the IWDG_KR register, the IWDG_RLR value is reloaded in the counter and the watchdog reset is prevented.
16.3.1 Hardware watchdog
If the “Hardware watchdog” feature is enabled through the device option bits, the watchdog is automatically enabled at power-on, and will generate a reset unless the Key register is written by the software before the counter reaches end of count.
16.3.2 Register access protection
Write access to the IWDG_PR and IWDG_RLR registers is protected. To modify them, you must first write the code 0x5555 in the IWDG_KR register. A write access to this register with a different value will break the sequence and register access will be protected again.
This implies that it is the case of the reload operation (writing 0xAAAA). A status register is available to indicate that an update of the prescaler or the down-counter reload value is on going.
单独让stm32跑 不复位
RCC_ClearFlag();
/* 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(0x41);
/* Enable WWDG and set counter value to 127, WWDG timeout = ~4 ms * 64 = 262 ms */
WWDG_Enable(0x7F);
/* Clear EWI flag */
WWDG_ClearFlag();
/* Enable EW interrupt */
WWDG_EnableIT(); //注释掉这一行 看门狗不能自动复位
while (1);
----------------------------------------------------
void WWDG_IRQHandler(void)
{
/* Update WWDG counter */
// WWDG_SetCounter(0x7F); //注释掉这一行 看门狗不能自动复位
/* Clear EWI flag */
WWDG_ClearFlag();
}
你把我搞糊涂了,你的问题是能产生复位还是不能产生复位
到底是中断的问题还是复位的问题?
另外,这个帖子楼主在问IWDG的问题,但你好像在说WWDG?
实现WDG功能时请尽量不要在Debug环境下
在Debug环境下实现WDG,会因为挂起了core而产生以下非逻辑的错误,另外判断是否复位一定要准确,因为不加延时的情况下,WDG两次复位的时间间隔很短,容易造成误判。
不好意思,我咨询的是WDG不能产生复位
用例程能进入中断,但是无论禁止中断还是
在中断中不更新初值
都不能产生控制器的复位!!
我没有在DEBUG状态。
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : main.c
* Author : MCD Application Team
* Version : V2.0.1
* Date : 06/13/2008
* Description : Main program body.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "platform_config.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ErrorStatus HSEStartUpStatus;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void Delay(vu32 nCount);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* 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(GPIOB,GPIO_Pin_5|GPIO_Pin_8); //LED ON
/* Clear reset flags */
RCC_ClearFlag();
}
else
{ /* WWDGRST flag is not set */
/* Reset GPIO_LED pin 6 */
GPIO_ResetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_8); //LED OFF
}
/* NVIC configuration */
NVIC_Configuration();
GPIO_ResetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_8); //LED OFF
Delay(700000);
GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_8); //LED ON
Delay(700000);
GPIO_ResetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_8); //LED OFF
Delay(700000);
GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_8); //LED ON
Delay(700000);
/* 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(); //注释这里不能造成STM32复位
while (1)
{}
}
/*******************************************************************************
* 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 */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 0 wait state */
FLASH_SetLatency(FLASH_Latency_0);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK */
RCC_PCLK1Config(RCC_HCLK_Div1);
/* Select HSE as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
/* Wait till HSE is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x04)
{}
}
/* GPIOA, GPIOB and SPI1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_SPI1, ENABLE);
}
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*led*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures NVIC and Vector Table base location.
* 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
/* 2 bits for Preemption Priority and 2 bits for Sub Priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* Function Name : Delay
* Description : Inserts a delay time.
* Input : nCount: specifies the delay time length.
* Output : None
* Return : None
*******************************************************************************/
void Delay(vu32 nCount)
{
for (; nCount != 0; nCount--);
}
#ifdef DEBUG
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* Input : - file: pointer to the source file name
* - line: assert_param error line source number
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d
", file, line) */
/* Infinite loop */
while (1)
{}
}
#endif
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
/*******************************************************************************
* Function Name : WWDG_IRQHandler
* Description : This function handles WWDG interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void WWDG_IRQHandler(void)
{
/* Update WWDG counter */
WWDG_SetCounter(0x7F); //注释这里不能造成STM32复位!!!!
/* Clear EWI flag */
WWDG_ClearFlag();
}