mini2440按键中断
来源:互联网 发布:音乐制作软件手机版 编辑:程序博客网 时间:2024/06/14 20:13
ARM中断控制系统
按键驱动程序设计
一.Arm中断控制系统
1.查询方式
程序不断地查询设备的状态,并做出相应的反应。该方式实现比较简单,常用在比较单一的系统中,比如:一个温控系统中可以实用查询的方式不断检测温度变化。
特点:实现简单;但CPU利用率很低,不适合多任务的系统。
2.中断方式
当事件发生时,硬件会设置某个寄存器;CPU在每执行完一个指令时,查看这个寄存器,如果所关注的事件发生了,则中断当前程序,跳转到一个固定的地址处理这个事件,处理完后返回到被中断的程序中继续运行。
特点:实现相对复杂,但效率较高,是常用的方法。
中断处理流程:
(1)中断控制器汇集各类外设发出的中断信号,然后通知CPU;
(2)CPU保存当前程序的运行环境,然后调用中断服务程序(ISR)来处理中断;
(3)在ISR中通过读取外设的相关寄存器来识别中断的类型,并进行相应的处理。
(4)清除中断:通过读写在相关中断控制寄存器和外设相关寄存器来实现;
(5)恢复被中断程序的执行环境,继续执行被中断的程序。
简化版:
1.汇集中断信号,通知CPU;
2.CPU保存当前运行环境,调用中断服务程序ISR
3.ISR读取寄存器识别中断类型
4.清中断
5.恢复中断程序的执行环境;
速记版:会(汇集)C(CPU)I(ISR)请(清中断)回复(恢复);
S3c2440支持60个中断源,含子中断源
SUBSRCPND(用于标明子中断源有没有发生中断)【发生中断被置1,清除子中断写入1】
SUBSRCPND寄存器用来表明子中断(如:INT_RXD0)是否发生。S3C2440有15个子中断,SUBSRCPND中每一位对应一个子中断,当这些子中断发生时,相应的位置被置1.清除子中断只需向SUBSRCPND寄存器中相应位写入1.
INTSUBMSK(屏蔽SUBSRCPND的中断,置1时屏蔽子中断)
INTSUBMSK寄存器用来屏蔽SUBSRCPND寄存器所标的中断。INTSUBMSK
寄存器中某位被设为1时,相应的子中断被屏蔽。设为0时,表示子中断被允许。
SRCPND(用于标明中断源有没有发生中断)【发生中断被置1,清除(子)中断写入1】
SRCPND中某一位用来标明一个(或一类)中断是否已经发生。例如:SRCPND
寄存器中的子中断INT_RXD0发生了,且没有被INTSUBMSK屏蔽,则SRCPND的INT_UART0位被置1. SRCPND寄存器的清除与SUBSRCPND寄存器相似,若想清除某一位,往此位写入1.
INTMSK(被置1时,中断屏蔽; 置0时,中断允许)
INTMSK寄存器用来屏蔽SRCPND所表示的中断。INTMSK某位被置为1时,对应的中断被屏蔽;设置为0时,相应中断被允许。
INTMSK只能屏蔽设为IRQ的中断,不能屏蔽设为FIQ的中断。
INTMODE(置1时,FIQ模式; 置0时,IRQ模式)
当INTMODE寄存器中某位被设置为1时,它所对应的中断源会被设置为FIQ模式,即此时中断发生时,CPU将进入快速中断模式,这通常用来处理特别紧急的中断。当该位被置为0时,表示为IRQ模式。
FIQ & IRQ
(1) IRQ模式下,中断处理程序需要自己保存R8到R12这几个寄存器,退出中断处理时需要自己恢复这几个寄存器,而FIQ模式由于这几个寄存器都有back寄存器(fiq_r8….),模式切换时CPU自动保存这些值到back寄存器,退出FIQ模式时自动恢复,所以这个过程FIQ比IRQ快。
(2) FIQ比IRQ有高的优先级,优先处理FIQ。
- #define GLOBAL_CLK 1
- #include <stdlib.h>
- #include <string.h>
- #include "def.h"
- #include "option.h"
- #include "2440addr.h"
- #include "2440lib.h"
- #include "2440slib.h"
- #include "mmu.h"
- #include "profile.h"
- #include "memtest.h"
- void key_init(void);
- static void __irq key_handler(void);
- void beep_init(void);
- void beep_run(void);
- /*************************************************
- Function name: delay
- Parameter : times
- Description : 延时函数
- Return : void
- Argument : void
- Autor & date : Daniel
- **************************************************/
- void delay(int times)
- {
- int i,j;
- for(i=0;i<times;i++)
- for(j=0;j<400;j++);
- }
- /*************************************************
- Function name: Main
- Parameter : void
- Description : 主功能函数
- Return : void
- Argument : void
- Autor & date : Daniel
- **************************************************/
- void Main(void)
- {
- beep_init();//设置对应端口为输出
- MMU_Init(); //
- key_init();
- while(1);
- }
- /*************************************************
- Function name: key_init()
- Parameter : void
- Description : 按键K1的初始化函数
- Return : void
- Argument : void
- Autor & date : Daniel
- **************************************************/
- void key_init(void)
- {
- rGPGCON &= ~(0x3<<0); /*set eint8 as interrupt*/
- rGPGCON |= (0x2<<0);
- rEXTINT1 &= ~(0xf<<0); /*set eint8 with low level*/
- rEINTPEND |= (1<<8); //写1清EINT8中断
- rEINTMASK &= ~(1<<8); //使能中断不屏蔽
- /*设置ISR*/
- pISR_EINT8_23=(U32)key_handler;
- EnableIrq(BIT_EINT8_23); //8-23共用一个中断号
- }
- /*************************************************
- Function name: key_handler()
- Parameter : void
- Description : 按键K1的中断服务子程序
- Return : void
- Argument : void
- Autor & date : Daniel
- **************************************************/
- static void __irq key_handler(void)
- {
- /*判断是否是按键K1产生的中断*/
- if(rINTPND==BIT_EINT8_23) //rINTPND判断中断是否被响应,1响应;0不响应
- {
- ClearPending(BIT_EINT8_23);
- if(rEINTPEND&(1<<8))//外部中断相应位来判断对应寄存器是否发生中断,EINT8是否发生中断
- {
- rEINTPEND |= 1<< 8;//清中断EINT8
- beep_run();
- }
- }
- }
- /*************************************************
- Function name: beep_init()
- Parameter : void
- Description : 初始化蜂鸣器
- Return : void
- Argument : void
- Autor & date : Daniel
- **************************************************/
- void beep_init(void)//设置IO为输出
- {
- rGPBCON &= ~(0x3<<0);
- rGPBCON |= (0x1<<0);
- }
- /*************************************************
- Function name: beep_run()
- Parameter : void
- Description : 运行蜂鸣器
- Return : void
- Argument : void
- Autor & date : Daniel
- **************************************************/
- void beep_run(void)
- {
- rGPBDAT |= (0x1<<0);
- delay(50);
- rGPBDAT &= (0x0<<0);
- delay(50);
- }
#define GLOBAL_CLK 1#include <stdlib.h>#include <string.h>#include "def.h"#include "option.h"#include "2440addr.h"#include "2440lib.h"#include "2440slib.h"#include "mmu.h"#include "profile.h"#include "memtest.h" void key_init(void);static void __irq key_handler(void);void beep_init(void);void beep_run(void);/*************************************************Function name: delayParameter : timesDescription : 延时函数Return : voidArgument : voidAutor & date : Daniel**************************************************/void delay(int times){ int i,j; for(i=0;i<times;i++) for(j=0;j<400;j++);}/*************************************************Function name: MainParameter : voidDescription : 主功能函数Return : voidArgument : voidAutor & date : Daniel**************************************************/void Main(void){ beep_init();//设置对应端口为输出 MMU_Init(); // key_init(); while(1); } /*************************************************Function name: key_init()Parameter : voidDescription : 按键K1的初始化函数Return : voidArgument : voidAutor & date : Daniel**************************************************/void key_init(void){ rGPGCON &= ~(0x3<<0); /*set eint8 as interrupt*/ rGPGCON |= (0x2<<0); rEXTINT1 &= ~(0xf<<0); /*set eint8 with low level*/ rEINTPEND |= (1<<8); //写1清EINT8中断 rEINTMASK &= ~(1<<8); //使能中断不屏蔽 /*设置ISR*/ pISR_EINT8_23=(U32)key_handler; EnableIrq(BIT_EINT8_23); //8-23共用一个中断号} /*************************************************Function name: key_handler()Parameter : voidDescription : 按键K1的中断服务子程序Return : voidArgument : voidAutor & date : Daniel**************************************************/static void __irq key_handler(void){ /*判断是否是按键K1产生的中断*/ if(rINTPND==BIT_EINT8_23) //rINTPND判断中断是否被响应,1响应;0不响应 { ClearPending(BIT_EINT8_23); if(rEINTPEND&(1<<8))//外部中断相应位来判断对应寄存器是否发生中断,EINT8是否发生中断 { rEINTPEND |= 1<< 8;//清中断EINT8 beep_run(); } }}/*************************************************Function name: beep_init()Parameter : voidDescription : 初始化蜂鸣器Return : voidArgument : voidAutor & date : Daniel**************************************************/void beep_init(void)//设置IO为输出{ rGPBCON &= ~(0x3<<0); rGPBCON |= (0x1<<0);}/*************************************************Function name: beep_run()Parameter : voidDescription : 运行蜂鸣器Return : voidArgument : voidAutor & date : Daniel**************************************************/void beep_run(void){ rGPBDAT |= (0x1<<0); delay(50); rGPBDAT &= (0x0<<0); delay(50);}
/******************************************************************************
重点分析:
******************************************************************************/
中断控制程序分析:
按键作为中断源
/*************************************************
Function name: key_init()
Parameter : void
Description :按键K1的初始化函数
Return : void
Argument : void
Autor & date : Daniel
**************************************************/
void key_init(void)
{
rGPGCON &= ~(0x3<<0); /*set eint8 as interrupt*/
rGPGCON |= (0x2<<0);
rEXTINT1 &= ~(0xf<<0); /*外部中断控制寄存器set eint8 with low level*/
rEINTPEND |= (1<<8); /*外部中断待定寄存器*/
rEINTMASK &= ~(1<<8); /*外部中断屏蔽寄存器*/
/*设置ISR*/
pISR_EINT8_23=(U32)key_handler; //按键按下就会执行相应的中断函数
EnableIrq(BIT_EINT8_23); //使能相应中断
}
<一>.把GPGCON0作为中断引脚
<二>.把EXTINT1外部中断寄存器1低四位设置全为0;低电平触发中断;
<三>.EINTPEND第8位清中断;判断中断源是否发生;
<四>EINTMASK第8位设为0,不屏蔽中断
/*************************************************
Function name: key_handler()
Parameter : void
Description :按键K1的中断服务子程序
Return : void
Argument : void
Autor & date : Daniel
**************************************************/
static void __irq key_handler(void)
{
/*判断是否是按键K1产生的中断*/
if(rINTPND==BIT_EINT8_23)
{
ClearPending(BIT_EINT8_23); //进入中断处理函数第一件事就是清中断,如果不清中断无法产生下次中断
if(rEINTPEND&(1<<8))
{
rEINTPEND |= 1<< 8;
beep_run();
}
}
}
转自:http://blog.csdn.net/yx_l128125/article/details/7697280
- mini2440按键中断
- MINI2440按键中断
- MINI2440按键中断
- mini2440 按键中断LED 实验
- mini2440按键中断和LED gpio
- mini2440 基于中断的按键驱动
- mini2440 简单按键中断模式驱动程序
- 关于mini2440按键中断的配置
- 基于mini2440外部中断的按键驱动
- mini2440按键中断控制led灯遇到的问题
- 按键中断---那些年我们一起玩mini2440(arm9)裸机
- 中断驱动设计----mini2440 按键驱动设计之路
- 基于mini2440的按键中断控制LED(裸机代码)
- Mini2440 裸机实验之LED程序、按键、中断
- 基于中断的linux按键驱动(mini2440)
- 按键中断
- 按键中断
- 按键 中断
- 网站设计
- 常见证书格式及转换
- 利用GDAL和QWT绘制图像直方图2--QWT绘制直方图
- MongoDB数据库文档大全(第7-9讲)
- 我的第一个c++程序(vs2008下运行)
- mini2440按键中断
- HBase 5种写入数据方式
- 1.LED闪烁实验
- u盘自动挂载-udev
- Bash下Ctrl-C、Ctrl-D和Ctrl-Z的区别
- seam改变CRUD操纵提示信息为中文示例
- MISCA-C
- 约数和公式 及其 证明 。。小学奥数啊 摔~
- 《Mastering Opencv ...读书笔记系列》车牌识别(I)