平台:jz2440
作者:庄泽彬(欢迎转载,请注明作者)
说明:韦东山一期视频学习笔记
一、我们首先来做第一个实验,用汇编语言点亮板子上的LED。
1.1 LED的原理图
从下面的原理图可知LED1是连接到芯片的GPF4
1.2 相关的GPIO寄存器的配置
我们要点亮LED,就要把相关的端口配置成输出口,并且输出低电平。看看芯片手册,要GPF4输出低电平要配置GPFCON寄存器设置相应的位位01即为输出状态,在配置GPFDAT相应的位为0即可输出低电平。
1.3相关代码:
led_on.S文件
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 .text 2 .global _start 3 _start: 4 LDR R0,=0x56000050 @ 设置R0为GPFCON寄存器 5 @ 用于配置端口的输入、输出状态 6 7 mov R1,#0x00000100 8 str R1,[R0] @ 设置GPF4端口为输出口 9 10 ldr R0,=0x56000054 @ 设置R0为GPFDAT寄存器 11 @ 用于配置端口输出的高低电平 12 13 mov R1,#0x00000100 14 str R1,[R0] @ 输出低电平 15 16 MAIN_LOOP: 17 B MAIN_LOOP
![复制代码](https://common.cnblogs.com/images/copycode.gif)
Makefile文件
1 led_on.bin:led_on.S 2 arm-linux-gcc -g -c -o led_on.o led_on.S 3 arm-linux-ld -Ttext 0x00000000 -g led_on.o -o led_on_elf 4 arm-linux-objcopy -O binary -S led_on_elf led_on.bin 5 clean: 6 rm led_on.bin led_on_elf *.o
1.4 执行结果
看一下图片LED是点亮了啊。
二、我们升级一下上一个程序,我们使用C语言的方式点亮LED灯.
2.1 我们要设置好C语言的运行环境,要关闭看门狗以及设置栈,函数的参数都是存放在栈里的,因此要用C语言的方式点亮LED,把栈设置好是很重要的。
查看芯片手册关闭看门狗的方法:
往WTCON寄存器写入0即可关闭
栈指针的设置:
目前我们的开发板是设置nandflash启动的,启动的时候会拷贝nandflash的前4K的内容到芯片内部的ram中运行,因此栈指针的范围不要超过4K
2.2相关代码
crt0.S
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 .text 2 .global _start 3 _start: 4 5 ldr R0,=0x53000000 @ 设置为看门狗寄存器地址 6 7 mov R1,#0x0 8 str R1,[R0] 9 10 ldr sp,=1024*4 @ 设置的sp范围不要超过4K 11 12 bl main 13 14 halt_loop: 15 b halt_loop
![复制代码](https://common.cnblogs.com/images/copycode.gif)
led_on_c.c
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 #define GPFCON (*(volatile unsigned long *)0x56000050) 2 #define GPFDAT (*(volatile unsigned long *)0x56000054) 3 4 int main() 5 { 6 GPFCON = 0x00000100; //配置GPF4为输出口 7 GPFDAT = 0x00000000; //输出低电平 8 9 return 0; 10 }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
Makefile
![复制代码](https://common.cnblogs.com/images/copycode.gif)
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 0x00000000 -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_elf led_on_c.dis led_on_c.bin *.o
![复制代码](https://common.cnblogs.com/images/copycode.gif)
2.3 编译与执行结果
执行make生成我们的目标文键led_on_c.bin,led_on_c.dis是反汇编文件
现象跟上一次的实验一下,这里就不贴图了啊。
3.1在修改一下上面的例子,改成流水灯
其他的文件我们保持不变只修改led_on_c.c,这个只是应用编程,想怎么改都ok,
led_on_c.c源码:
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 #define GPFCON (*(volatile unsigned long *)0x56000050) 2 #define GPFDAT (*(volatile unsigned long *)0x56000054) 3 4 #define GPF4_OUT (1<<(4*2)) 5 #define GPF5_OUT (1<<(5*2)) 6 #define GPF6_OUT (1<<(6*2)) 7 8 void delay(volatile unsigned long delay) 9 { 10 for (;delay > 0;delay --); 11 } 12 13 14 int main() 15 { 16 unsigned long i = 0; 17 18 GPFCON = GPF4_OUT|GPF5_OUT|GPF6_OUT; //配置为输出端口 19 20 while(1){ 21 delay(30000); 22 GPFDAT = (~(i<<4)); 23 if (++i == 8){ 24 i = 0; 25 } 26 } 27 28 return 0; 29 }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
效果图如下:
三、我们在做另外一个实验用按键来控制LED灯的亮灭,
3.1按键连线
key0 --- GPF0
key1 --- GPF1
key3 --- GPG3
GPG寄存器的地址如下图,需要注意的是,我们的按键是配置成输入引脚。
3.2相关代码
crt0.S
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 .text 2 .global _start 3 _start: 4 5 ldr R0,=0x53000000 @ 设置为看门狗寄存器 6 7 mov R1,#0x0 8 str R1,[R0] 9 10 ldr SP,=1024*4 @ 设置栈指针 11 12 bl main 13 halt_loop: 14 b halt_loop
![复制代码](https://common.cnblogs.com/images/copycode.gif)
key_leds.c
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 #define GPFCON (*(volatile unsigned long *)0x56000050) 2 #define GPFDAT (*(volatile unsigned long *)0x56000054) 3 4 #define GPGCON (*(volatile unsigned long *)0x56000060) 5 #define GPGDAT (*(volatile unsigned long *)0x56000064) 6 7 //LED1,LED2,LED3 8 #define GPF4_OUT (1<<(4*2)) 9 #define GPF5_OUT (1<<(5*2)) 10 #define GPF6_OUT (1<<(6*2)) 11 12 #define GPF4_MASK (3<<(4*2)) 13 #define GPF5_MASK (3<<(5*2)) 14 #define GPF6_MASK (3<<(6*2)) 15 16 //KEY1,KEY2,KEY3 17 #define GPF0_IN (0<<(0*4)) 18 #define GPF2_IN (0<<(2*4)) 19 #define GPG3_IN (0<<(3*4)) 20 21 #define GPF0_MAKS (3<<(0*2)) 22 #define GPF2_MAKS (3<<(2*2)) 23 #define GPG3_MAKS (3<<(3*2)) 24 25 int main() 26 { 27 unsigned long key_status; 28 29 //LED设置为输出引脚 30 GPFCON = GPFCON & ~(GPF4_MASK|GPF5_MASK|GPF6_MASK); 31 GPFCON = GPFCON | (GPF4_OUT|GPF5_OUT|GPF6_OUT); 32 //KEY设置为输入引脚 33 GPFCON = GPFCON & ~(GPF0_MAKS|GPF2_MAKS); 34 GPFCON = GPFCON | (GPF0_IN|GPF2_IN); 35 36 GPGCON = GPGCON & ~(GPG3_MAKS); 37 GPGCON = GPGCON | GPG3_IN; 38 39 while(1){ 40 key_status = GPFDAT; 41 42 if (key_status & (1<<0)) 43 GPFDAT |= (1<<4); 44 else 45 GPFDAT &= ~(1<<4); 46 47 if (key_status & (1<<2)) 48 GPFDAT |= (1<<5); 49 else 50 GPFDAT &= ~(1<<5); 51 52 key_status = GPGDAT; 53 54 if (key_status & (1<<3)) 55 GPFDAT |= (1<<6); 56 else 57 GPFDAT &= ~(1<<6); 58 } 59 return 0; 60 }
![复制代码](https://common.cnblogs.com/images/copycode.gif)
Makefile
![复制代码](https://common.cnblogs.com/images/copycode.gif)
1 key_leds.bin:crt0.S key_leds.c 2 arm-linux-gcc -g -c -o crt0.o crt0.S 3 arm-linux-gcc -g -c -o key_leds.o key_leds.c 4 arm-linux-ld -Ttext 0x00000000 -g crt0.o key_leds.o -o key_leds_elf 5 arm-linux-objcopy -O binary -S key_leds_elf key_leds.bin 6 arm-linux-objdump -D -m arm key_leds_elf > key_leds.dis 7 clean: 8 rm *.o *.bin *.dis key_leds_elf
![复制代码](https://common.cnblogs.com/images/copycode.gif)
实验现象:
相关的代码大家可以从我的github账号上下载:
https://github.com/zzb2760715357/100ask
目录结构如下: