S3C6410通过按键玩中断

发布者:size0109最新更新时间:2022-05-27 来源: eefocus关键字:S3C6410  按键  中断 手机看文章 扫描二维码
随时随地手机看文章

一 按键初始化

在S3C6410中,底板上通过开发板手册可以看出按键有六个,从S2到S7依次对应的为GPN0到GPN5,且控制GPN的寄存器为GPNCON,地址为0X7F008830。

这里写图片描述
这里写图片描述
这里写图片描述

由上图可知,只要设置相应位为10,就可以设置相应的寄存器为外部中断功能,按键的初始化代码如下


#define GPNCON (volatile unsigned long*)0x7f008830

    void button_init()

   {

       *(GPNCON) = 0b10 | (0b10<<10);        //设置按键S2与按键S7

    }


二 堆栈初始化

这里写图片描述
这里写图片描述
这里写图片描述

之前的初始化都是在svc模式下的,现在执行中断需要添加一个IRQ模式,根据手册上可以看出改变cpsr的M[4:0]位即可改变不同的模式,IRQ模式为b10010,设置好栈,就是当运行在中断模式下,sp指针指向正确的栈,同理在svc模式下sp指针指向正确的栈。

代码如下


init_stack:

        msr cpsr_c, #0xd2

        ldr sp, =0x53000000 //初始化r13_irq

        msr cpsr_c, #0xd3

    ldr sp, =0x54000000  //初始化R13_svc

    mov pc ,lr


三 中断初始化

配置按键中断为下降沿触发

找到外部中断控制器,ENT0CON0控制EINT0到EINT5分别设置相应的位为01x,即为下降沿触发,设置EINT0MASK屏蔽寄存器,把相应的位设置为0即可。

这里写图片描述
这里写图片描述
这里写图片描述

使能中断,s3c6410有多个中断源,以下为按键所用到的中断源(只显示部分中断源)。

这里写图片描述

使能按键中断

这里用到的按键中断源都属于VIC0,通过设置VIC0INTABLE来使能相应的中断源,由于在这只用到VIC0,所以只要设置VIC0即可,按键S2和按键S7分别用到External Interrupt0和External Interrupt5,所以用到中断源0和1,故设置VIC0INTABLE最低位0和1两位为1即可。

这里写图片描述
这里写图片描述

由于之前在start.s中中断被屏蔽掉了,现在需要打开,代码如下


__asm__( 

"mrs r0,cpsrn"

    "bic r0, r0, #0x80n"

    "msr cpsr_c, r0n"            

    : 

    : 

  );


设置向量中断

向量中断没有统一的入口,64个寄存器对应相应的中断源,每个寄存器存放中断源的中断处理程序地址,当中断产生的时候,硬件直接从寄存器中取出中断源中断处理程序的地址,只需要相应的中断处理程序写入到相应的寄存器中,就可以硬件直接处理。

这里写图片描述

按键中断采用的中断源为VIC0VECTADDR第0位和第1位,故设置EINT0_VECTADDR 为0x712000100,EINT5_VECTADDR设置为0x712000104,通过将函数名赋值给相应的中断源,如EINT0_VECTADDR = (int)key1_handle;就等于把中断处理程序的地址赋值给中断源,6410还需要设置一下是否为向量中断方式,默认的位非向量中断方式,所以在此需要将其设置一下。


清除外部中断PEND

当中断处理完之后,需要将其写入1清除,才能继续进行后面的中断,除此之外还需要清除VICXADDRESS,因为当中断产生的时候,除了调用处理函数之外,还把中断源记录的地址放到VICXADDRESS中,所以中断处理完之后,需要将其清零。


关于ARM流水线结构地址

ARM采取流水线结构运行,取码译码执行,所以PC指针一直指向当前执行地址+8,加入当前执行地址为0

● 当前代码执行地址: 0

● 即将要执行的代码地址: 0+4

● 此时PC指针值: 0+8

如果执行当前代码时发生了中断,我们需要保存即将要执行的代码地址到LR寄存器,而此时LR指针的值其实为PC指针值,因此需要将LR寄存器的值减去4之后再保存到LR中,才是保存的的即将要执行的代码地址。


中断程序代码如下


#define EXT_INT_0_CON       *((volatile unsigned int *)0x7f008900)   

#define EXT_INT_0_MASK      *((volatile unsigned int *)0x7f008920) 

#define EXT_INT_0_PEND      *((volatile unsigned int *)0x7f008924)     


#define VIC0INTENABLE       *((volatile unsigned int *)0x71200010)   


#define EINT0_VECTADDR      *((volatile unsigned int *)0x71200100)  

#define EINT5_VECTADDR      *((volatile unsigned int *)0x71200104)    

#define VIC0ADDRESS         *((volatile unsigned int *)0x71200f00)   

#define VIC1ADDRESS         *((volatile unsigned int *)0x71300f00)


void key1_handle()

{

    __asm__( 


    "sub lr, lr, #4n"  

    "stmfd sp!, {r0-r12, lr}n"       

    : 

    : 

   );


    led_on();


    /* 清除中断 */

    EXT_INT_0_PEND = ~0x0;  

    VIC0ADDRESS = 0; 

    VIC1ADDRESS = 0; 


    __asm__( 

    "ldmfd sp!, {r0-r12, pc}^ n"       

    : 

    : 

  );


}


void key6_handle()

{

    __asm__( 


    "sub lr, lr, #4n"  

    "stmfd sp!, {r0-r12, lr}n"       

    : 

    : 

  );

    led_off();


    /* 清除中断 */

    EXT_INT_0_PEND = ~0x0; 

    VIC0ADDRESS = 0; 

    VIC1ADDRESS = 0;   


    __asm__( 

    "ldmfd sp!, {r0-r12, pc}^ n"       

    : 

    : 

  ); 

}


void init_irq()

    EXT_INT_0_CON = (0b010)|(0b010<<8);            /* 配置为下降沿触发 */  


    EXT_INT_0_MASK = 0;                   /* 取消屏蔽外部中断 */  


    VIC0INTENABLE |= (0b1)|(0b10);                     /* 使能外部中断*/  


    EINT0_VECTADDR = (int)key1_handle;           /* 用户按下key时,CPU就会自动的将VIC0VECTADDR0的值赋给VIC0ADDRESS并跳转到这个地址去执 */  

    EINT5_VECTADDR = (int)key6_handle;


    __asm__( 


    "mrc p15,0,r0,c1,c0,0n"

    "orr r0,r0,#(1<<24)n"

    "mcr p15,0,r0,c1,c0,0n"


    "mrs r0,cpsrn"

    "bic r0, r0, #0x80n"

    "msr cpsr_c, r0n"            

    : 

    : 

  );

}

关键字:S3C6410  按键  中断 引用地址:S3C6410通过按键玩中断

上一篇:DMA机制(基于S3C6410)
下一篇:S3C6410核心初始化

推荐阅读最新更新时间:2024-11-08 11:37

stm8中断的学习
//PA4口中断初始化 void Driver_ExtIntOn(void) { //PA4 上拉输入 PA_DDR &= CLRBIT4; PA_CR1 |= SETBIT4; //下降沿触发 EXTI_CR1 |= SETBIT1; EXTI_CR1 &= CLRBIT0; //开启端口中断 PA_CR2 |= SETBIT4; } volatile bool ExiFlag = False; //中断服务程序 @far @interrupt void Driver_EXI_Interrupt(void) { //--- 外部中断处理 ---- //置中断标志 ExiFlag = True; } struct i
[单片机]
基于Small RTOS51的PS/2键盘驱动程序开发
引言   随着嵌入式系统的发展,嵌入式软件设计向软件平台靠近,单片机软件设计不再是单一线程结构方式,而是逐步采用多任务的设计思想。实时操作系统使得实时应用程序的设计、扩展和维护变得更容易,无需大的改动就可以增加新的功能。然而随着任务的增加,要求输入的数据也会增加,类型也呈多样化。如果仍然用矩阵式扫描键盘,势必浪费单片机巨大的资源,且增加了成本。若用PC机标准PS/2键盘取而代之,将可解决以上矛盾。本文介绍基于实时操作系统Small RTOS51的PS/2键盘驱动程序的设计,具有响应快,移植性强,占用资源少等优点。 1 驱动的设计   驱动的实现一般可用以下几种方法:① 使用任务编写;② 使用消息编写;③ 使用信号量编写。PS
[嵌入式]
s3c2440裸机-I2c编程-3.i2c中断服务程序
Start信号之后,发出设备地址,在第9个时钟就会产生一个中断,我们根据i2c的流程图来编写中断程序。 每传输完一个数据将产生一个中断,I2C操作的主体在中断服务程序,它可以分为两部分:写操作,读操作。 完整code如下: static p_i2c_msg p_cur_msg; int isLastData(void) { if (p_cur_msg- cnt_transferred == p_cur_msg- len - 1) return 1; /* 正要开始传输最后一个数据 */ else return 0; } void resume_iic_with_
[单片机]
STM8L之按键中断
简介 本文介绍STM8L系列如何使用按键中断,对PB2采用中断下降沿的方式进入中断。 实验平台 编译软件:IAR for STM8 1.42.2 硬件平台:stm8l101f3p6开发板 仿真器:ST-LINK 库函数版本:STM8L_STMTouch_Lib_V1.1.0 实验步骤 1、工程中添加自己写的按键驱动 1)写一个驱动GUA_Key.c (存放在工程的USER文件夹中) //****************************************************************************** //name:
[单片机]
STM8L之<font color='red'>按键</font><font color='red'>中断</font>
stc15单片机外部中断0程序(下降沿中断方式)
外部中断0(下降沿中断)实验步骤: 1、MINI USB连接线给开发板通电下载程序,下载软件中内部IRC时钟选择11.0592MHZ; 2、下载程序后,按下用户按键S3观察绿色指示灯有何变化; 3、原理图可知按键不按时IO口是高电平,故按下按键的瞬间在P32上产生下降沿,灯亮,而松开按键会产生上升沿,灯状态不翻转; 4、故按下一次按键,灯状态翻转一次(由亮变灭或由灭变亮)。 单片机源程序如下: /****************************************Copyright (c)**************************************************** **
[单片机]
ARM9的中断控制器
简要复习一下ARM9中断控制器的控制过程: 1.首先能识别触发的中断(对应中断源必须打开,然后查询当前中断状态寄存器),硬件会操控PC跳到中断向量入口(IRQ_HANDLE,硬件控制的只要是IRQ中断类型就会进入),在中断跳转函数里面保存现场(保存R0等等工作寄存器)--跳到服务函数(里面进行中断源判断和处理)---恢复现场,基本流程是这样。 2.中断的触发:高低电平,上升下降沿等等,具体的设置寄存器实现。 3.中断能否传到CPU?触发以后还要通过许多开关(寄存器设置使能与否)确保到达CPU,这样CPU才能识别(有的中断源是不需要的),有些中断是二级中断,需要开关比较多,注意芯片手册说明 4. 比如我们要触发的是INT_TC这
[单片机]
ARM9的<font color='red'>中断</font>控制器
RTI -- 实时中断
实时中断并不复杂,简单地说,就是一个定时模块,定时溢出,产生中断。功能跟 PIT差不多,都能用于定时。 对于PIT 时钟电路每固定一段时间都必须更新一次时间信息,这个更新的责任就落到了MCU身上。对于那种比较繁重的系统而言,“进行一次更新”会耗费许多的资源。而RTI只专注于记时工作,使MCU可以空出来处理其它的工作。外部晶振时钟可以直接“驱动”RTI。 RTI定时不会很准,因为它没有经过复杂的时钟处理,经过配置之后,可以变为a2^b 倍数,因为a2^b不能是任意数整数,不能配成你想要的任何频率,所以说RTI定时不会很准,不过它用起来还是很灵活、方便的。 本例通过用MC9S12XS128MAA来做一个实时中断。 以下为本例所
[单片机]
RTI -- 实时<font color='red'>中断</font>
S3C6410之uboot回炉再造(4)使能MMU
在上一篇中讲完了lowlevel_init中对相应模式的设置、在最后对MMU进行了初始化。 那在这一篇就把使能MMU的过程描述了。   1、设置访问域 1 after_copy:            //这里怎么就after了、我们可还没有copy呢                     //剧透一下,后面会补充copy相关的代码,此处暂且跳过 2 #ifdef CONFIG_ENABLE_MMU    // 3 enable_mmu: 4 /* enable domain access */ 5 ldr r5, =0x0000ffff 6 mcr p15, 0, r5, c3, c0, 0
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved