今天在捅咕我的那个悲催的2440开发板,对于飞凌的程序我一点也不想看,,通过一天的阅读2440的中文手册,终于明白了他的所有寄存器的几个重要操作。
首先,要请求中断源,这里面有三个寄存器很重要SRCPND ,INTMSK和 INTPND 。在中断初始化的时候要把相应中断的标志位置位,由于Eint0,1,2,3是正常的,EINT4以后都是复用的,所以还要配置EINTPEND 和EINTMASK来选择是用具体的哪个中断。EXTINT0是GPIO设备下的一个特殊寄存器,他的每三个用来表示一个中断源所使用的触发模式。这里我们都选择01x的模式。好了,到这里初始化工作做完了。
然后,我们就要写中断服务函数了。下面是中断函数的中断向量地址。这是很重要的。
/* 2440中断向量表 */
#define _ISR_STARTADDRESS 0x33ffff00
#define U32 unsigned int
// Exception vector
#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))
#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))
#define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8))
#define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xc))
#define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10))
#define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14))
#define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18))
#define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1c))
// Interrupt vector
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT3 (*(unsigned *)(_ISR_STARTADDRESS+0x2c))
#define pISR_EINT4_7 (*(unsigned *)(_ISR_STARTADDRESS+0x30))
#define pISR_EINT8_23 (*(unsigned *)(_ISR_STARTADDRESS+0x34))
#define pISR_CAM (*(unsigned *)(_ISR_STARTADDRESS+0x38)) // Added for 2440.
#define pISR_BAT_FLT (*(unsigned *)(_ISR_STARTADDRESS+0x3c))
#define pISR_TICK (*(unsigned *)(_ISR_STARTADDRESS+0x40))
#define pISR_WDT_AC97 (*(unsigned *)(_ISR_STARTADDRESS+0x44)) //Changed to pISR_WDT_AC97 for 2440A
#define pISR_TIMER0 (*(unsigned *)(_ISR_STARTADDRESS+0x48))
#define pISR_TIMER1 (*(unsigned *)(_ISR_STARTADDRESS+0x4c))
#define pISR_TIMER2 (*(unsigned *)(_ISR_STARTADDRESS+0x50))
#define pISR_TIMER3 (*(unsigned *)(_ISR_STARTADDRESS+0x54))
#define pISR_TIMER4 (*(unsigned *)(_ISR_STARTADDRESS+0x58))
#define pISR_UART2 (*(unsigned *)(_ISR_STARTADDRESS+0x5c))
#define pISR_LCD (*(unsigned *)(_ISR_STARTADDRESS+0x60))
#define pISR_DMA0 (*(unsigned *)(_ISR_STARTADDRESS+0x64))
#define pISR_DMA1 (*(unsigned *)(_ISR_STARTADDRESS+0x68))
#define pISR_DMA2 (*(unsigned *)(_ISR_STARTADDRESS+0x6c))
#define pISR_DMA3 (*(unsigned *)(_ISR_STARTADDRESS+0x70))
#define pISR_SDI (*(unsigned *)(_ISR_STARTADDRESS+0x74))
#define pISR_SPI0 (*(unsigned *)(_ISR_STARTADDRESS+0x78))
#define pISR_UART1 (*(unsigned *)(_ISR_STARTADDRESS+0x7c))
#define pISR_NFCON (*(unsigned *)(_ISR_STARTADDRESS+0x80)) // Added for 2440.
#define pISR_USBD (*(unsigned *)(_ISR_STARTADDRESS+0x84))
#define pISR_USBH (*(unsigned *)(_ISR_STARTADDRESS+0x88))
#define pISR_IIC (*(unsigned *)(_ISR_STARTADDRESS+0x8c))
#define pISR_UART0 (*(unsigned *)(_ISR_STARTADDRESS+0x90))
#define pISR_SPI1 (*(unsigned *)(_ISR_STARTADDRESS+0x94))
#define pISR_RTC (*(unsigned *)(_ISR_STARTADDRESS+0x98))
#define pISR_ADC (*(unsigned *)(_ISR_STARTADDRESS+0x9c)
定义完中断向量,我们就要真正的写中断服务函数了。首先有一个关键字 __irq 这是我们使用中断服务函数的关键。格式为:static void __irq Key0_ISR(void) //EINT0。
然后根据手册里面的要求,我们需要把 SRCPND 和INTPND相应位写“1”清零。这是我们中断服务函数出去的关键。
剩下的就是主函数,主函数里面我们要先初始化所需要的GPIO口,在 GPFCON中将用到的IO配置成10为EINT模式即可。然后调用中断的句柄函数为:pISR_EINT0 = (U32)Key0_ISR;这样一个外部中断就配置好了.
具体代码实现如下:
/**************************************************************************
*
* 以下为底层功能函数
*
*地点:长春理工大学
*
*作者:于清章
*
*时间:2012年09月26号
*
****************************************************************************/
#include"BSP.h"
#include<stdio.h>
#include<stdarg.h>
#include"2440slib.h"
/* 中断服务函数*/
static void __irq Key0_ISR(void) //EINT0
{
int led;
rSRCPND = rSRCPND | 0x1;
rINTPND = rINTPND | 0x1;//要写1清零!!
GPBDAT=(1<<10);
GPBDAT=~(1<<5);//LED1输出低电平
Uart_Printf("按键2\n");
}
static void __irq Key2_ISR(void) //EINT2
{
int led;
rSRCPND = rSRCPND | (0x1<<2);
rINTPND = rINTPND | (0x1<<2);//要写1清零!!
GPBDAT=(1<<5);//LED1输出低电平
GPBDAT=~(1<<6);//LED1输出低电平
Uart_Printf("按键3\n");
}
static void __irq Key3_ISR(void) //EINT3
{
int led;
rSRCPND = rSRCPND | (0x1<<3);
rINTPND = rINTPND | (0x1<<3);//要写1清零!!
GPBDAT=(1<<6);//LED1输出低电平
GPBDAT=~(1<<8);//LED1输出低电平
Uart_Printf("按键4\n");
}
static void __irq Key4_ISR(void) //EINT4-7
{
int led;
rSRCPND = rSRCPND | (0x1<<4);
rINTPND = rINTPND | (0x1<<4);//要写1清零!!
if(rEINTPEND&(1<<4))
{
rEINTPEND = rEINTPEND | (0x1<<4);
GPBDAT=(1<<8);//LED1输出低电平
GPBDAT=~(1<<10);//LED1输出低电平
Uart_Printf("按键5\n");
}
}
/***********************Main*********************************/
int LeMain()
{
/*********************变量定义*******************************/
unsigned char y;
bsp();
GPFCON = 0xfeae;//GPF0 [1:0] 00 = 输入 01 = 输出 10 = EINT[0] 11 = 保留
//1111111010101110
Interrupt_Configuration();
Uart_Printf("/**********************************************************/\n");
Uart_Printf("/*电子学会*/\n");
Uart_Printf("/**********************************************************/\n");
/**********************循环点灯******************************/
ChangeClockDivider(2,1);
ChangeMPllValue(127,2,1); //405MHZ
pISR_EINT0 = (U32)Key0_ISR;//外部中断0的句柄
pISR_EINT2 = (U32)Key2_ISR;
pISR_EINT3 = (U32)Key3_ISR;
pISR_EINT4_7 = (U32)Key4_ISR;
//watchdog_test();
while(1)
{
///Beep_off();
//Led_turn();
///Beep_on();
// Key_scan();
//ADC_Getvalue();
//if(WTCNT<100)
//{
// WTCNT=10000;
//
//
//Uart_Printf("计数器值--%x\n",rMPLLCON);
//WTDAT=18000; //给看门狗数值寄存器赋值
//Uart_Printf("进入喂狗阶段");
}
return(0);
}