首页 > 代码库 > Tiny6410之LED裸机驱动
Tiny6410之LED裸机驱动
操作步骤:
第一步:查看开发板电路原理图
找到LED 的管脚所对应的寄存器
nLED_1 - GPK4
nLED_2 - GPK5
nLED_3 - GPK6
nLED_4 - GPK7
由原理图可知LED对应的寄存器为GPK寄存器,由二极管的特性可知当LED_n为低电平时LED灯亮
第二步:查看数据手册找到GPK寄存器的地址及每位表示的意义
Register Address
GPKCON0 0x7F008800
GPKCON1 0x7F008804
GPKDAT 0x7F008808
GPKPUD 0x7F00880C
通过数据手册知道GPK寄存器有两个控制寄存器(GPKCON0和GPKCON1)和一个数据寄存器(GPKPDAT)
[GPK0 GPK1 GPK2 GPK3 GPK4 GPK5 GPK6 GPK7] 在GPKCON0中每4位表示一个GBKn(0<=n<=7)
[GPK8 GPK9 GPK10 GPK11 GPK12 GPK13 GPK14 GPK15] 在GPKCON1中每4位表示一个GBKn(8<=n<=15)
第三步:设置寄存器的值
由第一步可知主要用到的管脚为GPK4、GPK5、GPK6、GPK7
由第二步可知GPK[4-7]有GPKCON0 控制
1)将管脚设置为输出
LED作为显示是属于输出由数据手册可知(0000 = Input 0001 = Output)故只要讲GPKn对应的4位设置为0001即表示输出
2)将管脚的值设为低电平
LED的数据寄存器为GPKDAT,由数据手册关于GPKDAT的介绍就可知GPKDAT第n位的值即表示GPKn(0<=n<=15)的电平状态(一般都是0表示低电平,1表示高电平)
第四步:编写代码
1)关看门狗
通过数据手册找到看门狗的控制寄存器地址
Register Address
WTCON 0x7E004000
2)设置控制寄存器(GPKCON0)的值
3)设置数据寄存器(GPKDAT)的值
第五步:编写Makefile
1 led.bin: start.o main.o 2 arm-linux-ld -Ttext 0x50000000 -o led.elf $^ 3 arm-linux-objcopy -O binary led.elf led.bin 4 arm-linux-objdump -D led.elf > led_elf.dis 5 %.o : %.S 6 arm-linux-gcc -o $@ $< -c 7 %.o : %.c 8 arm-linux-gcc -o $@ $< -c 9 clean:10 rm *.o *.elf *.bin *.dis -rf
第六步:在虚拟机Linux环境下编译生成.bin文件
第七步:将上一步生成的.bin文件烧写到开发板上运行
代码实现:
汇编版:
1 .global _start 2 _start: 3 //关闭看门狗,防止不断重启 4 ldr r0,= 0x7E004000 //;将看门狗寄存器的地址赋给r0 5 mov r1,#0 //;将r1赋值为0 6 str r1, [r0] //;将r1的值装载到r0寄存器中 7 //;即将地址为0x7E004000的寄存器的值赋值为0 8 //设置GPKCON0寄存器 9 ldr r0, =0x7E008800 //;将GPKCON0寄存器的地址赋值为r010 ldr r1, =0x11110000 //;转换为0001,0001,0001,0001,0000,0000,0000,000011 str r1, [r0] //;即将 GPK7,GPK6,GPK5,GPK4 赋值设置成为输出12 13 mov r2, #0x100014 led_blink: 15 //设置GPKDAT寄存器 使GPK4-GPK7引脚输出低电平,LED亮16 ldr r0, =0x7F008808 //;将GPKDAT寄存器的地址赋值为r017 mov r1, #018 str r1, [r0] 19 //延时20 bl delay21 22 //设置GPKDAT寄存器 使GPK4-GPK7引脚输出高电平,LED灭23 ldr r0, =0x7F008808 //;将GPKDAT寄存器的地址赋值为r024 mov r1, #0x00f025 str r1, [r0]26 //延时27 bl delay28 29 sub r2 ,r2 ,#1 //;表示r2=r2-130 cmp r2, #0 //;将r2和0比较31 bne led_blink //;如果r2!=0 则跳转到 led_blink处执行32 33 halt:34 b halt //;死循环35 36 delay:37 mov r0, #0x100000038 39 delay_loop:40 cmp r0,#0;41 sub r0, r0, #142 bne delay_loop43 mov pc, lr44
C语言版:
1 //start.S 2 .global _start 3 _start: 4 //关看门狗 5 ldr r0, =0x7E004000 6 mov r1, #0 7 str r1, [r0] 8 9 // 设置堆栈10 ldr sp,=0xC002000 //SRAM 的映射地址是0X0C00000011 12 //调用点灯函数13 bl main14 halt:15 b halt16 17 //////////////////////////18 //Tiny6410Addr.halt19 #ifndef _Tiny6410Addr_H20 #define _Tiny6410Addr_H21 //GPK 22 #define GPKIO_BASE (0x7F008800)23 #define rGPKCON0 (*(volatile unsigned long*)(GPKIO_BASE+0x00))24 #define rGPKDAT (*(volatile unsigned long*)(GPKIO_BASE+0x08))25 26 #endif27 28 ///////////////////29 //led.c30 #include "Tiny6410Addr.h"31 #define GPK4_OUT (1<<4*4)32 #define GPK5_OUT (1<<4*5)33 #define GPK6_OUT (1<<4*6)34 #define GPK7_OUT (1<<4*7)35 //延时函数36 void delay()37 {38 volatile int i = 0x10000;39 while (i--);40 }41 42 int main()43 {44 unsigned int i = 0x10;45 //将GPK4-7设置为输出46 rGPKCON0 = GPK4_OUT | GPK5_OUT |GPK6_OUT |GPK7_OUT;47 //跑马灯式48 while (1)49 {50 rGPKDAT = i;51 i++;52 if(i == 0x100)53 i=0x10;54 delay();55 }56 57 return 0;58 }
Tiny6410之LED裸机驱动