微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM系统中断产生流程

ARM系统中断产生流程

时间:11-20 来源:互联网 点击:

uart_init
bluart_init; UART串口初始化

IMPORT irq_init
blirq_init;系统中断初始化

IMPORT key_init
blkey_init;按键初始化

IMPORT led_init
blled_init; LED灯初始化

msrcpsr_cxsf, #0xd2;切换到中断模式下
ldrsp,=0x31000000;设置中断模式栈指针

msrcpsr_cxsf, #0x13;返回管理模式

ldrlr,=halt_loop;设置管理模式下返回地址
IMPORT main
ldrpc,=main;跳入主函数main里执行
;***********************************************************************
;中断处理
;***********************************************************************
HandleIRQ
sublr,lr,#4;修正返回地址
stmdbsp!,{r0-r12,lr};保存程序执行现场
ldrlr,=int_return;设置中断处理程序返回地址
IMPORT handle_irq
ldrpc,=handle_irq;跳入中断处理程序

int_return;中断处理返回标签
ldmiasp!,{r0-r12,pc}^恢复程序执行现场,返回继续执行

halt_loop
bhalt_loop

initmem
ldrr0, =0x48000000
ldrr1, =0x48000034
;ldrr2, =memdata
adrr2, memdata
initmemloop
ldrr3, [r2], #4
strr3, [r0], #4
teqr0, r1
bneinitmemloop
movpc,lr

memdata
DCD0x22000000;BWSCON
DCD0x00000700;BANKCON0
DCD0x00000700;BANKCON1
DCD0x00000700;BANKCON2
DCD0x00000700;BANKCON3
DCD0x00000700;BANKCON4
DCD0x00000700;BANKCON5
DCD0x00018005;BANKCON6
DCD0x00018005;BANKCON7
DCD0x008e07a3;REFRESH
DCD0x000000b1;BANKSIZE
DCD0x00000030;MRSRB6
DCD0x00000030;MRSRB7

END;代码结束

该程序主要设置异常向量表,除了Reset异常和中断处理被处理以外,其它异常都未被处理,如果发生时,会产生死循环,Reset异常里主要实现了硬件的基本初始化,如:按键,LED灯等,设置栈指针,用于执行C程序,最后跳入C程序的main函数。在中断处理异常处理中首先修正返回地址,保存用户执行现场,跳入到中断处理例程中执行。
sys_init.c:
硬件初始化文件,里面包含LED,KEY的初始化函数。

#include "register.h"
#include "comm_fun.h"

#defineTXD0READY(1<2)//发送数据状态OK
#defineRXD0READY(1)//接收数据状态OK

/* UART串口初始化*/
void uart_init()
{
GPHCON |= 0xa0;//GPH2,GPH3 used as TXD0,RXD0
GPHUP= 0x0;//GPH2,GPH3内部上拉
ULCON0= 0x03;//8N1
UCON0= 0x05;//查询方式为轮询或中断;时钟选择为PCLK
UFCON0 = 0x00;//不使用FIFO
UMCON0 = 0x00;//不使用流控
UBRdiv0 = 12;//波特率为57600,PCLK=12Mhz
}

/* UART串口单个字符打印函数*/
extern void putc(unsigned char c)
{
while( ! (UTRSTAT0 & TXD0READY) );
UTXH0 = c;
}

/* UART串口接受单个字符函数*/
extern unsigned char getc(void)
{
while( ! (UTRSTAT0 & RXD0READY) );
return URXH0;
}

/* UART串口字符串打印函数*/
extern int printk(const char* str)
{
int i = 0;
while( str[i] ){
utc( (unsigned char) str[i++] );
}
return i;
}

/*按键初始化*/
int key_init()
{
//设置K1,K2,K3,K4,K5,K6对应控制寄存器为中断模式
GPGCON = (2<0) | (2<6) | (2<10) | (2<12) | (2<14) | (2<22);
/*
01x falling edge triggered下降沿触发
10x Rising edge triggered上升沿触发
11x Both edge triggered双沿触发
*/
//设置K1,K2,K3,K4,K5按键中断触发方式为上升沿触发
EXTINT1 = (3<0) | (3<12) | (3<20) | (3<24) | (3<28);
EXTINT2 = (3<12);//设置K6按键中断触发方式为上升沿触
printk("按键初始化OK/r/n");
return 0;
}

/* Led1~Led4初始化*/
#define LED1(1<5)//LED1 GPBDAT[5]
#define LED2(1<6)//LED2 GPBDAT[6]
#define LED3(1<7)//LED3 GPBDAT[7]
#define LED4(1<8)//LED4 GPBDAT[8]

/*点亮对应num号led灯*/
extern int led_on(int num)
{
switch(num)
{
case 1:
GPBDAT = GPBDAT & ~LED1; break;
case 2:
GPBDAT = GPBDAT & ~LED2; break;
case 3:
GPBDAT = GPBDAT & ~LED3; break;
case 4:
GPBDAT = GPBDAT & ~LED4; break;
default:
return 0;
}
return num;
}

/*关闭num号led灯*/
extern int led_off(int num)
{
switch(num)
{
case 1:
GPBDAT = GPBDAT | LED1; break;
case 2:
GPBDAT = GPBDAT | LED2; break;
case 3:
GPBDAT = GPBDAT | LED3; break;
case 4:
GPBDAT = GPBDAT | LED4; break;
default:
return 0;
}
return num;
}

/*关闭全部led灯*/
extern int all_led_off(void)
{
GPBDAT = GPBDAT | LED1 | LED2 | LED3 | LED4;
return 0;
}

/* led灯初始化*/
int led_init(void)
{
GPBCON = 0x15400;//设置GPB7为输出口
all_led_off();
printk("led初始化OK/r/n");
return 0;
}

/*中断初始化*/
void irq_init(void)
{
//打开KEY1~KEY6的屏蔽位
INTMSK &= ~(1<5);
EINTMASK &= ~((1<8) | (1<11) | (1<13) | (1<14) | (1<15) | (1<19));
printk("中断初始化OK/r/n");
}

该文件是相关硬件初始化程序,主要包含了看门狗驱动,按键驱动,系统中断驱动,LED驱动。
handle_irq.c:
中断处理函数,查出中断源,中断处理,清除中断源。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top