本文使用的开发板是九鼎创展的X210 iNand版本。
从以上LED的原理图上,我们发现开发板上一共有5颗LED,其中一颗D26的接法是:正极接5V,负极接地。因此D26这颗LED只要上电就会常亮,所以这颗LED是电源指示灯。
剩下4颗LED的接法是:正极接3.3V,负极接了SoC上的一个引脚(GPIO)。
具体的详细接法如下:
D22:GPJ0_3
D23:GPJ0_4
D24:GPJ0_5
D25:PWMTOUT1(GPD0_1)
二、查阅数据手册中GPJ0的相关部分
由上图可知,GPJ0相关的寄存器包括六个:GPJ0CON、GPJ0DAT、GPJ0PUD、GPJ0DRV、GPJ0CONPDN、GPJ0PUDPDN。实际上真正控制LED的主要是GPJ0CON、GPJ0DAT这两个。
点亮LED,主要的步骤是:
1、GPJ0CON寄存器中,选中Output模式
由上图可以得出以下几点信息:
(1)GPJ0一共有8个引脚,分别记作GPJ0_0 ~ GPJ0_7。
(2)GPJ0CON寄存器每个引脚占4位,例如GPJ0_0对应的bit位为bit0 ~ bit3,GPJ0_3对应的bit位为bit12 ~ bit15。给相应的寄存器位写入相应的值,该引脚硬件就会按照相应的模式去工作,例如给bit12 ~ bit15写入0001,GPJ0_3引脚就成为输出模式了。
(3)GPJ0CON寄存器的地址是0xE0200240,GPJ0DAT寄存器的地址是0xE0200244。
(4)低电平亮、高电平灭。
三、代码结构
(1)Makefile:编译时使用make得到led.bin(USB启动下载的镜像)和210.bin(SD卡启动下载的镜像)。
led.bin: start.o arm-linux-ld -Ttext 0x0 -o led.elf $^ arm-linux-objcopy -O binary led.elf led.bin arm-linux-objdump -D led.elf > led_elf.dis gcc mkv210_image.c -o mkx210 ./mkx210 led.bin 210.bin %.o : %.S arm-linux-gcc -o $@ $< -c %.o : %.c arm-linux-gcc -o $@ $< -c clean: rm *.o *.elf *.bin *.dis mkx210 -f
(2)mkv210_image.c:为BL1添加校验头,由led.bin加工得到210.bin。
#include#include #include #define BUFSIZE (16*1024) #define IMG_SIZE (16*1024) #define SPL_HEADER_SIZE 16 #define SPL_HEADER " S5PV210 HEADER " int main (int argc, char *argv[]) { FILE *fp; char *Buf, *a; int BufLen; int i; int nbytes, fileLen; unsigned int checksum, count; // 1. 3个参数 if (argc != 3) { printf("Usage: %s
(3)start.S:控制LED的汇编源代码。
四、编码控制LED
1、点亮中间一颗LED(GPJ0_4)
#define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start _start: // 把所有引脚都设置为输出模式 ldr r0, =0x11111111 ldr r1, =GPJ0CON str r0, [r1] // 把中间一颗LED(GPJ0_4)的输出设置为0,其余两颗设置为1,剩下的其它位不管 ldr r0, =((1<<3) | (1<<5)) ldr r1, =GPJ0DAT str r0, [r1] b .
2、LED闪烁效果
#define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start _start: // 把所有引脚都设置为输出模式 ldr r0, =0x11111111 ldr r1, =GPJ0CON str r0, [r1] flash: // 全部点亮 ldr r0, =((0<<3) | (0<<4) | (0<<5)) ldr r1, =GPJ0DAT str r0, [r1] // 延时 bl delay // 使用bl进行函数调用 // 全部熄灭 ldr r0, =((1<<3) | (1<<4) | (1<<5)) ldr r1, =GPJ0DAT str r0, [r1] // 延时 bl delay b flash // 延时函数 delay: ldr r2, =9000000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 // r2 = r2 -1 cmp r2, r3 // cmp会影响Z标志位,如果r2等于r3则Z=1,下一句中eq就会成立 bne delay_loop mov pc, lr // 函数调用返回
3、流水灯效果
#define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start _start: // 把所有引脚都设置为输出模式 ldr r0, =0x11111111 ldr r1, =GPJ0CON str r0, [r1] flash: // 点亮LED1(GPJ0_3),其它熄灭 ldr r0, =~(1<<3) ldr r1, =GPJ0DAT str r0, [r1] bl delay // 点亮LED2(GPJ0_4),其它熄灭 ldr r0, =~(1<<4) ldr r1, =GPJ0DAT str r0, [r1] bl delay // 点亮LED3(GPJ0_5),其它熄灭 ldr r0, =~(1<<5) ldr r1, =GPJ0DAT str r0, [r1] bl delay b flash // 延时函数 delay: ldr r2, =9000000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 cmp r2, r3 bne delay_loop mov pc, lr