1. 实验目的
通过按键 KEY0 来喂狗,然后通过 DS1 提示复位状态。如果不喂狗的话,灯DS1就会闪烁,也就是程序一直在复位状态;如果按键按下,则是喂狗状态,灯DS1就会一直亮,不会闪烁。
2. 实验准备和流程
独立看门狗的时间以32KHZ来计。
Tout=((4×2^prer) ×rlr) /32,其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值),范围为 0~7;rlr 为看门狗的重装载值(IWDG_RLR 的值);根据下面的程序设置,看门狗的溢出时间就是,(4*16)*500/32 = 1000ms = 1s
具体的流程如下:
初始化看门狗;
初始化LED和按键;
编写main函数。
2.1 初始化看门狗
void IWDG_Init(void){
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //取消写保护
IWDG_SetPrescaler(4); //预分频系数
IWDG_SetReload(500); //设置重装载值
IWDG_ReloadCounter(); //把rlr的初值加载到定时器
IWDG_Enable(); //使能看门狗
}
2.2 初始化LED和按键
//初始化按键
void KEY_GPIO_Config(void)
{
//初始化结构体 GPIO_InitStruct(取的一个随机的名字)
//里面是GPIO的速度,上下拉,输出类型
GPIO_InitTypeDef GPIO_InitStruct;
//打开时钟(一般开时钟要放到前面的位置,然后再是设置上拉,输出这些)
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
//驱动是哪个引脚 PE4
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
//输入
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
//上拉
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;//看标准库函数里面找的
//输入的速度 输入没有速度之说
//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
//变量获取它的指针,取地址就行(&)
GPIO_Init(GPIOE,&GPIO_InitStruct);
}
//检测按键扫描,哪个GPIO口,哪个引脚,扫描的是哪个端口
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
//检测电平的函数 bit是位的意思,读这个位是0还是1,就是这个位是高电平还是低电平
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == 0){
//松手检测
while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == 0){};//按下了一直在这里循环,当松手以后就会往下执行
return 0;
}
else return 1;
}
//初始化LED
void LED_GPIO_Config(void)
{
//初始化结构体 GPIO_InitStruct(取的一个随机的名字)
//里面是GPIO的速度,上下拉,输出类型
GPIO_InitTypeDef GPIO_InitStruct;
//打开时钟(一般开时钟要放到前面的位置,然后再是设置上拉,输出这些)
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE); //使能时钟必须放到前面,不然后面的操作不会使灯点亮
//驱动是哪个引脚 PF9
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
//推挽输出
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
//上拉
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP ;
//输出的速度
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
//变量获取它的指针,取地址就行(&)
GPIO_Init(GPIOF,&GPIO_InitStruct);
GPIO_SetBits(GPIOF,GPIO_Pin_10);//GPIOF10设置高,灯灭
}
2.3 编写main函数
int main(void)
{
LED_GPIO_Config(); //初始化LED
delay_init(168); //初始化延时函数
KEY_GPIO_Config(); //初始化按键的GPIO
delay_ms(200); //延时200ms
GPIO_ResetBits(GPIOF,GPIO_Pin_10); //置低位,LED灯亮
IWDG_Init(); //初始化看门狗
while(1){
if(KEY_Scan(GPIOE,GPIO_Pin_4) == 0){ //检测按键按下
IWDG_ReloadCounter(); //喂狗
}
delay_ms(10);
}
}
3. 实验结果
开始没有按下KEY0,灯会闪烁,说明程序在一直复位,delay_ms(200)会让灯展示出闪烁;如果按下按键(要保证这个按下和松开时间在1s内,因为看门狗的溢出时间是1s),就是喂狗状态,程序是不会复位的,也就是灯是一直亮的。
IWDG
4. 总结
由于程序是由按键实验复制过来的,在没有把延时函数初始化的情况下,就使用了延时,导致程序就卡在了delay_ms(200)上,经过调试发现问题,加上初始化,最后解决了这个问题。
delay_init(168); //初始化延时函数
delay_ms(200);