S5PV210 中断编程流程 按键中断

一.需掌握知识:
怎样初始化中断,怎样设置一级二级向量表。

二.程序效果:
今天编写interrput程序,预期的实验结果是,在S5PV210开发板上通过按键,以中断的方式实现led闪烁。

三. 常用概念
1.一级向量表:在以下地址寄存器中写入当异常是调用的函数。
#define ABORT_UNDEFINED_TABLE ((volatile unsigned int*)0XD0037404)
#define ABORT_RESET_TABLE ((volatile unsigned int*)0XD0037400)
#define ABORT_SOFTWARE_TABLE ((volatile unsigned int*)0XD0037408)
#define ABORT_PREFETCH_TABLE ((volatile unsigned int*)0XD003740c)
#define ABORT_DATA_TABLE ((volatile unsigned int*)0XD0037410)
#define ABORT_IRQ_TABLE ((volatile unsigned int*)0XD0037418)
#define ABORT_FIQ_TABLE ((volatile unsigned int*)0XD003741c)

2.ISR:Interrput Server Routing,中断服务程序。
3.S5PV210一共有128个中断源。

四.程序执行的过程
1.烧写程序,按下K1,产生IRQ。
2.从一级向量表中找到指定的函数。
3.通过对寄存器的读取,得到之前写好的ISR,执行。

五.编程思路
1.第一步查看芯片手册interrput章节,浏览其中所有的寄存器描述。
2.第二步根据寄存器描述写出初始化中断的函数。
3.第三步写出提供给其他模块中断设置的函数。例如(中断源使能,中断源模式选择,中断源服务程序绑定等)
4.第四步查看芯片手册key章节,浏览key和中断相关的寄存器,浏览其寄存器的描述。结合第三步写出key中断初始化函数。
5.调用初始化函数,查看功能时候实现。

六.相关寄存器
中断一二级向量表初始化:
VICIRQSTATUS:查看哪个中断源发出中断请求。
VICADDRESS:当前活动的服务程序,服务程序后清除。
A read of this register returns the address of the ISR and sets
the current interrupt as being serviced. A read must be
performed while there is an active interrupt.
A write of any value to this register clears the current interrupt.
A write must only be performed at the end of an interrupt
service routine.

中断中断源设置模块:
VICCECTADDR:Contains ISR vector addresses.
VICINTSELECT:中断源选择中断类型(IRQ,FIQ)
VICINTENABLE,VICINTENCLEAR:使能和关闭中断源。(总开关)

按键中断初始化:
rGPH2CON :  按键的引脚功能设置为中断。
*EXT_INT_2_CON : 中断设置触发方式(高,低电平)(下降沿,上升沿)。
*EXT_INT_2_MASK :使能对应中断源的中断。 (分开关)
*EXT_INT_2_PEND :查看具体中断源。判断具体哪个按键按下。

七.主程序和相关函数
1.主函数
int xmain()
{
init_led();
*rGPJ2DAT = 0x00;

init_interrput();
init_itr_key();

close_buzzer();
while(1)
{
}
return 0;

}

2.//查询方式和串口通讯。
void init_uart()
{
//将特定的GPIO口设置为UART模式。
*GPA0CON = 0x22;
*UFCON0 = 0x0;
*UMCON0 = 0x0;

*ULCON0 = (3<<0)|(0<<2)|(0<<5)|(0<<6);
*UCON0 = (1<<0)|(1<<2)|(1<<8)|(1<<9)|(0<<10);
//(66700000/(115200*16)  -1)
*UBRDIV0 = 35;
*UDIVSLOT = 0x888;
}

3.ISR和按键中断初始化
void ISR_key(void)
{
//中断发生位,判断是具体那个按键发出的中断
if( (*EXT_INT_2_PEND & (1<<0)) == 0x1)
{
*rGPJ2DAT = ~(*rGPJ2DAT);
*EXT_INT_2_PEND = *EXT_INT_2_PEND | 0x01;
}
else
{
*EXT_INT_2_PEND = 0xff;
}
}
void init_itr_key()
{
//设置中断方式,下降沿触发
*EXT_INT_2_CON = 0x2;
//使能中断源16
*EXT_INT_2_MASK = 0x0;

*rGPH2CON = 0xf;
set_ISR_itr(16,ISR_key);
set_type_itr(16,0);
set_enable_itr(16);
}
4.中断相关的函数
/**************  interrput ********************/
static void init_abort_table();
static void clear_address();
static void clear_enable();

//interrput中断初始化函数
void init_interrput()
{
init_abort_table();
clear_address();
clear_enable();
}
//初始化一级异常中断向量表
extern void IRQ_handle(void);
static void init_abort_table()
{
*ABORT_IRQ_TABLE = (volatile unsigned int)IRQ_handle;
}
//二级异常向量处理函数,设置执行ISR的程序
void irq_hdle(void)
{
volatile unsigned int i = 0;
ISR_fun f;
volatile unsigned int* vicAdd[]={VICADRESS0,VICADRESS1,VICADRESS2,VICADRESS3};
volatile unsigned int* vicStatus[]={VICIRQSTATUS0,VICIRQSTATUS1,VICIRQSTATUS2,VICIRQSTATUS3};
for(i=0;i<4;++i)
{
if( *(vicStatus[i]) != 0x00)
{

f = (ISR_fun)(*vicAdd[i]);
f();
}
*(vicAdd[i]) = 0x0;
}

}
//清除中断寄存器
static void clear_address()
{
*VICADRESS0 = 0XFFFFFFFF;
*VICADRESS1 = 0XFFFFFFFF;
*VICADRESS2 = 0XFFFFFFFF;
*VICADRESS3 = 0XFFFFFFFF;
}
//关闭所有中断
static void clear_enable()
{
*VICINTCLEAR0 = 0XFFFFFFFF;
*VICINTCLEAR1 = 0XFFFFFFFF;
*VICINTCLEAR2 = 0XFFFFFFFF;
*VICINTCLEAR3 = 0XFFFFFFFF;
}
//使能相应的中断
void set_enable_itr(unsigned int no)
{
volatile unsigned int i = 0;
volatile unsigned int row = 0;
volatile unsigned int col = 0;
i=no;
if(no < 128)
{
row = i/32;
col = i%32;
volatile unsigned int* virEnable[] = {VICINTENABLE0,VICINTENABLE1,VICINTENABLE2,VICINTENABLE3};
*(virEnable[row]) &= ~(1 << col); //对应位清0
*(virEnable[row]) |= (1 << col); //对应位至1
}
}
//设置中断源类型
void set_type_itr(unsigned int no,unsigned int type)
{
volatile unsigned int* virType[] = {VICINTSELECT0,VICINTSELECT1,VICINTSELECT2,VICINTSELECT3};
volatile unsigned int row = 0;
volatile unsigned int col = 0;
row = no/32;
col = no%32;
if(no < 128)
{
*(virType[row]) &= ~(1 << col); //对应位清0
*(virType[row]) |= ((type?1:0) << col); //对应位至1
}

}
//设置中断服务程序isr
void set_ISR_itr(unsigned int no,ISR_fun f)
{
volatile unsigned int* virISR[] = {VICVECTADDR0,VICVECTADDR1,VICVECTADDR2,VICVECTADDR3};
volatile unsigned int row = 0;
volatile unsigned int col = 0;
row = no/32;
col = no%32;
 
if(no < 128)
{
*(virISR[row] + col) = (volatile unsigned int)f;
}

}

你可能感兴趣的:(嵌入式裸机开发)