ARM裸机 - 外部中断方式处理按键编程实践_外部中断可以检测按键按下和弹起吗

原理图上可以看出:按下时是低电平,弹起时是高电平。

2.核心板原理图:

在这里插入图片描述

在这里插入图片描述 找到按键对应的GPIO:SW5:GPH0_2 SW6:GPH0_3 SW78910:GPH2_0123。

3.按键对应的GPIO模式设置

按键接到GPIO上,按键按下还是弹起,决定外部电路的接通与否,从而决定这个GPIO引脚的电压是高还是低;这个电压可以作为这个GPIO引脚的输入信号,此时GPIO配置为输入模式,即可从SoC内部读取该引脚的电平为1还是0(1对应高电平,0对应低电平)。

在CON寄存器中将GPIO设置为input模式,然后去读取DAT寄存器(读取到的相应位的值为1表示外部是高电平(对应按键弹起),读取到的位的值为0表明外部是低电平(按键按下))。

4.外部中断

SoC支持的中断类型中有一类叫外部中断。内部中断就是指的中断源来自于SoC内部(一般是内部外设),譬如串口、定时器等部件产生的中断;外部中断是SoC外部的设备,通过外部中断对应的GPIO引脚产生的中断。

按键在SoC中就使用外部中断来实现。具体实现方法是:将按键电路接在外部中断的GPIO上,然后将GPIO配置为外部中断模式。此时人通过按按键改变按键电路的电压高低,这个电压高低会触发GPIO对应的外部中断,通过引脚传进去给CPU处理。

5.电平触发和边沿触发

电平触发就是说GPIO上的电平只要满足条件,就会不停触发中断。电平触发分为高电平触发和低电平触发。电平触发的特点是,只要电平满足条件就会不停触发中断

边沿触发分为上升沿触发下降沿触发双边沿触发三种。边沿触发不关心电平常规状态,只关心电平变化的瞬间(边沿触发不关心电平本身是高还是低,只关心变化是从高到低还是从低到高的这个过程)。

分析按键的工作:如果我们关注的是按键按下和弹起这两个事件本身,那么应该用边沿触发来处理按键;如果我们关心的是按键按下/弹起的那一段时间,那么应该用电平触发。

6.几个关键寄存器

**EXT_CON:**配置外部中断的触发方式。触发方式就是说外部电平怎么变化就能触发中断,也就是说这个外部中断产生的条件是什么。

**EXT_PEND:**是中断挂起寄存器。这个寄存器中每一位对应一个外部中断,平时没有中断时值为0。当发生了中断后,硬件会自动将这个寄存器中该中断对应的位置1,我们去处理完这个中断后应该手工将该位置0。

**EXT_MASK:**是各个外部中断的使能/禁止开关。

7.中断方式处理按键编程实践

-> 外部中断对应的GPIO模式设置。
-> 中断触发模式设置。
-> 中断允许、清挂起。
-> 中断处理程序isr编写。

添加的key.c文件和main.c文件

#include "stdio.h"
#include "main.h"

// 定义操作寄存器的宏
#define GPH0CON		0xE0200C00
#define GPH0DAT		0xE0200C04
#define GPH2CON		0xE0200C40
#define GPH2DAT		0xE0200C44

#define rGPH0CON	(*(volatile unsigned int *)GPH0CON)
#define rGPH0DAT	(*(volatile unsigned int *)GPH0DAT)
#define rGPH2CON	(*(volatile unsigned int *)GPH2CON)
#define rGPH2DAT	(*(volatile unsigned int *)GPH2DAT)

#define EXT_INT_0_CON	0xE0200E00
#define EXT_INT_2_CON	0xE0200E08
#define EXT_INT_0_PEND	0xE0200F40
#define EXT_INT_2_PEND	0xE0200F48
#define EXT_INT_0_MASK	0xE0200F00
#define EXT_INT_2_MASK	0xE0200F08

#define rEXT_INT_0_CON	(*(volatile unsigned int *)EXT_INT_0_CON)
#define rEXT_INT_2_CON	(*(volatile unsigned int *)EXT_INT_2_CON)
#define rEXT_INT_0_PEND	(*(volatile unsigned int *)EXT_INT_0_PEND)
#define rEXT_INT_2_PEND	(*(volatile unsigned int *)EXT_INT_2_PEND)
#define rEXT_INT_0_MASK	(*(volatile unsigned int *)EXT_INT_0_MASK)
#define rEXT_INT_2_MASK	(*(volatile unsigned int *)EXT_INT_2_MASK)

//-----------------------中断方式处理按键-----------------------------------
// 以中断方式来处理按键的初始化
void key_init_interrupt(void)
{
	// 1. 外部中断对应的GPIO模式设置
	rGPH0CON |= 0xFF<<8;		// GPH0_2 GPH0_3设置为外部中断模式
	rGPH2CON |= 0xFFFF<<0;		// GPH2_0123共4个引脚设置为外部中断模式
	
	// 2. 中断触发模式设置
	rEXT_INT_0_CON &= ~(0xFF<<8);	// bit8~bit15全部清零
	rEXT_INT_0_CON |= ((2<<8)|(2<<12));		// EXT_INT2和EXT_INT3设置为下降沿触发
	rEXT_INT_2_CON &= ~(0xFFFF<<0);
	rEXT_INT_2_CON |= ((2<<0)|(2<<4)|(2<<8)|(2<<12));	
	
	// 3. 中断允许
	rEXT_INT_0_MASK &= ~(3<<2);			// 外部中断允许
	rEXT_INT_2_MASK &= ~(0x0f<<0);
	
	// 4. 清挂起,清除是写1,不是写0
	rEXT_INT_0_PEND |= (3<<2);
	rEXT_INT_2_PEND |= (0x0F<<0);
}

// EINT2通道对应的按键,就是GPH0_2引脚对应的按键,就是开发板上标了LEFT的那个按键
void isr_eint2(void)
{
	// 真正的isr应该做2件事情。
	// 第一,中断处理代码,就是真正干活的代码
	printf("isr_eint2_LEFT.\n");
	// 第二,清除中断挂起
	rEXT_INT_0_PEND |= (1<<2);
	intc_clearvectaddr();
}

void isr_eint3(void)
{
	// 真正的isr应该做2件事情。
	// 第一,中断处理代码,就是真正干活的代码
	printf("isr_eint3_DOWN.\n");
	// 第二,清除中断挂起
	rEXT_INT_0_PEND |= (1<<3);
	intc_clearvectaddr();
}

void isr_eint16171819(void)
{
	// 真正的isr应该做2件事情。
	// 第一,中断处理代码,就是真正干活的代码
	// 因为EINT16~31是共享中断,所以要在这里再次去区分具体是哪个子中断
	if (rEXT_INT_2_PEND & (1<<0))
	{
		printf("eint16\n");
	}
	if (rEXT_INT_2_PEND & (1<<1))
	{
		printf("eint17\n");
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/507ba2b7549b0895485e442ee420b622.png)

![img](https://img-blog.csdnimg.cn/img_convert/c8dcc8696fa4c8f998d12e0ff8332e8a.jpeg)

![img](https://img-blog.csdnimg.cn/img_convert/6f23924d284d2ad58a20aefedf43ff8c.png)

 **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

![img](https://img-blog.csdnimg.cn/img_convert/659ce376464006ec3edcc87d06c21d10.png)

![img](https://img-blog.csdnimg.cn/img_convert/fb9f4bfc629dbad628f57ed4da593de2.png)

 

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**

<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />



# 最后

**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**

**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**

g-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />



# 最后

**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**

**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**

**[更多资料点击此处获qu!!](https://bbs.csdn.net/topics/618376385)**
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值