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循环点亮,并使蜂鸣器响起。