天天看點

arm中斷控制led

board/keyled_intr.c

#include "stdio.h"
#include "s5pv210.h"

void Eint16_isr()
{
	if(rEXT_INT_2_PEND==0x1)
	{
		printf("key2 put down\n");
		rEXT_INT_2_PEND |=(0x1<<0);
		//清除中斷标志位
		rVIC0ADDRESS = 0x0;
		//清除中斷處理子程式位址
		rGPJ2DAT ^=(0x1<<0);
	}
	else if(rEXT_INT_2_PEND==0x2)
		{
			printf("key3 put down\n");
		rEXT_INT_2_PEND |=(0x1<<1);
		rVIC0ADDRESS = 0x0;
		rGPJ2DAT ^=(0x1<<1);
		}

	else if(rEXT_INT_2_PEND==0x4){
	printf("key4 put down\n");
		rEXT_INT_2_PEND |=(0x1<<2);
		rVIC0ADDRESS = 0x0;
		// rGPJ2DAT ^=(0x4<<0);或用下面的移位
		 rGPJ2DAT ^=(0x1<<2);
	}
	else {
printf("key5 put down\n");
		rEXT_INT_2_PEND |=(0x1<<3);
		rVIC0ADDRESS = 0x0;
		rGPJ2DAT ^=(0x1<<3);
		}

}


void led_init()
{	
	//GPJ2CON[3:0] = 0B0001
	rGPJ2CON &=~(0xffff<<0);
	rGPJ2CON |=(0x1111<<0);
	//GPJ2DAT[0] = 0/1 
	rGPJ2DAT |=(0xf<<0);

}

void key_init()
{
	// GPH2CON[3:0] = 0B1111 -> intr mode	
	rGPH2CON |=(0xffff<<0);
}

void ext_init()
{
	/*//EXT_INT_2_CON[2:0]= 010
	rEXT_INT_2_CON &=~(0x7<<0);
	rEXT_INT_2_CON |=(0x2<<0);
 	//EXT_INT_2_MASK[0] = 0
 	rEXT_INT_2_MASK &=~(0x1<<0);
	//EXT_INT_2_PEND[0] = 0
	rEXT_INT_2_PEND |=(0x1<<0);*/
	//如果是1個按鍵就是0x7,就是上面的,初始化led和key時都要注意
	// 下面是4個按鍵的中斷初始化
	rEXT_INT_2_CON &=~(0x7777<<0);
	rEXT_INT_2_CON |=(0x2222<<0);
 	rEXT_INT_2_MASK &=~(0xf<<0);
	rEXT_INT_2_PEND |=(0xf<<0);

}
void vic0_init()
{
	//VIC0INTENCLEAR[16] = 0
	rVIC0INTENCLEAR &=~(0x1<<16);
	//VIC0INTSELECT[16] = 0  -> EINT16 IRQ
	rVIC0INTSELECT &=~(0x1<<16);
	//VIC0INTENABLE[16] = 1   -> EINT16 ENABLE 

	*((unsigned int *)0xf2000140) = (unsigned int)Eint16_isr;
	rVIC0ADDRESS = 0x0;
	
	rVIC0INTENABLE |=(0x1<<16);
}

void keyled_intr()
{
	led_init();
	key_init();
	ext_init();
	vic0_init();
	printf("while....\n");
	while(1);
}
           

cpu/board.c

#include "stdio.h"
#include "api.h"

int start_armboot()
{
	printf(">>>>> welcome to c <<<<<<<\n");
	keyled_intr();
	return 0;
}
           

/cpu/start.S

.text 
.extern uart_init			
.extern printf
.extern start_armboot
.global _start
_start:
	mov r5,lr 
	
	bl uart_init
	ldr r0,=fmt
	bl printf

	bl exc_vectable
	bl cpsr_init
	bl start_armboot


return_uboot:
	mov lr,r5
	bx lr 

cpsr_init:@标志位初始化
	mrs r0,cpsr
	bic r0,r0,#0xc0
	msr cpsr,r0

	bx lr 

exc_vectable:
	ldr r0,=Handler_IRQ
	ldr r1,=0xd0037418
	@iram裡的位址
	str r0,[r1]

	bx lr 



Handler_IRQ:@中斷處理程式
	sub lr,lr,#4
	stmfd sp!,{r0-r12,lr}
	ldr lr,=return_irq


	ldr r0,=0xf2000000
	@vic0位址
	ldr r1,[r0]

	cmp r1,#0
	beq return_irq
	
	ldr r0,=0xf2000f00
	@VIC0ADDRESS位址
	ldr pc,[r0]

return_irq:
	ldmfd sp!,{r0-r12,pc}^

fmt:
	.asciz ">>>>> welcome to arm <<<<<<<\n"
.end
           

makefile

CC = arm-linux-gcc
LD = arm-linux-ld 
OBJCOPY = arm-linux-objcopy 

INCLUDEDIR := $(shell pwd)/include/
CPPFLAGS := -nostdinc -nostdlib -I$(INCLUDEDIR)
CFLAGS := -fno-builtin -Wall -O2 

export CC LD OBJCOPY CPPFLAGS CFLAGS 

OBJS := cpu/start.o cpu/board.o board/keyled_intr.o  lib/uart.o lib/libc.a 

all:start.bin clean

start.bin:$(OBJS)
	$(LD) -Ttext=0x40000000 $(OBJS) -o start.elf
	$(OBJCOPY) -O binary -S start.elf $@

%.o:%.S
	$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
%.o:%.c
	$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
clean:
	rm -rf ./start.elf
	make clean -C cpu
	make clean -C board
           

這裡用到架構

arm中斷控制led

通常要修改這幾個檔案

arm中斷控制led

說明:

GPD0CON是模式設定

GPD0DAT是資料寄存器

GPD0PUD是推挽選擇

推挽了之後帶負載能力會強一點

其實推挽輸出就是輸出電阻小一點

第一階段:外部中斷初始化

1. io控制器初始化

GPH2CON[3:0]=1111

2. 外部中斷控制器初始化

EXT_INT_2_CON[2:0]=010

EXT_INT_2_MASK[0] = 1

EXT_INT_PEND[0] = 1  // clear 0 

EXT_INT_CON2[3:0] = 1111 = 0XF

3. 向量中斷控制器初始化

4. 狀态寄存器的中斷使能

第二階段:中斷響應過程

1)保護現場

a.模式切換

CPSR -> SPSR_irq             硬體做

CPSR_svc <- CPSR_irq 硬體做

b. PC跳轉

pc -> lr 硬體做

pc <- 0x18 硬體做

c. 儲存通用寄存器r0-r12          使用者做

r0-r12 -> sp 

2)真正的中斷處理

3)恢複現場

a. r0-r12 <- sp 

b. lr -> pc 

c. SPSR_irq -> CPSR 

按鍵有不同模式,輸入模式,就不需要中斷,中斷模式就需要中斷。

使用中斷的話一定是要設定異常表的。

不是中斷處理器調用中斷處理函數。是cpu自己調用中斷處理函數。這個pc指針所指向的中斷私服程式就是中斷控制器在接受到硬體中斷後強制設定的。這個和硬體有關的。

arm的異常向量表位置是可調整的,這個在協處理器cp15中設定

另外,如果是在作業系統下跑的程式,隻需向系統注冊中斷處理函數就可以了。異常向量表是不會讓使用者程式動的

http://bbs.csdn.net/topics/390333297

參考:

http://blog.csdn.net/u012990532/article/details/47458701

http://blog.csdn.net/a158337/article/details/40043417

http://www.qrszxp.com/luojibiancheng/17.html

http://www.bubuko.com/infodetail-529486.html