脚本宝典收集整理的这篇文章主要介绍了2021/10/14 智能家具 嵌入式实训 第四天 中断 (2),脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
STM32的每个IO都可以作为外部中断输入。 STM32的中断控制器支持19个外部中断/事件请求: 线0~15:对应外部IO口的输入中断。 线16:连接到PVD输出。 线17:连接到RTC闹钟事件。 线18:连接到USB唤醒事件。
每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。
从上面可以看出,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),STM32F103RCT6(51),那么中断线怎么跟io口对应呢?
通过该图可知,每一个中断线都对应了7组中的对应编号的IO口(这边以ZET6:112个IO=16个 * 7组)。 有如下关系: GPIOx.0映射到EXTI0 GPIOx.1映射到EXTI1 … GPIOx.15映射到EXTI15注意:每个时间只能有一个I/O可映射到对应的中断线。
是不是16个中断线就可以分配16个中断服务函数呢? IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数(下表少写了EXTI0)
从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数外部中断线10 ~15分配一个中断向量,共用一个中断服务函数。
EXTI0_IRQHandler EXTI1_IRQHandler EXTI2_IRQHandler EXTI3_IRQHandler EXTI4_IRQHandler EXTI9_5_IRQHandler EXTI15_10_IRQHandler
①映射 ②中断使能、触发模式等使能方式。 ③编写中断服务函数
一般配置步骤: ①初始化IO口为输入。 GPIO_Init();
② 开启IO口复用时钟。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
③设置IO口与中断线的映射关系。 void GPIO_EXTILineConfig();
④初始化线上中断,设置触发条件等。 EXTI_Init();
⑤配置中断分组(NVIC),并使能中断。 NVIC_Init();
⑥编写中断服务函数。 EXTIx_IRQHandler();
⑦清除中断标志位 EXTI_ClearITPendingBit();
①void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//设置IO口与中断线的映射关系exp: GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
②void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//初始化中断线:触发方式等
③ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//判断中断线中断状态,是否发生
④void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除中断线上的中断标志位
先把exit.h写完
#ifndef _EXTI_H_ #define _EXTI_H_ #include "stm32f10x.h" #include "stdio.h" #include "key.h" #include "beep.h" extern uint8_t key1_status; /* 函数接口 */ void EXTI0_Config(void); #endif
再写exit.c
①初始化IO口为输入。 GPIO_Init();
就是使能
按键
可以直接引用 key,h led.h
GPIO_InitTypeDef GPIO_InitStruce; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOC , ENABLE); GPIO_InitStruce.GPIO_Mode=GPIO_Mode_IPU;//上拉输入 GPIO_InitStruce.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_InitStruce.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStruce); GPIO_InitStruce.GPIO_Mode=GPIO_Mode_IPD;//下拉输入 GPIO_InitStruce.GPIO_Pin=GPIO_Pin_0; GPIO_InitStruce.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruce);
>可省略
第二步:开启IO口复用时钟
增加:RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);
第三步:设置IO口与中断线的映射关系
该函数存在于:stm32f10x_gpio.h中增加:GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
看按键的连接口 这里是KEY1 PA0 映射线
//配置中断线和IO管脚的映射关系(PA0 -- 中断线0)
第四步:初始化线上中断,设置触发条件等。
该函数存在于:stm32f10x_exti.h中增加:
//2. 配置中断线 EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line0; //中断线0 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 EXTI_Init(&EXTI_InitStructure);
第五步:配置中断分组(NVIC),并使能中断。
该函数存在于:misc.h中通道的参数是在stm32f10x,h中找到IRQn结尾的。增加:
//3. 配置NVIC //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC中断优先级组(一般写在主函数开始处) NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; //选择中断通道 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //中断通道使能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; //占先优先级 0 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; //次级优先级 0 NVIC_Init(&NVIC_InitStruct);
这边要注意,在这同时要在main.c中先写下该函数NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组,2位抢占优先级,2位响应优先级
,设置优先级后,这边填写的抢占优先级才有效。
下面写中断服务函数
编写中断服务函数&清除中断标志位
该函数在startup_stm32f10x_hd.s中:EXTI4_IRQHandler
故可在exti,c文件中编写一下程序:
先定义一下
uint8_t key1_status = 0;
key1的初始值
基本的中断服务函数
void EXTI0_IRQHandler(void) //中断服务函数 { Delay_nop_nms(10);//延时10ms if(KEY1==0){ //如果KEY1按下 BEEP_TOGGLE; } EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位 }
void EXTI0_IRQHandler(void) //中断服务函数 { if(EXTI_GetITStatus(EXTI_Line0)) //判断中断是否发生(PR挂起寄存器) { EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位 if(KEY1)//按下 key1_status = 1; else//抬起 { BEEP_TOGGLE; //LED1_TOGGLE; key1_status = 2; } } }
然后编写主函数
#include "main.h" /*********************************************************************************** 函数功能:main函数 形参:无 返回值:无 ***********************************************************************************/ int main(void) { Systick_Config(72000); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC中断优先级组 LED_Config(ON); Beep_Config(OFF); KEY_Config(); EXTI0_Config(); while(1) { LED_Twinkle(); if(key1_status==2) { key1_status=0; BEEP_TOGGLE; } } }
就相当于key1按下 key1_status为1
抬起后 key1_status为2
这样
if(key1_status==2)
key1_status=0;
可以表示一个按下抬起的过程
以上是脚本宝典为你收集整理的2021/10/14 智能家具 嵌入式实训 第四天 中断 (2)全部内容,希望文章能够帮你解决2021/10/14 智能家具 嵌入式实训 第四天 中断 (2)所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。