• 按键中断---那些年我们一起玩mini2440(arm9)裸机


    ARM中断控制系统

    按键驱动程序设计

    一.Arm中断控制系统

    1.查询方式

    程序不断地查询设备的状态,并做出相应的反应。该方式实现比较简单,常用在比较单一的系统中,比如:一个温控系统中可以实用查询的方式不断检测温度变化。

    特点:实现简单;但CPU利用率很低,不适合多任务的系统。

    2.中断方式

    当事件发生时,硬件会设置某个寄存器;CPU在每执行完一个指令时,查看这个寄存器,如果所关注的事件发生了,则中断当前程序,跳转到一个固定的地址处理这个事件,处理完后返回到被中断的程序中继续运行。

    特点:实现相对复杂,但效率较高,是常用的方法。

     

    中断处理流程:

    (1)中断控制器汇集各类外设发出的中断信号然后通知CPU;

    (2)CPU保存当前程序的运行环境然后调用中断服务程序ISR来处理中断

    (3)ISR中通过读取外设的相关寄存器来识别中断的类型,并进行相应的处理

    (4)清除中断:通过读写在相关中断控制寄存器和外设相关寄存器来实现;

    (5)恢复被中断程序的执行环境继续执行被中断的程序。

     

    简化版:

    1.汇集中断信号,通知CPU;

    2.CPU保存当前运行环境,调用中断服务程序ISR

    3.ISR读取寄存器识别中断类型

    4.清中断 

    5.恢复中断程序的执行环境;

    速记版:会(汇集)CCPUI(IRS)(清中断)回复(恢复);

    S3c2440支持60个中断源,含子中断源

    SUBSRCPND(用于标明子中断源有没有发生中断)【发生中断被置1清除子中断写入1

    SUBSRCPND寄存器用来表明子中断(如:INT_RXD0是否发生。S3C244015个子中断,SUBSRCPND中每一位对应一个子中断,当这些子中断发生时,相应的位置被置1.清除子中断只需向SUBSRCPND寄存器中相应位写入1.

     

    INTSUBMSK屏蔽SUBSRCPND的中断,1时屏蔽子中断

    INTSUBMSK寄存器用来屏蔽SUBSRCPND寄存器所标的中断。INTSUBMSK

    寄存器中某位被设为1时,相应的子中断被屏蔽。设为0时,表示子中断被允许。

     

    SRCPND(用于标明中断源有没有发生中断)【发生中断被置1清除(子)中断写入1

    SRCPND某一位用来标明一个(或一类)中断是否已经发生。例如:SRCPND

    寄存器中的子中断INT_RXD0发生了,且没有被INTSUBMSK屏蔽,则SRCPNDINT_UART0位被置1. SRCPND寄存器的清除与SUBSRCPND寄存器相似,若想清除某一位,往此位写入1.

     

    INTMSK(被置1时,中断屏蔽; 0时,中断允许)

    INTMSK寄存器用来屏蔽SRCPND所表示的中断。INTMSK某位被置为1时,对应的中断被屏蔽;设置为0时,相应中断被允许。

    INTMSK只能屏蔽设为IRQ的中断,不能屏蔽设为FIQ的中断。

     

    INTMODE1时,FIQ模式;  0时,IRQ模式

    INTMODE寄存器中某位被设置为1时,它所对应的中断源会被设置为FIQ模式,即此时中断发生时,      CPU将进入快速中断模式,这通常用来处理特别紧急的中断。当该位被置为0时,表示为IRQ模式。

     

    FIQ & IRQ

    (1)   IRQ模式下,中断处理程序需要自己保存R8R12这几个寄存器,退出中断处理时需要自己恢复这几个寄存器,而FIQ模式由于这几个寄存器都有back寄存器(fiq_r8….,模式切换时CPU自动保存这些值到back寄存器,退出FIQ模式时自动恢复,所以这个过程FIQIRQ快。

    (2)   FIQIRQ有高的优先级,优先处理FIQ

     pasting

    1. #define    GLOBAL_CLK             1  
    2.   
    3. #include <stdlib.h>  
    4.   
    5. #include <string.h>  
    6.   
    7. #include "def.h"  
    8.   
    9. #include "option.h"  
    10.   
    11. #include "2440addr.h"  
    12.   
    13. #include "2440lib.h"  
    14.   
    15. #include "2440slib.h"  
    16.   
    17. #include "mmu.h"  
    18.   
    19. #include "profile.h"  
    20.   
    21. #include "memtest.h"  
    22.   
    23.    
    24.   
    25. void key_init(void);  
    26.   
    27. static void __irq key_handler(void);  
    28.   
    29. void beep_init(void);  
    30.   
    31. void beep_run(void);  
    32.   
    33. /*************************************************  
    34. Description     : 延时函数  
    35. **************************************************/  
    36.   
    37. void delay(int times)  
    38.   
    39. {  
    40.   
    41.     int i,j;  
    42.   
    43.     for(i=0;i<times;i++)  
    44.   
    45.        for(j=0;j<400;j++);  
    46.   
    47. }  
    48.   
    49. /*************************************************  
    50. Description     : 主功能函数  
    51. **************************************************/  
    52.   
    53. void Main(void)  
    54.   
    55. {       
    56.   
    57.    beep_init();//设置对应端口为输出  
    58.   
    59.    MMU_Init(); //  
    60.   
    61.    key_init();  
    62.   
    63.    while(1);  
    64. }       
    65.   
    66. /*************************************************  
    67. Description     : 按键K1的初始化函数  
    68. **************************************************/  
    69.   
    70. void key_init(void)  
    71.   
    72. {  
    73.   
    74.     rGPGCON &= ~(0x3<<0);     /*set eint8 as interrupt*/  
    75.   
    76.     rGPGCON |=  (0x2<<0);  
    77.   
    78.       
    79.   
    80.     rEXTINT1 &= ~(0xf<<0);   /*set eint8 with low level*外部中断控制寄存器*/  
    81.   
    82.     rEINTPEND |= (1<<8);  //写1清EINT8中断   /*外部中断待定寄存器*/
    83.   
    84.     rEINTMASK &= ~(1<<8); //使能中断不屏蔽  /*外部中断屏蔽寄存器*/
    85.   
    86.       
    87.   
    88.     /*设置ISR*/  
    89.   
    90.     pISR_EINT8_23=(U32)key_handler;  //按键按下就会执行相应的中断函数
    91.   
    92.     EnableIrq(BIT_EINT8_23); //8-23共用一个中断号  /使能相应中断
    93.   
    94. }      
    95. /*************************************************  
    96. Description     : 按键K1的中断服务子程序  
    97. **************************************************/  
    98.   
    99. static void __irq key_handler(void)  
    100.   
    101. {  
    102.   
    103.        /*判断是否是按键K1产生的中断*/  
    104.   
    105.     if(rINTPND==BIT_EINT8_23) //rINTPND判断中断是否被响应,1响应;0不响应  
    106.   
    107.     {  
    108.   
    109.               ClearPending(BIT_EINT8_23); /进入中断处理函数第一件事就是清中断,如果不清中断无法产生下次中断 
    110.   
    111.               if(rEINTPEND&(1<<8))//外部中断相应位来判断对应寄存器是否发生中断,EINT8是否发生中断  
    112.   
    113.               {  
    114.   
    115.                      rEINTPEND |= 1<< 8;//清中断EINT8  
    116.   
    117.                      beep_run();  
    118.   
    119.               }  
    120.   
    121.        }  
    122.   
    123. }  
    124.   
    125. /*************************************************  
    126. Description     : 初始化蜂鸣器  
    127. **************************************************/  
    128.   
    129. void beep_init(void)//设置IO为输出  
    130.   
    131. {  
    132.   
    133.     rGPBCON &= ~(0x3<<0);  
    134.   
    135.     rGPBCON |=  (0x1<<0);  
    136.   
    137. }  
    138.   
    139. /*************************************************  
    140. Description     : 运行蜂鸣器  
    141. **************************************************/  
    142.   
    143. void beep_run(void)  
    144.   
    145. {  
    146.   
    147.     rGPBDAT |= (0x1<<0);  
    148.   
    149.     delay(50);  
    150.   
    151.     rGPBDAT &= (0x0<<0);  
    152.   
    153.     delay(50);  
    154.   
    155. }  

  • 相关阅读:
    缺省参数的注意事项
    可变和不可变类型
    Python之旅
    BBS项目 个人界面分类,文章,模板的使用详解
    Django 模板
    BBS项目 部分主界面and个人博客界面代码详解
    BBS项目 注册界面and部分首页代码详解
    BBS项目 备忘时时更新
    BBS项目 登录界面代码详解
    BBS项目 基本表关系
  • 原文地址:https://www.cnblogs.com/liuchengchuxiao/p/4150532.html
Copyright © 2020-2023  润新知