Tiny6410之LED裸机驱动
Posted 凌潇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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寄存器的地址赋值为r0 10 ldr r1, =0x11110000 //;转换为0001,0001,0001,0001,0000,0000,0000,0000 11 str r1, [r0] //;即将 GPK7,GPK6,GPK5,GPK4 赋值设置成为输出 12 13 mov r2, #0x1000 14 led_blink: 15 //设置GPKDAT寄存器 使GPK4-GPK7引脚输出低电平,LED亮 16 ldr r0, =0x7F008808 //;将GPKDAT寄存器的地址赋值为r0 17 mov r1, #0 18 str r1, [r0] 19 //延时 20 bl delay 21 22 //设置GPKDAT寄存器 使GPK4-GPK7引脚输出高电平,LED灭 23 ldr r0, =0x7F008808 //;将GPKDAT寄存器的地址赋值为r0 24 mov r1, #0x00f0 25 str r1, [r0] 26 //延时 27 bl delay 28 29 sub r2 ,r2 ,#1 //;表示r2=r2-1 30 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, #0x1000000 38 39 delay_loop: 40 cmp r0,#0; 41 sub r0, r0, #1 42 bne delay_loop 43 mov pc, lr 44
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 的映射地址是0X0C000000 11 12 //调用点灯函数 13 bl main 14 halt: 15 b halt 16 17 ////////////////////////// 18 //Tiny6410Addr.halt 19 #ifndef _Tiny6410Addr_H 20 #define _Tiny6410Addr_H 21 //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 #endif 27 28 /////////////////// 29 //led.c 30 #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裸机驱动的主要内容,如果未能解决你的问题,请参考以下文章
Linux-2.6.39在Tiny6410上的移植 - 外设驱动移植