您的位置:首页 > 其它

s3c2440-外部中断

2016-03-30 23:02 302 查看
s3c2440 的cpu有7种中断模式

1,user

2,fiq

3,irq

4,svc

5,abt

6,sys

7,und

一般的运行模式是user,当cpu发生什么其他情况时,就进入对应的工作模式,比如快速中断fiq,或者是普通中单irq。

当Without sub -register 中断触发之后,SRCPND相应位会被置1在没有被INTMSK屏蔽或者不是fiq(快速中断),

一般的中断都属于srcpnd模式,只有串口,can中断属于sub模式

当with sub -register触发之后,subsrcpnd寄存器相应位被置1,如果没有被intsubmsk寄存器屏蔽,他在srcpnd中也会被置1

在中断没有被屏蔽之后,会在intpnd寄存器中被置1,中断服务程序可以读取intpnd或者intoffset来判断中断源

中断的优先级是在PRIORITY中进行设置,

PRIORITY的前6位表示6个次级筛选,后面的26位分别表示次级筛选器的优先级数值,

其中数值有4种情况,00,01,10,11,分别表示不同的排序,0一直在5的前面。只有1234再排序,(妈的markdown不方便上图)

在中断发生之后,需要清除中断,中断的清除可以在中断函数之前也可以在之后,这取决于程序的需要,不过我建议在之前,没啥。

而中断清除的顺序也是控制好的,先清除源头,

一般是 subsrcpnd-srcpnd-intpnd(往里面写1就好了)最简单的方法是(intpnd=intpnd)

intmod可以设置fiq和irq,把相应的位置设置为1就是设置fiq的使能,如果是irq则配置优先级(RIORITY),也可以不设置

subsrcpnd:sub模式下中断响应寄存器,

intsubmsk:sub模式下中断屏蔽寄存器

srcpnd:中断响应寄存器

intmsk:中断屏蔽寄存器,某一位别置1时,中断被屏蔽(初始0xffffffff)

intmod:中断类型设置寄存器,可以设置fiq(只有一个,且是置1)

intpnd:中断标志寄存器,可以从中读取到中断源

intoffset:用于表示intpnd寄存器中是那个位被置1,

又上总结具体的中断初始化模式如下:

1,设置mode,

intmod 相应的位置1表示这个中断是快速中断,其余置0,表示irq

2,更据相应的中断设置msk

intmsk:置0表示使能,置1表示禁止,初始是0xffffff

intpubmsk:置0表示使能,置1表示禁止,初始是0xffffff

3,设置中断优先级,

这个可以不做,采用默认模式也可以

4,编写中断函数,

通过关键之 __irq 定义中断运行函数

5,判断中断源

使用intpnd或者intoffset判断相应的中断源。

6,发送中断之后清除中断

优先清除subsrcpnd(如果有)

然后是srcpnd

然后是intpnd

/*
time:2016-03-29,
change:创建文件,GPIO.c  GPIO.h
auther:wxc
*/

#include <S3C2440.H>

#define _ISR_STARTADDRESS 0x33ffff00

#define U32 unsigned int
#define pISR_EINT            (*(unsigned *)(_ISR_STARTADDRESS+0x20))

#define uint_8 unsigned char
#define uint_32 unsigned int
#define GPIO volatile unsigned long*

#define OUT 1
#define IN 0
#define false 0
#define true 1

#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
/*
功能:
参数:
返回:
*/

/*
功能:延时函数
参数:延时时间
返回:无
*/
void delay_ms(uint_32 time)
{
int j= 5000;
for(;time>0;time--)
{
for(;j>0;j--)
;
}
}

/*
功能:设置引脚方向
参数:GPx引脚类型,con 引脚方向,flag引脚值
返回:是否设置成功
*/
int GPIO_CON(GPIO GPx,int con,int flag)
{
if(flag<0||flag>16)
{
return false;
}

*GPx |= con<<(flag*2);
return true;
}
/*
功能:获取引脚值
参数:GPx引脚类型,flag引脚值
返回:返回数据
*/
int getGPIO_DAT(GPIO GPx,int flag)
{
return (*GPx&(1<<flag))>>flag;
}

/*
功能:设置引脚值
参数:GPx引脚类型,con引脚值,flag引脚位置
返回:设置成功
*/
int setGPIO_DAT(GPIO GPx,int con,int flag)
{
if(con>2)
{
return false;
}
if(con == OUT)
*GPx = (*GPx|(1<<flag));
else
*GPx = (*GPx&~(1<<flag));
return true;
}
/*
功能:初始化引脚功能函数
参数:
返回:
*/
void initPin()
{
int bool=0;
bool = GPIO_CON(&GPBCON,OUT,5);
bool = GPIO_CON(&GPBCON,OUT,6);
bool = GPIO_CON(&GPBCON,OUT,7);
bool = GPIO_CON(&GPBCON,OUT,8);
GPIO_CON(&GPGCON,2,0);
GPIO_CON(&GPGCON,2,3);
GPIO_CON(&GPGCON,2,5);
GPIO_CON(&GPGCON,2,6);
GPIO_CON(&GPGCON,2,7);
GPIO_CON(&GPGCON,2,11);

}

/*
功能:中断函数
参数:
返回:
*/
void __irq EINT8_19()
{
int obj=0,i=0;
int led_array[6] = {0,3,5,6,7,11};
/*清除中断信号*/
obj = INTOFFSET;
SRCPND |= (1<<obj); //清除外部中断8~23中断信息
INTPND |= (1<<obj);
//获取外部中断中断源
obj = EINTPEND;
for(i=8;i<20;i++)
{
if(obj &(1<<i)) //判断这个位有没有触发中断
{
setGPIO_DAT(&GPBDAT,0,7);
EINTPEND |= 1<<i;
}
}

}
/*
功能:初始化中断函数
参数:
返回:
*/
void initIrq()
{
INTMSK &= ~(1<<5);     //使能8~23外部中断
EINTMASK &= ~(1<<8|1<<11|1<<13|1<<14|1<<15|1<<19); //使能8 11 13 14 15 19外部中断
//没有设置优先级,没有设置fiq,没有设置触发模式

pISR_EINT = (U32)EINT8_19; //设置外部中断运行函数
}

//点个灯玩玩
int main()
{
int ledIndex = 5;
int bool=0;
initPin();
while(1)
{
//      GPBDAT &= ~(3<<5);
bool = setGPIO_DAT(&GPBDAT,1,ledIndex);
delay_ms(10000);
bool = setGPIO_DAT(&GPBDAT,0,ledIndex);
//      setGPIO_DAT(GPBCON,0,ledIndex);
delay_ms(10000);
if(ledIndex++>8)
{
ledIndex = 5;
}
}
return false;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: