ARM系统中断产生流程
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;代码结束
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");
}
handle_irq.c:
中断处理函数,查出中断源,中断处理,清除中断源。
ARM系统中断产生流 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)