stm32 独立看门狗[操作寄存器+库函数]
- 000: 预分频因子=4 100: 预分频因子=64
- 001: 预分频因子=8 101: 预分频因子=128
- 010: 预分频因子=16 110: 预分频因子=256
- 011: 预分频因子=32 111: 预分频因子=256
重装载寄存器:(IWDG_RLR)
#include <stm32f10x_lib.h>
#include “system.h”
#include “wdg.h”
#define LED1 PAout(4)
#define LED2 PAout(5)
void Gpio_Init(void);
int main(void)
{
Rcc_Init(9); //系统时钟设置
Gpio_Init();
Iwdg_Init(3,1000); //设定为800ms内喂狗
while(1){
LED1 = !LED1;
delay(100000); //延时100ms后喂狗,LED闪烁
//delay(1000000); //延时1000ms,引发独立看门狗复位,LED不闪烁
Iwdg_Feed(); //喂狗
}
}
void Gpio_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0x0000FFFF; // PA0~3设置为浮空输入,PA4~7设置为推挽输出
GPIOA->CRL|=0x33334444;
}
#include <stm32f10x_lib.h>
#include “wdg.h”
/**
本文件包含窗口看门狗和独立看门口的相关函数
**/
u8 Wwdg_Cnt = 0x7F; //计数器值,默认为最大值127
//独立看门狗初始化
//参数说明:
// pre:分频数(0~7),相应分频因子为4(2^pre)
// rlr:低12位有[11:0]
// 喂狗时间计算: T = (4(2^pre)*rlr)/40;(ms)
void Iwdg_Init(u8 pre,u16 rlr)
{
IWDG ->KR = 0x5555; //使能对PR RLR寄存器的写操作
IWDG ->PR = pre; //设置分频数
IWDG ->RLR = rlr; //设定重装值
IWDG ->KR = 0xAAAA; //装载RLR值到看门狗计数器,即喂狗
IWDG ->KR = 0xCCCC; //启动看门狗
}
//独立看门狗喂狗
void Iwdg_Feed()
{
IWDG -> KR = 0xAAAA; //喂狗
}
//窗口看门狗初始化
//参数说明:
// cnt 计数器的值,最大 127,0x7F
// w_cnt 窗口值,最大 127,0x7F
// pre 预分频器的时基值,低两位有效;实际时钟为: PLCK1/4096/2^pre
//需要再主函数中开启中断 WWDG_IRQChannel
//设定喂狗时间范围必须在:(WWDG时钟为PCLK1,36Mhz)
// Tmax =(40962^pre(cnt-63)/36) (us)
// Tmin =(40962^pre(cnt-w_cnt)/36) (us)
//超出次时间喂狗复位
void Wwdg_Init(u8 cnt,u8 w_cnt,u8 pre)
{
u8 Cnt_Max = 0x7f; //计数器最大值
Wwdg_Cnt = Cnt_Max&cnt; //设定计数器的值,防止溢出
RCC->APB1ENR |= 1<<11;
WWDG -> CFR |= pre <<7; //设定预分频器的时基,实际分频值我
WWDG -> CFR |= 1<<9; //使能中断
WWDG -> CFR &= 0xFF80; //初始化低七位,即窗口值清0
WWDG -> CFR |= w_cnt; // 设定窗口值
WWDG -> CR |= Wwdg_Cnt|(1<<7); //设定计数器值,并激活开门狗
}
//窗口看门狗喂狗
void Wwdg_Feed()
{
WWDG->CR |= (Wwdg_Cnt&0x7F);
}
#include <stm32f10x_lib.h>
void Iwdg_Init(u8 pre,u16 rlr);
void Iwdg_Feed(void);
void Wwdg_Init(u8 cnt,u8 w_cnt,u8);
void Wwdg_Feed(void);
#include “stm32f10x.h”
#include “stdio.h”
#define PRINTF_ON 1
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART_Configuration(void);
void IWDG_Configuration(void);
void EXTI_Configuration(void);
vu32 DelayTime;
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART_Configuration();
EXTI_Configuration();
IWDG_Configuration();
while(1){
if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)
{
printf("\r\n The Stm32 has been reset by IWDG .\r\n");
RCC_ClearFlag();
}
//do sth. here
DelayTime = 100000;
while(--DelayTime);
// 延时17ms
IWDG_ReloadCounter(); //80ms不喂狗复位
GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)(1- GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_4)));
}
}
void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA , &GPIO_InitStructure);
}
void IWDG_Configuration(void)
{
RCC_LSICmd(ENABLE); //打开LSI
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET);
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_32);
IWDG_SetReload(100); //80ms ,max 0xFFF 0~4095
IWDG_ReloadCounter();
IWDG_Enable();
}
void RCC_Configuration(void)
{
/ 定义枚举类型变量 HSEStartUpStatus /
ErrorStatus HSEStartUpStatus;
/* 复位系统时钟设置*/
RCC_DeInit();
/* 开启HSE*/
RCC_HSEConfig(RCC_HSE_ON);
/* 等待HSE起振并稳定*/
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/* 判断HSE起是否振成功,是则进入if()内部 */
if(HSEStartUpStatus == SUCCESS)
{
/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* 设置FLASH延时周期数为2 */
FLASH_SetLatency(FLASH_Latency_2);
/* 使能FLASH预取缓存 */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* 使能PLL */
RCC_PLLCmd(ENABLE);
/* 等待PLL输出稳定 */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
/* 选择SYSCLK时钟源为PLL */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* 等待PLL成为SYSCLK时钟源 */
while(RCC_GetSYSCLKSource() != 0x08);
}
/* 打开APB2总线上的GPIOA时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG, ENABLE);
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
USART_ClockInit(USART1 , &USART_ClockInitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
#if PRINTF_ON
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(u8) ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
return ch;
}
#endif