led.bin:start.o uart.o key_led.o arm-linux-ld -Ttext 0 -o led.elf start.o uart.o key_led.o arm-linux-objcopy -O binary led.elf led.bin arm-linux-objdump -D led.elf>led.dis cp *.bin /tftpboot/ -r start.o:start.S arm-linux-gcc -c start.S -o start.o uart.o:uart.c arm-linux-gcc -c uart.c -o uart.o key_led.o:key_led.c arm-linux-gcc -c key_led.c -o key_led.o clean: rm -rf *.o *.elf *.dis *.bin /tftpboot/led.bin
Makefile :添加key_led.o , uart.o
@ @ 功能:运行后,进入串口功能,按'q'退出进入key_led功能,按key1,key2,key3,key4点 @ 亮相应的led灯,按key5全部点亮,按key6进入led循环点亮,并使蜂鸣器响起。 @ 时间:2012-12-01 @ .globl _start _start: @外设地址范围 #define busaddr 0x70000000 #define wtcon 0x7e004000 @led灯使用的寄存器地址 #define gpmcon 0x7f008820 #define gpmdat 0x7f008824 @时钟使用的寄存器地址 #define apll_lock 0x7e00f000 #define others 0x7e00f900 #define clk_div0 0x7e00f020 #define apll_con 0x7e00f00c #define mpll_con 0x7e00f010 #define clk_src 0x7e00f01c @串口使用的寄存器地址 #define gpacon 0x7f008000 #define ulcon0 0x7f005000 #define ucon0 0x7f005004 #define ufcon0 0x7f005008 #define umcon0 0x7f00500c #define ubrdiv0 0x7f005028 #define udivslot0 0x7f00502c #define ufstat0 0x7f005018 #define utxh0 0x7f005020 #define urxh0 0x7f005024 @蜂鸣器使用的寄存器 #define gpfcon 0x7f0080a0 #define gpfdat 0x7f0080a4 @告诉CPU外设地址范围 ldr r0, =busaddr orr r0, r0, #0x13 mcr p15, 0, r0, c15, c2, 4 @关闭看门狗 ldr r0, =wtcon mov r1, #0 str r1, [r0] @调用时钟初始化代码,调用led点灯代码 bl clock_init bl uart_init ldr sp, =8*1024 bl uart bl key_led bl pwm_buzzer bl led_loop b . @蜂鸣器 pwm_buzzer: ldr r0, =gpfcon ldr r1, =(1<<30) str r1, [r0] ldr r0, =gpfdat ldr r1, =(1<<15) str r1, [r0] mov pc, lr @led循环点灯程序 led_loop: @设置引脚为输出模式 ldr r0, =gpmcon ldr r1, =0x1111 str r1, [r0] @设置输出引脚循环输出低电平 ldr r0, =gpmdat led_loop1: mov r1, #0xe str r1, [r0] bl delay mov r1, #0xd str r1, [r0] bl delay mov r1, #0xb str r1, [r0] bl delay mov r1, #0x7 str r1, [r0] bl delay b led_loop1 @延时 delay: ldr r2, =100000 delay_sub: sub r2, r2, #1 cmp r2, #0 bne delay_sub moveq pc, lr @时钟初始化为532MHz clock_init: @设置lock_time,有默认值,不设置也可以 ldr r0, =apll_lock ldr r1, =0xffff str r1, [r0] str r1, [r0,#4] str r1, [r0,#8] @开启异步模式 ldr r0, =others ldr r1, [r0] bic r1, r1, #0xc0 str r1, [r0] @等待异步模式启动动完成 clock_loop1: ldr r1, [r0] and r1, #0xf00 cmp r1, #0 bne clock_loop1 @设置分频系数 ldr r0, =clk_div0 ldr r1, =((0)|(0<<4)|(1<<8)|(1<<9)|(3<<12)) str r1, [r0] @设定apll时钟频率 ldr r0, =apll_con ldr r1, =((1)|(3<<8)|(266<<16)|(1<<31)) str r1, [r0] @设定mpll时钟频率 ldr r0, =mpll_con ldr r1, =((1)|(3<<8)|(266<<16)|(1<<31)) str r1, [r0] @切换到apll和mpll时钟工作 ldr r0, =clk_src mov r1, #0x3 str r1, [r0] @初始化完毕,返回 mov pc, lr @串口的初始化 uart_init: @将GPA0、GPA1、GPA2、GPA3设为对应功能引脚RXD[0],TXD[0],CTSn[0],RTSn[0] ldr r0, =gpacon ldr r1, =0x22 str r1, [r0] @数据位,停止位,校验位,模式的设置 ldr r0, =ulcon0 mov r1, #0x3 str r1, [r0] @时钟的选择,发送接收的使能 ldr r0, =ucon0 mov r1, #0x5 str r1, [r0] @FIFO启用 ldr r0, =ufcon0 ldr r1, =0x01 str r1, [r0] @流量控制,默认配置,可以省略 ldr r0, =umcon0 mov r1, #0 str r1, [r0] @波特率整数部分设置 ldr r0, =ubrdiv0 mov r1, #34 str r1, [r0] @波特率小数部分设置 ldr r0, =udivslot0 ldr r1, =0xdfdd str r1, [r0] mov pc, lr
start.S : 整合时钟、led、按键、串口、蜂鸣器功能。
#define ufstat0 (*(volatile unsigned long *)0x7f005018) #define urxh0 (*(volatile unsigned char *)0x7f005024) #define utxh0 (*(volatile unsigned char *)0x7f005020) char getchar_uart(void) { while ((ufstat0 & 0x7f) == 0) ; return urxh0; } void putchar_uart(char c) { while (ufstat0 & (1<<14)) ; utxh0 = c; } int uart(void) { char p; while(1){ p = getchar_uart(); if (p == 'q') return 0; putchar_uart(p); } return 0; }
uart.c :start.S文件中调用的串口使能函数代码。
#define gpncon (*(volatile unsigned long *)0x7f008830) #define gpndat (*(volatile unsigned long *)0x7f008834) #define gpmcon (*(volatile unsigned long *)0x7f008820) #define gpmdat (*(volatile unsigned long *)0x7f008824) int key_led(void) { gpncon &= ~(0xfff); gpmcon &= ~(0xffff); gpmcon |= 0x1111; while(1){ if(gpndat & (1<<0)) gpmdat |= (1<<0); else gpmdat &= ~(1<<0); if(gpndat & (1<<1)) gpmdat |= (1<<1); else gpmdat &= ~(1<<1); if(gpndat & (1<<2)) gpmdat |= (1<<2); else gpmdat &= ~(1<<2); if(gpndat & (1<<3)) gpmdat |= (1<<3); else gpmdat &= ~(1<<3); if(gpndat & (1<<4)) gpmdat |= 1; else gpmdat &= 0; if(gpndat & (1<<5)) gpmdat |= 1; else{ gpmdat &= 0; return 0; } } return 0; }
key_led.c :按键初始化函数。
整个程序功能:运行后,进入串口功能,按'q'退出进入key_led功能,按key1,key2,key3,key4点亮相应的led灯,按key5全部点亮,按key6进入led循环点亮,并使蜂鸣器响起。