这是根据韦东山的关于中断的代码改成在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
关键字:mini2440 中断 裸机代码
引用地址:
根据韦东山修改的mini2440中断的裸机代码
推荐阅读最新更新时间:2024-03-16 14:50
STM32中断设置以及中断优先级设置三步曲
中断作为stm32中必不可少的一个功能,其重要性是不言而喻的因此把中断学习好是根本。 所以今天就来好好啃一下中断配置的知识,俗话说:磨刀不误砍柴工。问题是什么呢?项目中我用到了一个触摸键盘TTP229,结果在测试键盘时,不能够输入密码?最终,调试出bug就是由于中断优先级的影响。 本项目使用到的是STM32F030C8型号的MCU,我们可以从官方下载到的标准库文件中的启动汇编文件中,查看到本型号单片机的外部中断向量表。(如下图所示) 首先,我们了解一下NVIC是什么,在core_cm0.h文件中的标准库中的NVIC结构体。 其中,我们一般只用到ISER、ICER、IP这3个寄存器。ISER用于使能中
[单片机]
单片机定时器中断时间误差的分析及补偿
1 前言 单片机内部一般有若干个定时器。如8051单片机内部有定时器0和定时器1。在定时器计数溢出时,便向CPU发出中断请求。当CPU正在执行某指令或某中断服务程序时,它响应定时器溢出中断往往延迟一段时间。这种延时虽对单片机低频控制系统影响甚微,但对单片机高频控制系统的实时控制精度却有较大的影响,有时还可能造成控制事故。为扩大单片机的应用范围,本文介绍它的定时器溢出中断与CPU响应中断的时间误差、补偿误差的方法和实例。 2 误差原因、大小及特点 产生单片机定时器溢出中断与CPU响应中断的时间误差有两个原因。一是定时器溢出中断信号时,CPU正在执行某指令;二是定时器溢出中断信号时,CPU正在执行某中断服务程序。 2.1.
[单片机]
STM32裸机开发—外部中断
a. 初始化IO口作为输入 这一步需要设置你要作为外部中断输入的IO口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部硬件一定要上拉或下拉。否则可能导致中断不停地被触发。在干扰较大的地方,就算使用了上拉/下拉,也建议在外部硬件上设置上拉/下拉,这样可以在一定程度上防止外部干扰带来的影响。 *RCC_APB2ENR=0x00000019;//打开portb和portc的时钟和复用时钟 *PORTA_CRL=0x44444844;//设置PA2口为上拉/下拉输入模式 由于还需要驱动液晶屏所以同时打开了PORTB和PORTC的时钟。 b. 开启IO口复用时钟,设置IO口与中断线的映射关系
[单片机]
u-boot-2009.08在mini2440上的移植(一)---建立mini2440工程环境(1)
移植环境 1,主机环境:VMare下CentOS 5.5 ,1G内存。 2,集成开发环境:Elipse IDE 3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。 4,开发板:mini2440,2M nor flash,128M nand flash。 5,u-boot版本:u-boot-2009.08 6,参考文章: http://blogold.chinaunix.net/u3/101649/showart.php?id=2105215 http://blog.chinaunix.net/space.php?uid=23787856&do=blog&id=115382
[单片机]
STM32 中断向量,优先级
一,中断优先级: STM32(Cortex-M3)中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念 抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。 当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理
[单片机]
实验四 外中断(80C51单片机汇编语言编程)
S1加1键,S2减1键 要求:上电全灭。每按一次S1亮的灯多一盏;每按一次S2亮的灯少一盏。按8次后重复开始状态。 ORG 0000H LJMP MAIN ORG 0003H LJMP INT0 ORG 0013H LJMP INT1 ORG 0030H MAIN:SETB EA SETB EX0 SETB EX1 SETB IT0 SETB IT1 MOV B,#00H HERE:SJMP HERE INT0:MOV A,B RL A INC A MOV B,A MOV P1,A RETI INT1:MOV A,B
[单片机]
ARM异常---一个Uart中断的触发处理过程
首先给出一些定义: //2440addr.inc INTOFFSET EQU 0x4a000014 ;Interruot request source offset //option.inc _ISR_STARTADDRESS EQU 0x33ffff00 //2440init.s MACRO $HandlerLabel HANDLER $HandleLabel $HandlerLabel sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work regi
[单片机]
STM32外部中断解决方法
01 单片机外部中断简介 所谓外部中断,就是通过外部信号所引起的中断,如单片机引脚上的电平变化(高电平、低电平)、边沿变化(上升沿、下降沿)等。51单片机有5个中断源,其中有两个是外部中断,分别为INT0和INT1,INT0被分配在P3.2引脚,INT1被分配在P3.2引脚,也即是说如果使用51单片机的外部中断0,则必须将信号接在P3.2上,否则无效。 02 举例说明什么是中断 单片机在执行程序时有两种方式: 查询方式 中断方式 所谓查询方式就是单片机一遍一遍的扫描,查看所监视的目标有没有发生变化,是一种主动式的监视方法,用一个成语可以很客观的描述:守株待兔。 所谓中断方式就是单片机不主动去监视目标,而是目标主动通知单片机状态
[单片机]