S3C2440裸板程序之中断

本实例实现按键中断来控制LED的亮灭。

head.S

.extern main	
.text
.global _start
_start:
	b Reset
	
HandleUndef:
	b HandleUndef

HandleSWI:
	b HandleSWI

HandlePrefetchAbort:
	b HandlePrefetchAbort

HandleDataAbort:
	b HandleDataAbort

HandleNotUsed:
	b HandleNotUsed

	b HandleIRQ

HandleFIQ:
	b HandleFIQ

Reset:
	ldr sp, =4096			@ 设置好栈指针,调用C函数之前要设好栈
	bl disable_watch_dog    @ 关闭watch dog,否者CPU会不断重启

	msr cpsr_c, #0xd2	    @ 进入中断模式
	ldr sp, =3072			@ 设置中断模式栈指针

	msr cpsr_c, #0xd3		@ 进入系统模式
	ldr sp, =4096			@ 设置系统模式栈指针

	bl init_led             @ 初始化LED的GPIO管脚
	bl init_irq				@ 调用中断初始化函数
	msr cpsr_c, #0x5f		@ 设置I-bit =0,开IRQ中断

	ldr lr, =halt_loop		@ 设置返回地址
	ldr pc, =main			@ 调用main函数

halt_loop:
	b halt_loop

HandleIRQ:
	sub lr, lr, #4			   @ 计算返回地址
	stmdb sp!, { r0-r12, lr }  @ 保存使用到的寄存器
							   @ 注意,此时的sp是中断模式的sp,即3072
	ldr lr, =int_return		   @ 设置调用ISR函数(即EINT_Handle)后的返回地址
	ldr pc, =EINT_Handle	   @ 调用中断服务函数

int_return:
	ldmia sp!, { r0-r12, pc }^ @ 中断返回,^表示将spsr的值复制到cpsr

init.c

/********************
@goal:interrupt key down , led on 
@method: 
@date: 2018/06/09
@auto:Alon
*********************/

#include "s3c24xx.h"

/* 
	LED1:GPF4
	LED2:GPF5
	LED3:GPF6
*/
#define	GPF4_out	(1<<(4*2))
#define	GPF5_out	(1<<(5*2))
#define	GPF6_out	(1<<(6*2))

#define GPF4_msk	(3<<(4*2))
#define GPF5_msk	(3<<(5*2))
#define GPF6_msk	(3<<(6*2))

#define GPF0_eint   (2<<(0*2))
#define GPF2_eint   (2<<(2*2))
#define GPG3_eint   (2<<(3*2))

#define GPF0_msk	(3<<(0*2))
#define GPF2_msk	(3<<(2*2))
#define GPG3_msk	(3<<(3*2))

void disable_watch_dog(void)
{
	WTCON = 0;
}

void init_led(void)
{
	GPFCON &= ~(GPF4_msk | GPF5_msk 
| GPF6_msk); /*clear bit*/
	GPFCON |= GPF4_out | GPF5_out | GPF6_out; /*set output*/
}

int init_irq()
{
	/* set GPFCON interrupt*/
	GPFCON &= ~(GPF0_msk | GPF2_msk);
    GPFCON |= GPF0_eint | GPF2_eint;
	
	/* set GPGCON interrupt*/
	GPGCON &= ~GPG3_msk;
    GPGCON |= GPG3_eint;
	EINTMASK &= (~(1<<11));/*EINT0 ,EINT2 not need control ,EIN11 need*/

	PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;
	INTMSK &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));
}



interrupt.c

#include "s3c24xx.h"

void EINT_Handle()
{
	unsigned long oft = INTOFFSET;
	unsigned long val;
	GPFDAT |= (7<<4);  /*all leds off*/

	switch(oft)
	{
		case 0:/*EINT 0*/
			GPFDAT &= ~(1<<4); /*led1 on*/
			break;
		case 2:/*EINT 0*/
			GPFDAT &= ~(1<<5); /*led2 on*/
			break;
		case 5:/*EINT 8_23 , so include eint11*/
			GPFDAT &= ~(1<<6); /*led3 on*/
			break;
		default:
			break;
	}

	if(5 == oft)
		EINTPEND = 1<<11; /*clear eint 11*/
		
	SRCPND |= 1<<oft;
	INTPND |= 1<<oft;
}

main.c

/********************
@goal:interrupt key down , led on 
@method: 
@date: 2018/06/09
@auto:Alon
*********************/


int main()
{
	while(1);
	return 0;
}

s3c24xx.h

/* WOTCH DOG register */
#define     WTCON           (*(volatile unsigned long *)0x53000000)

/* SDRAM regisers */
#define     MEM_CTL_BASE    0x48000000
#define     SDRAM_BASE      0x30000000

/* NAND Flash registers */
#define NFCONF              (*(volatile unsigned int  *)0x4e000000)
#define NFCMD               (*(volatile unsigned char *)0x4e000004)
#define NFADDR              (*(volatile unsigned char *)0x4e000008)
#define NFDATA              (*(volatile unsigned char *)0x4e00000c)
#define NFSTAT              (*(volatile unsigned char *)0x4e000010)

/*GPIO registers*/
#define GPBCON              (*(volatile unsigned long *)0x56000010)
#define GPBDAT              (*(volatile unsigned long *)0x56000014)

#define GPFCON              (*(volatile unsigned long *)0x56000050)
#define GPFDAT              (*(volatile unsigned long *)0x56000054)
#define GPFUP               (*(volatile unsigned long *)0x56000058)

#define GPGCON              (*(volatile unsigned long *)0x56000060)
#define GPGDAT              (*(volatile unsigned long *)0x56000064)
#define GPGUP               (*(volatile unsigned long *)0x56000068)

#define GPHCON              (*(volatile unsigned long *)0x56000070)
#define GPHDAT              (*(volatile unsigned long *)0x56000074)
#define GPHUP               (*(volatile unsigned long *)0x56000078)

/*UART registers*/
#define ULCON0              (*(volatile unsigned long *)0x50000000)
#define UCON0               (*(volatile unsigned long *)0x50000004)
#define UFCON0              (*(volatile unsigned long *)0x50000008)
#define UMCON0              (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)
#define UTXH0               (*(volatile unsigned char *)0x50000020)
#define URXH0               (*(volatile unsigned char *)0x50000024)
#define UBRDIV0             (*(volatile unsigned long *)0x50000028)

/*Interrupt registes*/
#define SRCPND              (*(volatile unsigned long *)0x4A000000)
#define INTMOD              (*(volatile unsigned long *)0x4A000004)
#define INTMSK              (*(volatile unsigned long *)0x4A000008)
#define PRIORITY            (*(volatile unsigned long *)0x4A00000c)
#define INTPND              (*(volatile unsigned long *)0x4A000010)
#define INTOFFSET           (*(volatile unsigned long *)0x4A000014)
#define SUBSRCPND           (*(volatile unsigned long *)0x4A000018)
#define INTSUBMSK           (*(volatile unsigned long *)0x4A00001c)

/*external interrupt registers*/
#define EINTMASK            (*(volatile unsigned long *)0x560000a4)
#define EINTPEND            (*(volatile unsigned long *)0x560000a8)

Makefile

objs := head.o init.o interrupt.o main.o 

interrupt.bin : $(objs)
	arm-linux-ld -Ttext 0x00000000 -o interrupt_elf $^	
	arm-linux-objcopy -O binary -S interrupt_elf $@
	arm-linux-objdump -D -m arm interrupt_elf >interrupt.dis

%.o:%.c
	arm-linux-gcc -Wall -O2 -c -o $@ $<

%.o:%.S 
	arm-linux-gcc -Wall -O2 -c -o $@ $<

clean:
	rm -f interrupt_elf interrupt.dis interrupt.bin *.o

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值