Day6
目录
一、EXIT外部中断
1.外部中断概述
2.外部中断映射
3.外部中断常用库函数
4. 外部中断的一般配置歩骤
5.关于中断服务函数
6.手写代码
7.实验现象
??? 二、独立看门狗实验
1.看门狗作用
2.两个看门狗
3. 独立看门狗功能描述
4.独立看门狗的寄存器
5.独立看门狗时间设置
6.独立看门狗库函数操作
7.IWDG初始化步骤
8.手写代码
9.实验现象
三、今日总结:
一、EXIT外部中断
1.外部中断概述
STM32的每个I0都可以作为外部中断输入。
STM32的中断控制器支持19个外部中断/事件清求:线0~15:对应外部I0口的输入中断。
线16:连接到PV/D输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。
每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发1屏蔽,专用的状态位。
#关于中断线和中断服务函数的分配
2.外部中断映射
GPIOx.0映射到EXIT.0
GPIOx.1映射到EXIT.1
GPIOx.15映射到EXIT.15
3.外部中断常用库函数
void GPIO EXTIineConfig(uint8_ tGPIO_ PortSource, uint8_ t GPIO_ PinSource);? //设置IO口与中短线映射关系
例如exp: GPIO_ EXTILineConfig(GPIO_ PortSourceGPIOE,GPIO_ PinSource2);
void EXTI Init(EXTI_ InitTypeDef* EXTI_ lnitStruct); //初始化中断线:触发方式等
ITStatus EXTI GetlTStatus(uint32_tEXTI Line); ?? //检测中断线状态,是否发生
void EXTI_ ClearlTPendingBit(uint32_ tEXTI_ Line);?? //清除中断线上的中断标志位
EXTI_Init函数
void EXTI Init(EXTI_ InitTypeDef* EXTI_ lnitStruct);
4. 外部中断的一般配置歩骤
①初始化IO口为输入
GPIO_Init()
②开启复用时钟
RCC_ APB2PeriphClockCmd(RCC_ APB2Periph AFIO,ENABLE);
③设置IO口与中断线映射关系
void?GPIO_EXTILineConfig();
④初始化线上中断,设置触发条件
EXTI_Init();
⑤配置中断分組(NVIC),并使能中断。
NVIC_Init();
⑥编写中断服务函数
EXTIx_ IRQHandler();
⑦清除中断标志位
EXTI_ClearlTPendingBit();??? //手动清除
5.关于中断服务函数
6.手写代码
【main.c】
#include "stm32f10x.h"
#include "bsp_led.h"
#include " exti.h"
/**
? * @brief? 主函数
? * @param? 无
? * @retval 无
? */
int main(void)
{
?????? /* LED 端口初始化 */
?????? LED_GPIO_Config();
?????? ? ??
?????? /* 初始化EXTI中断,按下按键会触发中断,
? *? 触发中断会进入stm32f4xx_it.c文件中的函数
?????? *? KEY1_IRQHandler和KEY2_IRQHandler,处理中断,反转LED灯。
?????? */
?????? EXTI_Key_Config();
??????
?????? /* 等待中断,由于使用中断方式,CPU不用轮询按键 */
?????? while(1)???????????????????????????
?????? {
?????? }
}
【exti.c】
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_key.h"
?/**
? * @brief? 配置嵌套向量中断控制器NVIC
? * @param? 无
? * @retval 无
? */
void NVIC_Configuration(void)
{
? NVIC_InitTypeDef NVIC_InitStructure;
?
? /* 嵌套向量中断控制器组选择 */
? NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
?
? /* 配置USART为中断源 */
? NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
? /* 抢断优先级*/
? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
? /* 子优先级 */
? NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
? /* 使能中断 */
? NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
? /* 初始化配置NVIC */
? NVIC_Init(&NVIC_InitStructure);
}
/**
?? * @brief描述:配置PE5为中断口,并设置中断优先级
?? * @param输入:\
?? * @retval返回值\
?? */
?????? ?
void EXTI_PE5_Config(void)
{
?????? GPIO_InitTypeDef GPIO_InitStructure;
?????? EXTI_InitTypeDef EXTI_InitStructure;? \
??????
?????? /*配置PE5的外部时钟和AFIO时钟*/?
?????? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
??????
?????? /*配置PE5的NVIC中断优先级*/
?????? NVIC_Configuration();
??????
?????? /*配置GPIO中断线IO*/
?????? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
?????? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //上拉输入
?????? GPIO_Init(GPIOE, &GPIO_InitStructure);
?????? /*选定要配置为EXTI的IO'口和IO口的工作模式*/
?????? GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource5);
?????? EXTI_InitStructure.EXTI_Line = EXTI_Line5;
?????? EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
?????? EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;???? //下降沿中断
??????
?????? EXTI_InitStructure.EXTI_LineCmd=ENABLE;????? //使能
?????? EXTI_Init(&EXTI_InitStructure);
??????
}
/**
?? * @brief描述:中断服务函数
?? * @param输入:\
?? * @retval返回值:\
?? */
void EXTI9_5_IRQHandler(void)
{
?????? if(EXTI_GetITStatus(EXTI_Line5)!=RESET)?? //确保是否产生EXTILine'中断
?????? {//LED1取反
????????????? GPIO_WriteBit(GPIOC,GPIO_Pin_3,(BitAction)?? \
???????????????????? ((1-GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3))));
????????????? EXTI_ClearITPendingBit(EXTI_Line5);? //手动清除中断标志位
?????? }
}
【exti.h】
#ifndef __EXTI_H__
#define __EXTI_H__
void EXTI_PE5_Config(void);
void NVIC_Configuration(void);
void EXTI9_5_IRQHandler(void);
#endif
7.实验现象
按下k1,LED灭,再按LED亮
???
??? 二、独立看门狗实验
1.看门狗作用
在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗"(watchdog)。
看门狗负责人检测程序异常执行的情况,进行系统复位,重新执行
2.两个看门狗
独立看门狗IWDG:由低速时钟LSI驱动,即使主程序故障依然有效
适用于主程序外独立工作,时间精度要求低
窗口看门狗:APB1时钟分频,通过可配置时间窗口检测应用程序非正常延时,适合精确计时窗口
3. 独立看门狗功能描述
在键值寄存器(IWDG_ KR)中写入0xCCCC,开始启用独立看门狗。此时计数器开始从其复位值0xFFF递减,当计数器值计数到尾值0x000时会产生一个复位信号(IWDG RESET)。
无论何时,只要在键值寄存器IWDG_KR中写0xAAAA(通常说的喂狗),自动重装载寄存器
IWDG RLR的值就会重新加载到计数器,从而避免看门狗复位。
*如果程序异常,就无法正常喂狗,从而系统复位。
4.独立看门狗的寄存器
5.独立看门狗时间设置
6.独立看门狗库函数操作
void IWDG_WriteAccessCmdint16_t IWDG_WriteAccess);
//取消写保护:0x5555使能void
IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
//设置预分频系数:写PR
void IWDG_SetReload(uint16_t Reload);
//设置重装载值:写RLR
void IWDG_ReloadCounter(void);
//喂狗:写OxAAAA到KR
void IWDG_Enable(void);
//使能看门狗:写0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
//状态:重装载/预分频更新
7.IWDG初始化步骤 ?
①取消寄存器写保护:
IWDG WriteAccessCmd();
②设置独立看门狗的预分频系数,确定时钟:
IWDG SetPrescaler();
③设置看门狗重装载值,确定溢出时间:
IWDG SetReload();
④使能看门狗
IWDG Enable();
⑤应用程序喂狗:
IWDG ReloadCounter();
⑥溢出时间计算:
Toute((4 X2Aprer) Xrlr) /40(M3)
8.手写代码
【main.c】
#include "stm32f10x.h"
#include "bsp_led.h"?
#include "bsp_key.h"
#include "iwdg.h"
void Delay(__IO uint32_t nCount)????? //简单的延时函数
{
?????? for(; nCount != 0; nCount--);
}
/**
? * @brief? 主函数
? * @param? 无
? * @retval 无
? */
int main(void)
{?????
?????? /* LED端口初始化 */
?????? LED_GPIO_Config();
?????? /* 按键端口初始化 */
?????? Key_GPIO_Config();
??????
?????? Delay(0X8FFFFF);
?????? LED1_ON;
??????
?????? /* 看门狗初始化*/
?????? IWDG_Init(4,625);? //最大溢出时间设置为1s
??????
??????
?????? /* 轮询按键状态,若按键按下则反转LED */
?????? while(1)???????????????????????????
?????? {????? ??
????????????? if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON? )
????????????? {
???????????????????? //检测到按键1按下就喂狗
???????????????????? IWDG_ReloadCounter();
????????????? }
?? }
}
【iwdg.c】
#include "iwdg.h"
#include "stdint.h"
#include "stm32f10x.h"
void IWDG_Init(uint8_t prer,uint16_t rlr)
{
?????? IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
?????? IWDG_SetPrescaler(prer); //外部传入
?????? IWDG_SetReload(rlr);?? //外部传入
?????? IWDG_ReloadCounter();
?????? IWDG_Enable();
}
【iwdg.h】
#ifndef __IWDG_H__
#define __IWDG_H__
#include "stdint.h"
void IWDG_Init(uint8_t prer,uint16_t rlr); // 分频系数和重装载值
#endif
9.实验现象
?
如果一直不喂狗,会一直复位,加上前面的延时,会看到红灯闪烁
在1s 时间内喂狗的话,则会持续亮红灯
三、今日总结:
今天学习的内容主要是EXIT外部中断和IWDG独立看门狗,这两个内容都很基础,但是合理运用的话确实十分便捷的功能,也都顺利编译了程序,实现了实验现象,确实是有成就感的
昨天公布了排名之后还是有点紧张的,毕竟刚入门那几天走了不少弯路,对排名有一定影响,好在最近找回了自己的学习节奏,同时也能很好的完成每天布置的学习任务,希望坚持下去有所收获
但也发现了一些问题:由于我在学习过程中既看正点原子视频,又看野火的库开发实战指南,同时用野火的源代码进行学习,发现三者的命名方式和风格都不太一样,导致我的程序中可能命名方式和宏定义方式不统一,但我打算先放一放这个问题,等自己知识量充足后再慢慢调整自己的命名和定义风格
|