栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

轮询与中断(lv9-day16-day18)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

轮询与中断(lv9-day16-day18)

 

文章目录
  • 轮询与中断
    • 1 CPU与硬件的交互方式
    • 2轮询方式实现按键检测
    • 3 GPIO 中断
      • 3.1 GPX1_1中断相关寄存器配置
        • 3.1.1首先设置GPX1_1中断模式(GPX1CON)
        • 3.1.2 其次配置GPX1_1中断产生模式为下降沿触发(EXT_INT41CON)
        • 3.1.3 然后打开GPX1_1中断(EXT_INT41_MASK 写1关闭 写0开启)
        • 清除中断标志位
        • 3.1.1代码
      • 3.2 中断控制器
        • 3.2.1 相关寄存器的配置
        • 3.3.2 中断控制器配置代码
    • 4 中断处理
      • 4.1 中断处理框架的搭建
          • 4.1.1LR 寄存器(链接寄存器)执行跳转指令的原理
          • 4.1.2 在中断向量表FRQ中添加中断处理跳转指令
          • 4.1.2 irq_handler的编写
          • 4.1.3 中断处理程序的编写
      • 4.2代码

 

轮询与中断 1 CPU与硬件的交互方式

2轮询方式实现按键检测

这里采用4412开发板上的按键2 当其按下,就向串口发送 “key2 poress”

通过上面原理图可知,KEY2连接到板子的GPX1_1上。

由上面原理图可知,当按键K2未被按下时GPX1_1此时的电平时是高电平,被按下时电平是低电平。
可以通过读GPX1_1的电平检测按键是否按下(GPX1_1设置成输入模式)。

#include "exynos_4412.h"
int main()
{
	
	GPX1.CON =GPX1.CON &(~(0xFF)) |(0x00<<4);
	while(1)
	{
		
		
		if(!GPX1.DAT & (1<<1))
		{
           printf("Key2 Pressedn");
		   
		   while(!GPX1.DAT & (1<<1));
		}
		else
		{

		}
	}
	return 0;
}

3 GPIO 中断

GPIO中断方式实现按键检测(检测到按键按下就向UART2发送Key2 Pressed)
4412开发板上的KEY2连接在GPX1_1上

3.1 GPX1_1中断相关寄存器配置

3.1.1首先设置GPX1_1中断模式(GPX1CON)


配置GPX1CON的[7:4]为0xF

3.1.2 其次配置GPX1_1中断产生模式为下降沿触发(EXT_INT41CON)


配置EXT_INT41CON的[6:4]为0x2

3.1.3 然后打开GPX1_1中断(EXT_INT41_MASK 写1关闭 写0开启)


配置EXT_INT41_MASK 的[1]为0x0

最后挂起GPX1_1中断(EXT_INT41_PEND,一般不用配置,默认开启,但是要在中断处理程序里清除中断标志位)

3.1.4 清除中断标志位


这一个寄存器用于清除中断标志位,注意写1清零



这一个寄存器用于通知中断控制器CPU已经处理完中断(把产生中断的ID写到这个寄存器里)

3.1.5  代码

#include "exynos_4412.h"
void GPIO_INT_INIT(void)
{

	
	GPX1.CON=GPX1.CON |(0xF<<4);
	
	EXT_INT41_CON = EXT_INT41_CON &(~(0x7<<4)) |(0x2<<4);
	
	EXT_INT41_MASK = EXT_INT41_MASK &(~(1<<1));
}
int main()
{

	//初始化KEY2中断模式初始化
    GPIO_INT_INIT();
	return 0;
}

3.2 中断控制器

4412总共能产生160个中断,中断控制器为每一个中断都分配了一个唯一的ID,便于管理。

由上面的原理图可知KYE2的中断时外部中断9.


查芯片手册外部中断9的ID是57,先记住这个ID后面会用到

3.2.1 相关寄存器的配置


这一个寄存器用于使能或者禁止总中断。

这一寄存器用于使能或者禁止控制所有中断的具体那个中断,总共有160个中断,每个寄存器32位,所以需要5个寄存器。

由于KEY的外部中断ID是57,由上图可知,它由第二个寄存器的第25位控制使能与禁止。

 

ICDIPTR_CPU
这一个寄存器用于控制中断信号交给那个cpu处理(4412是4核处理器,所以只有低四位有用)


由于有160个中断信号,每一个中断信号我们都可以为它选择一个CPU ,每一个中断信号都有一个8位的空间用于控制它交给那个CPU处理,所以总共需要 160*8/32=40个寄存器。下面是对应关系

假设我们要让6号中断交给CPU2处理,那就要往第二个寄存器(基地址+0x804)的16到23位写0000 0010
所以57号中断为偏移量为838的寄存器来控制。由于我们一般会在4412上装一个操作系统,这些工作操作系统都会帮我们处理,所以我们在这里用默认的CPU0来处理中断信号。



这一寄存器用来使能中断信号能否通过CPU到达处理器。使用那个CPU就要使能那个通道(4个)


这一个寄存器的[9:0]位用于记录是谁产生的中断。

 

3.3.2 中断控制器配置代码

void INI_init(void)
{
	
	ICDDCR = ICDDCR |1;
	
	ICDISER.ICDISER1 = ICDISER.ICDISER1 | (1<<25);
	
	ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xFF<<8)) |(0x01<<8);
	
	CPU0.ICCICR =CPU0.ICCICR | 1;


}
4 中断处理 4.1 中断处理框架的搭建

4.1.1LR 寄存器(链接寄存器)执行跳转指令的原理




总之,当产生IRQ中断时LR寄存器保存的地址是不正确的,需要人为修正(再减4)

4.1.2 在中断向量表FRQ中添加中断处理跳转指令

_start:
	b reset
	b.
	b.
	b.
	b.
	b.
	b irq_handler
	b

4.1.3 irq_handler的编写

irq_handler :
				 
	sub lr ,lr,#4
	
    stmfd sp! ,{r0-r12,lr}
    //处理异常
	 bl do_irq
	 
	GPX1.CON=GPX1.CON |(0xF<<4);
	
	EXT_INT41_CON = EXT_INT41_CON &(~(0x7<<4)) |(0x2<<4);
	
	EXT_INT41_MASK = EXT_INT41_MASK &(~(1<<1));
}
void INI_init(void)
{
	
	ICDDCR = ICDDCR |1;
	
	ICDISER.ICDISER1 = ICDISER.ICDISER1 | (1<<25);
	
	ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xFF<<8)) |(0x01<<8);
	
	CPU0.ICCICR =CPU0.ICCICR | 1;


}
void LED_init(void)
{
	GPX2.CON=GPX2.CON &(~(0xF<<28)) |(0x1<<28);
}
void Delay(int time)
{
  while(time--);

}
int main()
{

	//初始化KEY2中断模式初始化
    GPIO_INT_INIT();
    //中断控制器初始化
    INI_init();
    //led初始化
    LED_init();
    while(1)
    {
       		GPX2.DAT=GPX2.DAT & (~(1<<7));
		    Delay(1000000);
		    GPX2.DAT=GPX2.DAT | (1<<7);
		    Delay(1000000);

    }
	return 0;
}

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/935279.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号