下边的这段代码是登伟写的,很完美的中断框架,以后就用这个了,站在登伟的肩膀上,嘿嘿。
首先分析下,比较优秀的地方,
先看这段代码:
memcpy(0x0,(unsigned char *)0x30000000,0x1000);
我们知道,在x86系统和一些51核的单片机中,都会维护一个中断向量表,而这个中断向量表一般都会在存储器的开头部分,当中断发生的时候,系统会自动去这段区域进行查找,这段区域的地址是系统默认的,即是不用你自己去设定,只要你在这块规定的区域加入中断服务程序的地址就可以了,而这块区域给中断向量有限的存储空间,只可以放置一些跳转指令,所以只要加入能够跳转到实际的中断服务程序的指令就可以了,我们知道,既然这段挑战是芯片自动完成的,那么在我们的arm系统中,也需要在这块区域填充一些必要的跳转指令,这就是上边这段代码存的在意义了,上边的这个函数将我们自己创建的中断向量表拷贝存储器默认的中断向量表地址,这样就可以顺利的进行中断了。
下边在看看另外一直值得学习的地方,代码如下:
void EXIT_IRQ_init(int num ,void __irq (* Exit_Handler)(void),int type) //这是一个完美的中断设置函数,可以借用。
{ switch(num) { case 0: pISR_EINT0 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT0); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT0); //使能中断
break; case 1: pISR_EINT1 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT1); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT1); break; case 2: pISR_EINT2 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT2); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT2); break; case 3: pISR_EINT3 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT3); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT3); default: break; } }
|
这个中断设置部分,结构很清晰,如果以后需要加入别的中断服务程序,可以仿照这样的写法,可以继续添加,在这个函数中可以完成对中断类型、触发类型、中断服务函数的设置,所以说,可以说是完美的,以后的中断就采用这个函数,当然会做一些的修改。完整的代码如下:
//======================================================================
// 工程名称: Exa_EINT
// 功能描述: 此实验用外部中断0 - EINT0,GPF0为 外部中断信号,本实验采用上升沿触发
// 中断程序中,置位GPF高四位,LED5-8点亮或者熄灭
// IDE环境: ADS v1.2
// 涉及的库: 无
// 组成文件: main.c,
// 2410addr.h, def.h timer.h
// 硬件连接: KA与3.3V相连
// K1与IOB5相连
// J32的COM与GND短接
// 维护记录: 2008-6-25 V1.0 by dengwei
//======================================================================
//====================================================
// 包含头文件区
//====================================================
#include "2410addr.h" //声明S3C2410的寄存器及其常用变量
#include "2410lib.h" #include "option.h" #include "string.h"
void __irq Eint0Handler(void); void EXIT_IRQ_init(int num ,void __irq (* Exit_Handler)(void),int type);
void ClearPending(int bit) { register i; rSRCPND = bit; rINTPND = bit; i = rINTPND; } void ClearSubPending(int bit) { register i; rSUBSRCPND = bit; i = rINTPND; } #define EnableIrq(bit) rINTMSK &= ~(bit) #define DisableIrq(bit) rINTMSK |= (bit)
#define EnableSubIrq(bit) rINTSUBMSK &= ~(bit) #define DisableSubIrq(bit) rINTSUBMSK |= (bit)
//====================================================
// 语法格式:void Main(void)
// 功能描述: 时钟 端口 中断初始化
// 入口参数: 无
// 出口参数: 无
//====================================================
int Main() {
memcpy(0x0,(unsigned char *)0x30000000,0x1000); //拷贝程序到0地址 主要作用是维护中断向量表
SetSysFclk(FCLK_200M); ChangeClockDivider(1,1); rGPFCON=(rGPFCON|0x03)&0xFFFFFFFE; //GPF0设置为EINT0
rGPFUP= rGPFUP | 0x01; //屏蔽 GPF0 上拉功能
rGPFDAT = rGPFDAT & 0xf0; //GPF4,5,6,7 输出高电平
rGPFCON = rGPFCON | 0x5500; //GPF4,5,6,7 设置为输出
rGPFUP = rGPFUP & 0x0F; rGPFDAT = rGPFDAT | 0xf0; //GPF4,5,6,7 输出高电平
EXIT_IRQ_init(0,Eint0Handler,4); while(1); } //====================================================
// 语法格式:void EXIT_IRQ_init(int num)
// 功能描述: 外部中断1~3初始化
// 入口参数:
// num: 中断初始化序号
// Exit_Handler:
// 中断服务程序
// type: 0:低电平触发
// 1:高电平触发
// 2:下降沿触发
// 4:上升沿触发
// 6:双沿触发
// 出口参数: 无
//====================================================
//这个程序的优点是结构清晰,可以在很多的地方应用
void EXIT_IRQ_init(int num ,void __irq (* Exit_Handler)(void),int type) //这是一个完美的中断设置函数,可以借用。
{ switch(num) { case 0: pISR_EINT0 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT0); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT0); //使能中断
break; case 1: pISR_EINT1 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT1); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT1); break; case 2: pISR_EINT2 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT2); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT2); break; case 3: pISR_EINT3 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07); rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT3); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT3); default: break; } } //====================================================
// 语法格式: void __irq Eint0Handler(void)
// 功能描述: 点亮或者熄灭LED5-8 中断函数
// 入口参数: 无
// 出口参数: 无
//====================================================
void __irq Eint0Handler(void) { rGPFDAT = rGPFDAT ^ 0xf0; //端口取反置位
ClearPending(BIT_EINT0); //清除中断标志
}
|
阅读(3059) | 评论(0) | 转发(0) |