运用外部中断检测按键实现任务

学习笔记

外部中断简介:

中断分类

STM32的每个IO都可以作为外部中断输入,STM32的中断控制器支持19哥外部中断/事件请求:
0-15 I/O输入中断
16:连接到PVD输出。
17:连接到RTC闹钟事件。
18:连接到USB唤醒事件。

触发方式:

(1)上升沿:EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Rising;
(2)下降沿:EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Falling;
(3)双边沿触发:EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Rising_Falling;

中断线的分配:

因为STM32有上百个I/O,但只有16跟线,所以有一种独特的分配方式:
GPIOX0-----------exti0
.
.
.以此类推
即:
### 中断服务函数的分类:
STM32提供16个中断线,但是只提供7个中断向量,只有7个中断服务函数:
(可在startup_stem32f10x_xx.s文件中找到)
EXTI0| EXTI1| EXTI2 |ECTI3 | EXTI4分别有自己的中断服务函数
EXTI9-5用一个
EXTI15-10用一个
中断服务函数列表:
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler

初始化步骤:

(1)初始化所用的外部中段I/0口

本篇以cet711为例:
选用按键B1,由电路图可得,连接为PA0口
在这里外部跳线帽将NK1和MPA0连接在一起插入图片描述
在这里外部跳线帽将NK1和MPA0连接在一起
在这里插入图片描述
由图可知,按键按下后,读入低电平。

配置:

使能时钟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

PA0上拉输入

	GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
    GPIO_Init(GPIOA,&GPIO_InitStructure);`

(2)配置I/O与中断线连接:(映射关系)

因为所用PA0所以用exti0线映射,

时钟初始化:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
映射:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

(3)初始化中断线:(触发方式)

   EXTI_InitTypeDef EXTI_Initstructure;
	EXTI_Initstructure.EXTI_Line=EXTI_Line0;
	EXTI_Initstructure.EXTI_LineCmd=ENABLE;
	EXTI_Initstructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Falling;//ϽµÑØ´¥·¢
	EXTI_Init(&EXTI_Initstructure); 

(4)中断优先级管理:

1.中断优先级分组(写在主函数中,exti_init()之前):
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

中断优先级分组可以配置寄存器SCB->AIRCR从而分配寄存器中优先级的位,如2位分配给抢占优先级,2位分配给相应优先级。即抢占优先级分四个0——3,响应优先级分四个0——3

2.中断优先级分配:
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;//中断线0
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_InitStructure);

以上初始化结束

(5)写中断服务函数:

void EXTI0_IRQHandler(void)
{
	
  delay_ms(10);//消抖

	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)//判断是否按下
  {
	 LED_LI(1);//灯亮
	 beep_con(1);//蜂鸣器叫
	 }
  
  

  EXTI_ClearITPendingBit(EXTI_Line0);
}

EXTI_ClearITPendingBit(EXTI_Line0);//这句话用来清空中断标志位
外部中断标志位无法自动清空需要手动在中断服务函数中清空。
中断服务函数作用: 当中断发生时,进入中断服务函数中执行,然后在继续执行主程序。

代码

void EXITA_INIT(void)
{
  EXTI_InitTypeDef EXTI_Initstructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
	
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	EXTI_Initstructure.EXTI_Line=EXTI_Line0;
	EXTI_Initstructure.EXTI_LineCmd=ENABLE;
	EXTI_Initstructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_Initstructure.EXTI_Trigger=EXTI_Trigger_Falling;//ϽµÑØ´¥·¢
	
	NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
	EXTI_Init(&EXTI_Initstructure); 
	NVIC_Init(&NVIC_InitStructure);
	
}
void EXTI0_IRQHandler(void)
{
	
  delay_ms(10);

	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)
  {
	 LED_LI(1);
	 beep_con(1);
	 }
  
  

  EXTI_ClearITPendingBit(EXTI_Line0);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值