之前有很风行的游戏,名字叫《看门狗》。该游戏用了很新的引擎技能,打造出了一个广阔巨大的国际,内容是玩家Aiden·Pearce(主角)是一名通晓黑客技能的高手,其时的国际是处于一切物品都被置了电子设备操控,整个城市都在依靠着他们,主人公决议运用自己的技能为这个国际惩奸除恶。
这个游戏以极高的自由度、超卓的游戏质量与丰厚的游戏内容被业界公认为舱位次世代游戏的大门之作,该游戏被IGN评为年度最佳射击游戏(下载地址:http://down.ali213.net/pcgame/WatchDogs.html 有时机必定玩玩。)
二 开宗明义:
下面言归正传,在作业中用的STM32需求运用看门狗技能:
看门狗浅显解说:
单片机体系在外界的搅扰下会呈现程序跑飞的现象导致呈现死循环,看门狗电路便是为了防止这种状况的发生。看门狗的效果便是在必守时刻内(经过守时计数器完成)没有接纳喂狗信号(一共 MCU 现已挂了),便完成处理器的主动复位重启(发送复位信号)。
三 庐山面目:
STM32芯片一共有两个看门狗,一个是独立看门狗(IWDG),另一个是窗体看门狗(WWDG)
①先来讲讲独立看门狗:
STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即便主时钟发生毛病,它也依然
有用。这儿需求留意独立看门狗的时钟是一个内部 RC 时钟,所以并不是准确的 40Khz,而是
在 30~60Khz 之间的一个可改变的时钟,仅仅咱们在预算的时分,以 40Khz 的频率来核算,看
门狗对时刻的要求不是很准确,所以,时钟有些误差,都是能够承受的。
独立看门狗的装备作业代码:
1 void IWDG_Init(u8 prer,u16 rlr)2 {3 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //①使能对寄存器 I 写操作4 IWDG_SetPrescaler(prer); //②设置 IWDG 预分频值:设置 IWDG 预分频值5 IWDG_SetReload(rlr); //②设置 IWDG 重装载值6 IWDG_ReloadCounter(); //③依照 IWDG 重装载寄存器的值重装载 IWDG 计数器7 IWDG_Enable(); //④使能 IWDG8 }9 //喂独立看门狗10 void IWDG_Feed(void)11 {12 IWDG_ReloadCounter();//reload13 }
主逻辑区代码:
1 delay_init();//延时函数初始化2 NVIC_Configuration(); //设置 NVIC 中止分组 2:2 位抢占优先级,2 位呼应优先级3 KEY_Init(); //按键初始化4 IWDG_Init(4,625); //与分频数为 64,重载值为 625,溢出时刻为 1s5 while(1)6 {7 if(KEY_Scan(0)==KEY_UP)8 {9 IWDG_Feed(); //假如 按键按下,则喂狗10 }11 delay_ms(10);12 }
程序的功用便是经过按键翻开看门狗,当看门狗被触发之后碑文相应的操作。
②再来看看窗体看门狗
窗口看门狗(WWDG)通常被用来监测由外部搅扰或不行预见的逻辑条件形成的应用程序
违背正常的运转序列而发生的软件毛病。除非递减计数器的值在 T6 位(WWDG->CR 的第六位)
变成 0 前被改写,看门狗电路在到达预置的时刻周期时,会发生一个 MCU 复位。在递减计数
器到达窗口装备寄存器(WWDG->CFR)数值之前,假如 7 位的递减计数器数值(在操控寄存器中)
被改写, 那么也将发生一个 MCU 复位。这表明递减计数器需求在一个有限的时刻窗口中被刷
新。
看门狗时刻核算公式:
窗口看门狗的超时公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;
其间:
Twwdg:WWDG 超时时刻(单位为 ms)
Fpclk1:APB1 的时钟频率(单位为 Khz)
WDGTB:WWDG 的预分频系数
T[5:0]:窗口看门狗的计数器低 6 位
1 void WWDG_Init(u8 tr,u8 wr,u32 fprer)2 {3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能4 WWDG_CNT=tr&WWDG_CNT; //初始化 WWDG_CNT.5 WWDG_SetPrescaler(fprer); //设置 IWDG 预分频值6 WWDG_SetWindowValue(wr); //设置窗口值7 WWDG_Enable(WWDG_CNT);8 //使能看门狗,设置 counter9 WWDG_ClearFlag(); //铲除提早唤醒中止标志位10 WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC11 WWDG_EnableIT(); //舱位窗口看门狗中止12 }13 //重设置 WWDG 计数器的值14 void WWDG_Set_Counter(u8 cnt)15 {16 WWDG_Enable(cnt); //使能看门狗,设置 counter .17 }18 //窗口看门狗中止服务程序19 void WWDG_NVIC_Init()20 {21 NVIC_InitTypeDef NVIC_InitStructure;22 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中止23 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占 2 子优先级 3 组 224 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占 2,子优先级 3,组 225 NVIC_Init(&NVIC_InitStructure); //NVIC 初始化26 }27 void WWDG_IRQHandler(void)28 {29 WWDG_SetCounter(WWDG_CNT);30 //当禁掉此句后,窗口看门狗将发生复位31 WWDG_ClearFlag();32 //铲除提早唤醒中止标志位33 LED1=!LED1;34 //LED 状况翻转35 }
主逻辑区代码:
1 int main(void)2 {3 delay_init();//延时函数初始化4 NVIC_Configuration(); //设置 NVIC 中止分组 25 usart1_init();串口1初始化6 LED_Init(); //LED 初始化7 KEY_Init(); //按键初始化8 LED0=0;9 delay_ms(500);10 WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//计数器值为 7f,窗口寄存器为 5f,//分频数为 811 while(1)12 {13 LED0=1;14 }15 }
功用:
经过 LED0(DS0)来指示是否正在初始化。而 LED1(DS1)用来指示是否发生了中
断。咱们先让 LED0 亮 300ms,然后封闭以用于判别是否有复位发生了。在初始化 WWDG 之
后,咱们回到死循环,封闭 LED1,并等候看门狗中止的触发/复位。
四 泛泛而谈:
再来剖析一下独立看门狗(IWDG)和窗体看门狗(WWDG)的差异: