基于A9的流水灯试验

目录

基于A9的流水灯试验:

Makefile:

test.lds:

makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解:makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解 - 腾讯云开发者社区-腾讯云 (tencent.com)

arm位清零bic指令:http://t.csdn.cn/q2bMo  

ARM指令集详解:http://t.csdn.cn/KIXMX  

联合 c 和 汇编的流水灯实现:


基于A9的流水灯试验:

+GPF3CON    配置寄存器    0x1140 01E0    [23:20] 0x1 Output
+GPF3DAT    辅助输入输出pin    0x1140 01E4    [ 5: 0] 0x1 LED5 亮

+GPX1CON    配置寄存器    0x1100 0C20    [ 3: 0] 0x1 Output
+GPX1DAT    辅助输入输出pin    0x1100 0C24    [ 7: 0] 0x1 LED3 亮

+GPX2CON    配置寄存器    0x1100 0C40    [31:28] 0x1 Output
+GPX2DAT    辅助输入输出pin    0x1100 0C44    [ 7: 0] 0x1 LED2 亮

+GPX3CON    配置寄存器    0x1100 0C60    [19:16] 0x1 Output
+GPX3DAT    辅助输入输出pin    0x1100 0C64    [ 7: 0] 0x1 LED4 亮

.global _start
_start:
    b reset
    ldr pc,_undefined_instruction
    ldr pc,_software_interrupt
    ldr pc,_prefetch_about
    ldr pc,_data_about
    ldr pc,_not_used
    ldr pc,_irq
    ldr pc,_fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word _software_interrupt
_prefetch_about: .word _prefetch_about
_data_about: .word _data_about
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq

reset:      /*设置cpu模式为svc模式*/
    mrs r0,cpsr
    bic r0,r0,#0x1f /*清除cpsr的模式位*/
    orr r0,r0,#0xd3 /*让处理器处于ARM状态、禁用irq、fiq,并将模式设置为svc模式*/
    msr cpsr,r0
    /*设置异常向量表起始地址*/
    ldr r0, =_start
    mcr p15,0,r0,c12,c0,0 /*这里需要是 c12,不能是 c15,还是不太明白*/
    /*用户初始化*/
    ldr sp,stacktop /*设置svc的栈顶*/
    sub r6,sp,#64   /*计算user需要指向的栈顶位置/
    /*切换到用户模式*/
    mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0x10  /*处理器状态不变,启用irq、fiq,模式设置为user*/
    msr cpsr,r0

    mov sp,r6   /*设置user模式的栈顶*/
    bl _main
_main:
    ldr r0,=0x114001E0	/*led5 GPF3CON*/
    ldr r1,=0x114001E4 /*led5 GPF3DAT*/
    ldr r2,=0x11000c20 /*led3 GPX1CON*/
    ldr r3,=0x11000c24 /*led3 GPX1DAT*/
    ldr r4,=0x11000c40 /*led2 GPX2CON*/
    ldr r5,=0x11000c44 /*led2 GPX2DAT*/
    ldr r6,=0x11000c60 /*led4 GPX3CON*/
    ldr r7,=0x11000c64 /*led4 GPX3DAT*/

    /*led5 配置输出pin*/    
    ldr r8,[r0]
    bic r8,r8,#0x00f00000
    orr r8,r8,#0x00100000
    str r8,[r0]   
    /*led3 配置输出pin*/
    ldr r8,[r2]
    bic r8,r8,#0xf
    orr r8,r8,#0x1
    str r8,[r2]
    /*led4 配置输出pin*/
    ldr r8,[r6]
    bic r8,r8,#0x000f0000
    orr r8,r8,#0x00010000
    str r8,[r6]
    /*led2 配置输出pin*/    
    ldr r8,[r4]
    bic r8,r8,#0xf0000000
    orr r8,r8,#0x10000000
    str r8,[r4]
        
loop:
    /*led5 亮*/
    ldr r9,[r1]
    orr r9,r8,#0x20
    str r9,[r1] 
    bl delay
    bic r9,r8,#0x20
    str r9,[r1]
    
    /*led3 亮*/
    ldr r9,[r3]
    orr r9,r8,#0x1
    str r9,[r3]
    bl delay
    bic r9,r8,#0x1
    str r9,[r3]
        
    /*led4 亮*/
    ldr r9,[r7]
    orr r9,r8,#0xf0
    str r9,[r7]
    bic r9,r8,#0xf0
    str r9,[r3]    
    
    /*led2 灭*/
    /*清除输出pin,不建议*/
/*    ldr r8,[r4]
      bic r8,r8,#0xf0000000
      str r8,[r4]
*/
    /*清除 led2 数据位*/
    ldr r9,[r5]
    bic r9,r8,#0x1
    str r9,[r5]

bl loop
delay:
   stmfd sp!,{r0-r12,lr}
   mov r10,#1
     lop1:
     add r10,r10,#1     
     cmp r10,#0xf000000
     blt lop1
  ldmfd sp!,{r0-r12,pc}

stack: .space 64*8
stacktop: .word stack+64*8

在ARM 处理器中,只有MRS 指令可以状态寄存器CPSR或SPSR读出到通用寄存器中
【mrs r0,cpsr;    将 cpsr 状态寄存器的值读到 r0 中】
msr:写状态寄存器指令
在ARM 处理器中。只有MSR 指令可以直接设置状态寄存器CPSR或SPSR
【msr cpsr,r0;    将 r0 的值写到 cpsr 寄存器中】

Makefile:

all:
	arm-linux-gcc 3.s -o start.o -c -g
	arm-linux-ld  start.o -o start.elf -Ttest.lds
	arm-linux-objcopy start.elf start.bin -O binary
clean:
	rm *.o *.elf *.bin

test.lds:

ENTRY(_start)
SECTIONS{
	. = 0x41000000;
	.text : {
		start.o(.text)
		*(.text)
	}
	.data : {
		*(.data)
	}
	.bss : {
		*(.bss)	
	}
}

makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解:makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解 - 腾讯云开发者社区-腾讯云 (tencent.com)

-------------------------------------------------------------------------------------------------------------------------

arm位清零bic指令:http://t.csdn.cn/q2bMo  

ARM指令集详解:http://t.csdn.cn/KIXMX  

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

联合 c 和 汇编的流水灯实现

main.c:

#define GPF3CON *(unsigned int volatile*)0x114001E0
#define GPF3DAT *(unsigned int volatile*)0x114001E4

#define GPX1CON *(unsigned int volatile*)0x11000c20
#define GPX1DAT *(unsigned int volatile*)0x11000c24

#define GPX2CON *(unsigned int volatile*)0x11000c40
#define GPX2DAT *(unsigned int volatile*)0x11000c44

#define GPX3CON *(unsigned int volatile*)0x11000c60
#define GPX3DAT *(unsigned int volatile*)0x11000c64
/*自定义睡眠函数*/
void delay()
{
	int t = 0xf0000000;
	while(t--);
}
int main(int argc, char *argv[])
{ 
	//配置输出 pin ,基本准则:先清后或
	GPF3CON = GPF3CON & ( ~(0xf<<20) ) | (0x1<<20);
	GPX1CON = GPX1CON & ( ~(0xf<< 0) ) | (0x1<< 0);
	GPX2CON = GPX2CON & ( ~(0xf<<28) ) | (0x1<< 0);
	GPX3CON = GPX3CON & ( ~(0xf<<16) ) | (0x1<<16);
	while(1){
		GPF3DAT = GPF3DAT | (0x1<<5);
		delay();
		GPF3DAT = GPF3DAT | ~(0x1<<5);
		delay();
		
		GPX1DAT = GPX1DAT | (0x1<<0);
		delay();
		GPX1DAT = GPX1DAT | ~(0x1<<0);
		delay();
		
		GPX2DAT = GPX2DAT | (0x1<<0);
		delay();
		GPX2DAT = GPX2DAT | ~(0x1<<0);
		delay();
		
		GPX3DAT = GPX3DAT | (0x1<<16);
		delay();
		GPX3DAT = GPX3DAT | ~(0x1<<16);
		delay();
	}
    return 0;
} 

Makefile:
 

all:
	arm-linux-gcc 3.s -o start.o -c -g
	arm-linux-gcc main.c -o main.o -c -g
	arm-linux-ld  start.o main.o -o start.elf -Ttest.lds
	arm-linux-objcopy start.elf start.bin -O binary
clean:
	rm *.o *.elf *.bin

汇编:

.global _start
_start:
    b reset
    ldr pc,_undefined_instruction
    ldr pc,_software_interrupt
    ldr pc,_prefetch_about
    ldr pc,_data_about
    ldr pc,_not_used
    ldr pc,_irq
    ldr pc,_fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word _software_interrupt
_prefetch_about: .word _prefetch_about
_data_about: .word _data_about
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq

reset:      /*设置cpu模式为svc模式*/
    mrs r0,cpsr
    bic r0,r0,#0x1f /*清除cpsr的模式位*/
    orr r0,r0,#0xd3 /*让处理器处于ARM状态、禁用irq、fiq,并将模式设置为svc模式*/
    msr cpsr,r0
    /*设置异常向量表起始地址*/
    ldr r0, =_start
    mcr p15,0,r0,c12,c0,0 /*这里需要是 c12,不能是 c15,还是不太明白*/
    /*用户初始化*/
    ldr sp,stacktop /*设置svc的栈顶*/
    sub r6,sp,#64   /*计算user需要指向的栈顶位置/
    /*切换到用户模式*/
    mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0x10  /*处理器状态不变,启用irq、fiq,模式设置为user*/
    msr cpsr,r0

    mov sp,r6   /*设置user模式的栈顶*/
    /*跳转到用户程序*/
    bl main

stack: .space 64*8
stacktop: .word stack+64*8

你可能感兴趣的:(arm,arm,A9)