实验一:点亮led
一、先看原理图:
可知4个led分别对应GPF4/GPF5/GPF6/GPF7
二、看看GPIO相关寄存器
其实地址是GPFCON
:0x56000050 ;GPFDAT :0X56000054
对于每一位:

三、汇编代码
@******************************************************************************
@ File:led_on.S @ 功能:LED点灯程序,点亮LED1
@******************************************************************************
.text
.global _start
_start:
LDR R0,=0x56000050 @ R0设为GPFCON寄存器。此寄存器 @ 用于选择端口F各引脚的功能:
@ 是输出、是输入、还是其他
MOV R1,#0x00000100
STR R1,[R0]
@ 设置GPF4为输出口, 位[8:7]=0b01
LDR R0,=0x56000054 @ R0设为GPBDAT寄存器。此寄存器
@ 用于读/写端口B各引脚的数据
MOV R1,#0x00000000 @ 此值改为0x00000010,
@ 可让LED1熄灭
STR R1,[R0] @ GPF4输出0,LED1点亮
MAIN_LOOP:
B MAIN_LOOP
以上是源码;
现在看下Makefile:
led_on.bin : led_on.S
arm-linux-gcc -g -c -o led_on.o led_on.S
arm-linux-ld -Ttext 0x0000000 -g led_on.o -o led_on_el
arm-linux-objcopy -O binary -S led_on_elf led_on.bin
clean:
rm -f led_on.bin led_on_elf *.o
这里重点对makefile进行延伸
-c 表示编译但不连接 是编译最常用的
-o 表示输出 应用灵活 ,后面是输出名
-g 表示编译信息,可不用
arm-linux-ld 参数:
-Ttext 表示编译地址
arm-linux-objcopy 这里用做格式转换用
-O(大写) 表示输出
-S(大写) 表示不从源文件复制重定位到新目标文件 非必须的
还有一个反汇编指令
arm-linux-objdmp :
-D 表示反汇编所有断段
-d 表示反汇编可执行段
-m 反汇编目标构架
-b 目标文件制定格式
完整的arm-linux-objdump 如下:
arm-linux-objdump -D -b binary -m arm led_elf>led.dis
注意:“>”不能少,否则会忽略led.dis
C语言代码实现:
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
int main()
{
GPFCON = 0x00000100; // 设置GPF4为输出口, 位[8:7]=0b01
GPFDAT = 0x00000000; // GPF4输出0,LED1点亮
return 0;
}
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
int main()
{
GPFCON = 0x00000100; // 设置GPF4为输出口, 位[8:7]=0b01
GPFDAT = 0x00000000; // GPF4输出0,LED1点亮
return 0;
}
@以下是引导程序:
@******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************
.text
.global _start
_start:
ldr r0, =0x53000000 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启
ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数
halt_loop:
b halt_loop
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************
.text
.global _start
_start:
ldr r0, =0x53000000 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启
ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数
halt_loop:
b halt_loop
Makefile文件:
led_on_c.bin : crt0.S led_on_c.c
arm-linux-gcc -g -c -o crt0.o crt0.S
arm-linux-gcc -g -c -o led_on_c.o led_on_c.c
arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on_c.o -o led_on_c_elf
arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin
arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis
clean:
rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o
arm-linux-gcc -g -c -o crt0.o crt0.S
arm-linux-gcc -g -c -o led_on_c.o led_on_c.c
arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on_c.o -o led_on_c_elf
arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin
arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis
clean:
rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o
下面补充一下 led闪烁 。
直接贴代码:
1 /************************************************************************* 2 > File Name: led.c 3 > Author: hulig 4 > Mail: fang682@oki.com 5 > Created Time: 2014年10月13日 星期一 19时29分13秒 6 @this program is test and ok 7 ************************************************************************/ 8 9 10 #define GPFCON (*(volatile unsigned long*) 0x56000050) 11 #define GPFDAT (*(volatile unsigned long*) 0x56000054) 12 13 void delay() 14 { 15 unsigned long cnt; 16 for(cnt=0;cnt<100000;cnt++); 17 18 } 19 20 int main(void) 21 { 22 23 GPFCON |=(1<<8); //GPFCON=0x00000100; 24 25 while(1){ 26 GPFDAT &=~(1<<4); //GPFDAT=0x00000000; 27 delay(); 28 GPFDAT |=(1<<4); //GPFDAT=0x00000010; 29 delay(); 30 31 } 32 return 0; 33 34 }
然后启动文件同上 ,Makefile亦是。
浙公网安备 33010602011771号