STM32学习笔记(白话文理解版)—外部IO中断实验

发布于:2023-02-14 ⋅ 阅读:(574) ⋅ 点赞:(0)

STM32学习笔记(白话文理解版)—外部IO中断实验

一、什么是中断

理解定义:
中断是指一个突发事件,中止了CPU当前的工作,转而处理突发事件,处理完成后再回到当前工作中继续执行。
中断理解图

二、中断分类

STM32允许多种多样的中断,如外部IO、ADC、USART、I2C、RTC、USB、PVD等

三、嵌套向量中断控制器(NVIC)

理解:
根据上文我们知道STM32允许多种多样的中断,那同时发生中断怎么办呢?让哪个中断先发生哪个后发生呢?(各个中断间会产生优先级),因此我们需要管理这些中断,NVIC(嵌套向量中断控制器)便能设置各个中断的优先级来管理这些中断
杜洋老师上图分析

  • 假设我们要使用外部IO中断,我们要开启相应的中断同时也要开启中断控制器,确保各中断可以进入中断控制器
  • 当产生中断信号时,中断信号进入中断控制器,中断控制器对各中断信号进行排序有先有后,将排序最高的中断任务发送给ARM内核进行处理,处理完成后中断控制器继续发送其他较低优先级的中断进行处理。

四、中断之——EXIT外部IO中断

特点:

  1. 所有GPIO口都可设置为中断输入
  2. 外部IO可有上升沿、下降沿、高低电平三种触发方式
  3. 可选择中断触发或事件触发

五、外部IO中断使用步骤

  1. 配置时钟(使能GPIO时钟,启用复用时钟)
  2. IO口关联中断通道
  3. 配置EXTI中断
  4. 配置中断控制器
  5. 编写中断处理函数

六、外部IO中断实验

(1)实验功能

最开始LED灯处于熄灭状态,给PA4引脚一个下降沿,进入中断处理函数,其中中断处理函数功能为,使LED灯点亮

(2)主函数部分

函数功能:
函数从主函数依次向下执行:

  1. 初始化LED
  2. 将LED灯设置为低电平,这是LED灯处于熄灭状态
  3. 设置中断优先级(初学默认)
  4. 将中断通道进行初始化
#include "stm32f10x.h"
#include "sys.h"
#include "led.h"
#include "nvic.h"
#include "delay.h"
int main(void)
{
	LED_Init();//初始化LED(将引脚PA10初始化)
	LED_Low();//设置LED最开始为灭(将引脚PA10设置为低电平)
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级(初学者默认设置就好)
	KEYLED();//中断的初始化
	while(1) 
	{
	};
}

(3)LED部分

设置了三个函数:

  • LED_Init()函数:进行LED灯的初始化,其中包括两部分:
    * RCC_APB2PeriphClockCmd()函数:使能时钟
    * GPIO_Init()函数:IO引脚的初始化函数,进行个个引脚的初始化配置,主要接受两个参数(配置引脚组,配置的参数)

  • LED_Low()函数:熄灭LED灯
    * GPIO_ResetBits()函数:(引脚组,引脚组中的几号)使此IO口输出低电平

  • LED_High()函数:点亮LED灯
    * GPIO_SetBits()函数:(引脚组,引脚组中的几号)使此IO口输出高电平

#include "sys.h"
#include "led.h"
void LED_Init(void)//点灯函数初始化
{
	//定义结构体为初始化引脚(GPIO_Init函数)做准备
	GPIO_InitTypeDef GPIO_InitStruct;
	//配置时钟rcc 使能APB2这个时钟,时钟于STM32就像是人的心脏,只有开启心脏,并将心脏置于正确的模式,单片机才能更好的工作
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//配置引脚gpio
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置引脚为 推挽输出模式(初学记住就行)
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//配置的是哪个引脚?引脚10
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//配置是什么速度?
	GPIO_Init(GPIOA,&GPIO_InitStruct);	
}
void LED_Low(void)//熄灭LED灯
{
	//输出低电平
	GPIO_ResetBits(GPIOA,GPIO_Pin_10);//引脚组A,引脚组A的10号引脚
}
void LED_High(void)//点亮LED灯
{
	//输出高电平
	GPIO_SetBits(GPIOA,GPIO_Pin_10);//引脚组A,引脚组A的10号引脚
}

(4)中断部分

配置步骤:

  1. 配置时钟
  2. IO口关联中断通道
  3. 配置EXTI中断
  4. 配置中断控制器
#include "nvic.h"
#include "sys.h"
#include "led.h"
/*
1.配置时钟
2.IO口关联中断通道(见下图)
3.配置EXTI中断
4.配置中断控制器
*/
void KEYLED(void)
{
	NVIC_InitTypeDef  NVIC_InitStruct;	//定义结构体变量
	EXTI_InitTypeDef  EXTI_InitStruct;

	//1.配置时钟:时钟对于STM32就像是人的心脏,我们启动心脏,并讲心脏设置为合理的模式,STM32才能正确的运行
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动GPIO时钟 (需要与复用时钟一同启动)     
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//配置端口中断需要启用复用时钟
	//2.IO口关联中断通道(见图解)
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);  //定义 GPIO  中断
	//3.配置EXTI中断(和点灯配置相同)
	EXTI_InitStruct.EXTI_Line=EXTI_Line4;  //定义中断线
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;    //中断使能
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //下降沿触发
	EXTI_Init(& EXTI_InitStruct);//中断初始化:上面4条语句都是为这条铺垫,因为这条的函数参数是结构体变量
	//4.配置中断控制器(和点灯配置相同)
	NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn;   //中断线     
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	NVIC_Init(& NVIC_InitStruct);//中断控制器初始化:上面4条语句都是为这条铺垫,因为这条的函数参数是结构体变量
}

//中断执行函数:
void  EXTI4_IRQHandler(void){
	if(EXTI_GetITStatus(EXTI_Line4)!=RESET){//判断某个线上的中断是否发生 
			//如果发生中断执行下面语句
		LED_High();//开启灯(将引脚PA10设置为高电平)
		EXTI_ClearITPendingBit(EXTI_Line4);   //清除 LINE 上的中断标志位
	}     
}

关于2. IO口关联中断通道解释:

  • STM32的IO口有100多个,但供IO口使用的中断线只有16个,那我们就需要将16个中断线和100多个IO口对应起来,使每个中断标志位对应了许多个GPIO引脚
    eg:EXIT4 对应了PA4、PB4、PC4…PG4

  • 故配置外部IO中断部分时需要将IO口和中断联系起来,以此来说明使用了哪个IO口的中断

    eg:本例子使用了PA4引脚的中断,根据图示应该关联EXTI4标志位,关联后就可根据EXTI_Init()函数 进行外部中断EXTI的配置了
    杜洋老师

六、总结

最开始时LED灯为熄灭状态,通过对外部IO中断的设置,设置为给一个IO端口下降沿后,进入中断处理函数,中断处理函数内执行点亮LED的操作,而后跳出中断处理函数,继续执行主函数。
本篇粗浅介绍了什么是中断,中断的分类,中断中外部IO中断的应用步骤,浅薄的理解了外部IO中断实验,如有不对之处还请批评指正。

本文含有隐藏内容,请 开通VIP 后查看