这是依据韦东山的关于中止的代码改成在mini2440板子上能够运转的代码。
以下是5个文件的一切内容:
@是注释符!!
head.S文件内容:
@**************************************************************************
@ File:head.S
@ 功用:初始化,设置中止形式、体系形式的栈,设置好中止处理函数
@**************************************************************************
.extern main
.text
.global _start
_start:
@**************************************************************************
@ 中止向量,本程序中,除Reset和HandleIRQ外,其他反常都没有运用
@**************************************************************************
@0x00地址处的指令为”b Reset”,在体系复位后,这条指令将跳去履行标号”Reset”开端的代码
b Reset
@0x04:未定义指令停止形式的向量地址
HandleUndef:
b HandleUndef
@0x08:管理形式的向量地址,经过SWI指令进入此形式
HandleSWI:
b HandleSWI
@0x0c:指令预取停止导致的反常的向量地址
HandlePrefetchAbort:
b HandlePrefetchAbort
@0x10:数据拜访停止导致的反常的向量地址
HandleDataAbort:
b HandleDataAbort
@0x14:保存
HandleNotUsed:
b HandleNotUsed
@0x18:中止形式的向量地址
b HandleIRQ
@0x1c:快中止形式的向量地址
HandleFIQ:
b HandleFIQ
Reset:
ldr sp,=4096
@设置栈指针,以下都是C函数,调用前需求设好栈。栈是用 @来保存C函数的变量和回来地址
bl disable_watch_dog @封闭WATCHDOG,不然CPU会不断重启
msr cpsr_c,#0xd2 @进入中止形式
ldr sp,=3072 @设置中止形式的栈指针,这儿的sp存放器是sp_irq
msr cpsr_c,#0xdf @进入体系形式
ldr sp,=4096 @设置体系形式的栈指针,这儿的sp存放器是sp_sys
@其实复位之后,CPU就处于体系形式
@前面的”ldr sp,=4096″完结相同的功用,此句可省掉
bl init_led @初始化LED的GPIO管脚,在init.c中
bl init_irq @调用中止初始化函数,在init.c中
msr cpsr_c,#0x5f @设置I-bit=0,开IRQ中止
ldr lr,=halt_loop @设置回来地址
ldr pc,=main @调用main函数,main函数是个不做任何事的无限循环。当按下按键时,这个循环被打断,CPU进入
@中止形式,履行“b HandleIRQ”的指令
halt_loop:
b halt_loop
HandleIRQ: @HandleIRQ开端的代码用于处理中止
sub lr,lr,#4 @核算中止处理完毕后的回来地址
stmdb sp!,{r0-r12,lr} @保存运用到的存放器
@留意,此刻的sp是中止形式的sp
@初始值是上面设置的3072
ldr lr,=int_return @设置调用ISR即EINT_Handle函数后的回来地址
ldr pc,=EINT_Handle @调用中止服务函数,在interrupt.c中
int_return:
ldmia sp!,{r0-r12,pc}^ @中止回来,^表明将spsr的值复制到cpsr
init.c文件内容:
#define EINTMASK (*(volatile unsigned long*)0x560000a4)//外部中止屏蔽存放器
#define INTMSK (*(volatile unsigned long*)0x4a000008)
#define GPBCON (*(volatile unsigned long*)0x56000010)
#define GPBDAT (*(volatile unsigned long*)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
#define GPGCON (*(volatile unsigned long*)0x56000060)
#define GPGDAT (*(volatile unsigned long*)0x56000064)
#define GPG0_eint (2<<(0*2)) //K1,EINT8
#define GPG3_eint (2<<(3*2)) //K2,EINT11
#define GPG5_eint (2<<(5*2)) //K3,EINT13
#define GPG6_eint (2<<(6*2)) //K4,EINT14
#define WTCON (*(volatile unsigned long*)0x53000000)
void disable_watch_dog(void)
{
WTCON=0;
}
void init_led(void)
{
GPBCON=GPB5_out|GPB6_out|GPB7_out|GPB8_out;
GPBDAT|=(0x0f<<5); //一切LED平息,假如没有这一句,LED灯默许是全亮的
}
void init_irq()
{
GPGCON=GPG0_eint|GPG3_eint|GPG5_eint|GPG6_eint;
//关于EINT8,EINT11,EINT13,EINT14,需求在EINTMASK存放器使能它们
EINTMASK&=(~(1<<8))&(~(1<<11))&(~(1<<13))&(~(1<<14));
//这4个外部中止的优先级是相同的,EINT8_23都接裁定器的REQ1引脚
//所以不必像韦东山程序里那样再设置优先级了
//EINT8,EINT11,EINT13,EINT14使能
INTMSK&=(~(1<<5));
}
interrupt.c文件内容:
#define GPBDAT (*(volatile unsigned long*)0x56000014)
#define INTOFFSET (*(volatile unsigned long*)0x4A000014)
#define EINTPEND (*(volatile unsigned long*)0x560000a8)
#define SRCPND (*(volatile unsigned long*)0x4a000000)
#define INTPND (*(volatile unsigned long*)0x4a000010)
void EINT_Handle()
{
unsigned long oft=INTOFFSET;
unsigned long val;
GPBDAT|=(0x0f<<5); //一切LED平息,假如没有这一句,那么会呈现一个成果,便是将程序下到板子里运转时,
//4个LED灯都是灭的,由于在init.c函数里设置它为全灭。然后你按下K1,LED1亮了,
//再按下K2,LED2亮了,可是LED1却没平息,知道你按到K4,4个LED全亮,再按就没变化了
//加上这一句就不相同了,每按一个键,只亮相应的灯,这也阐明中止的履行情况
val=EINTPEND; //EINT存放器,它的位x为1时,表明EINT现已产生(x为4——23)。
if(val&(1<<8)) //K1被按下,LED1被点亮
GPBDAT&=~(1<<5);
if(val&(1<<11)) //K2被按下,LED2被点亮
GPBDAT&=~(1<<6);
if(val&(1<<13)) //K3被按下,LED3被点亮
GPBDAT&=~(1<<7);
if(val&(1<<14)) //K4被按下,LED4被点亮
GPBDAT&=~(1<<8);
//铲除中止
if(oft==5)
EINTPEND=(1<<8)|(1<<11)|(1<<13)|(1<<14); //铲除EINTPEND存放器,往某位写入1即可清楚此位
SRCPND=1< //铲除SRCPND存放器,往某位写入1即可清楚此位
INTPND=1< //铲除INTPND存放器,往某位写入1即可清楚此位
//留意:铲除次序很重要:先是EINTPEND,然后是SRCPND,最终是INTPND
}
main.c文件内容:
int main()
{
while(1);
return 0;
}
Makfile文件内容:
objs:=head.o init.o interrupt.o main.o
int.bin:$(objs)
arm-linux-ld -Ttext 0x00000000 -o int_elf $^
arm-linux-objcopy -O binary -S int_elf $@
arm-linux-objdump -D -m arm int_elf > int.dis
%.o:%.c
arm-linux-gcc -Wall -O2 -c -o $@ $<
%.o:%.S
arm-linux-gcc -Wall -O2 -c -o $@ $<
clean:
rm -f int.bin int_elf int.dis *.o
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/kaiguan/262949.html