zoukankan      html  css  js  c++  java
  • 6.6410和210的按键中断编程

    6.6410和210的按键中断编程

    首先是打开6410底板原理图:

    可以看到OK6410有六个按键:

    可以看到OK6410的六个按键对应的引脚是KEYINT1、KEYINT2、KEYINT3、KEYINT4、KEYINT5和KEYINT6。接着在核心板的原理图里搜索这个词:

    可以看到按键中断与GPN系列寄存器的引脚是互用的,接着就是在芯片手册里查看有关GPN系列寄存器的信息,重点是关注GPN控制寄存器:GPNCON:

    这里我们使用到的按键对应的中断,需要配置成中断的方式,对应的GPN位设置为10,中断功能,即需要将KEYINT1-6设置为中断功能的,即是将GPNCON对应的前12位设置为101010101010即可。这样就把对应的GPN0-5设置为中断位。实现代码:

    上面我们完成了按键的初始化,这样就把六个按键对应的位设置为外部中断的功能了。

    接下来就是中断的初始化了。

        1.设置按键中断是发生在下降沿,也就是下降沿触发的方式,即低电平,按键弹开是上升沿,也就是高电平。

    这里需要寄存器EINT0CON0:

    由原理图知道KEYINT1-KEYINT6对应的中断位是XEINT0-XEINT5,由上面设置从下降沿触发:

    设置好了下降沿触发,接着就是把先前屏蔽的功能去掉,就是使能中断:

    屏蔽寄存器:

    这里我们需要将对中断位EINT0-EINT5的屏蔽功能给去掉,要不然,即使发生了中断也不会送到CPU。这是为了方便,就不一一去设置,直接将该寄存器赋值为0,就是全部中断去掉屏蔽:

    取消屏蔽外部中断后,就是使能外部中断的操作:

    上面两个寄存器就是使能中断的,每一位控制一种中断源,在系统复位之后默认的值是0,如果需要使能某个中断,就需要将对应的位设置为1=Interrupt enabled。

    从上面知道,我们的外部中断0-3是属于中断源0的,外部中断4-11是属于中断源1的。所以要使能六个按键的外部中断,需要使能0号中断源和1号中断源,该中断源是属于VIC0寄存器组的,就是往VIC0INTENABLE的0位和1位写入1即可,代码实现:

    这样使能外部中断也完成了。

    接下来设置CPSR程序状态寄存器,来打开总的中断控制,因为前面的学习中是把它关闭的。

    到这里如果按照2440的非向量中断的设置到这里就结束,但是在6410里还没有,因为6410采用的是向量中断方式。

    首先来看看非向量中断方式的流程图:

    上面就是非向量中断的中断处理流程,当中断产生的时候,会跳转到对应的统一的入口,去执行对应的中断处理程序,大部分的工作都是软件来完成的。

    而6410的向量中断,很大部分的工作是硬件来完成的,这样速度会更快,原理图:

    上面就是向量中断的原理。

    所以接下来就是在中断初始化的时候,把对应的中断处理程序(就是处理程序的函数名字)安排到对应的寄存器里。接下来就是该操作:先找到对应的寄存器组:

    可以看到属于VIC0组的有32个寄存器,属于VIC1组的也有32个寄存器,刚好64寄存器,对应64个中断源。按键1对应的是EINT0,也就是对应寄存器0x71200100.

    代码:

    上面就是按键的中断处理程序。但是在6410默认是没有使能向量中断的,它是先下兼容,默认是非向量中断的,所以6410要使用向量中断需要使能。注意210就不需要使能了。在CP15的c1寄存器的24位控制的。6410使能代码:

    __asm__(

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

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

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

    "mrs r0,cpsr "

    "bic r0, r0, #0x80 "

    "msr cpsr_c, r0 "

    :

    :

    );

    上面就是使能向量中断的操作,到这里才完成了6410的中断初始化的操作。

    最后就是中断处理了。

    步骤:

    1. 保存环境
    2. 中断处理
    3. 清除中断
    4. 恢复环境

    1.保存环境:

    __asm__(

    "sub lr, lr, #4 "

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

    :

    :

    );

    2.中断处理:

    3.是清中断:

    清中断对应的寄存器:

    该寄存器当相应的中断产生的时候,对应的中断位会被置1.从该寄存器的NOTES知道,如果往对应的中断位写入1,则就是清除中断。这里为了方便,我们写入全1,清除所有的中断。

    我们前面知道每一种向量中断对应一个寄存器

    VIC0组的寄存器:

    VIC1组寄存器:

    上面就是64中断源对应的64个寄存器,在这些寄存器的后面有寄存器VICxADDRESS:

    这种寄存器有两个,VIC0ADDRESS和VIC1ADDRESS.例如当VIC0的一个串口中断产生的时候,系统除了会调用对应的处理函数外,还会把中断处理程序的地址保存到VICxADDRESS寄存器里面。

    当中断处理完后,要把这两个寄存器清零:

    这样就完成了中断处理程序了。

    4.最后一步就是清中断:

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

    到这里才完成了中断处理程序的步骤,最后的部分代码如下:

    注意到这里虽然中断的处理程序完成了,但是还不能烧写到开发板。这是因为跟2440的情况一样,我们的start.S里只有对svc模式的堆栈进行初始化,没有对irq模式的堆栈进行初始化。所以最后我们还得来对irq的堆栈进行初始化:

    可以看到程序一开始就工作在SVC模式,而我们的按键中断是工作在irq模式的。我们需要这是工作在irq模式的堆栈,才能让程序正常运行。要设置系统工作在irq模式,需要将CPSR的模式位设置为10010:

    实现代码:

    这里的cpsr_c是CPSR寄存器的末尾8位:

    这里设置的值为0xd2=0b 11010010,可以看到该值把中断打开了,而且还设置系统工作在irq模式。

    最后的代码是:

    我们给irq模式下的sp堆栈设置了值,接着给SVC模型下的sp堆栈设置了值。重新编译一下烧写到开发板,当我们按下相应的按键的时候,可以看到对应的LED灯亮了。如果按下第一下可以亮,接着按按键没有反应,很有可能是堆栈没有设置好。

    这就是6410的中断处理流程,对于210也是一样的操作,只是210默认是打开向量中断的,不必去设置打开,其他都是一样的。

  • 相关阅读:
    404页面应该怎么做?
    网站被百度和google封了,怎么办?
    如何下载没有提供下载按钮的网页视频
    新手学习.net编程计划-1
    windows7旗舰版下载出现蓝屏代码50怎么办?
    微软已于10月底停止销售预装Windows 7/8.1的电脑
    Html代码seo优化最佳布局实例讲解
    下载类网站的SEO优化方面技巧
    命名空间“System.Windows.Forms”中不存在类型或命名空间名称“DataVisualization”。是否缺少程序集引用?
    SQL、LINQ、Lambda 三种用法(转)
  • 原文地址:https://www.cnblogs.com/FORFISH/p/5188795.html
Copyright © 2011-2022 走看看