Tiny6410按键轮询方式控制LED的SD卡启动裸机程序

Tiny6410按键轮询方式控制LED的SD卡启动裸机程序

    这个程序已经写了很久了,感觉程序没什么问题,但是一运行就出问题,就是按键没什么反应,不能控制LED灯的亮灭,上网找资料,大部分用按键控制LED的裸机程序都是用中断的方式进行的,我对中断还不是太了解,所以想用轮询的方式试试,所以一直以来也没试验成功。今天是大年初二,晚上闲来无事,加之又在网上搜了点别的程序,决定试试。试了以后还是不行,只好又编译自己以前写的这个程序再试。

我一直怀疑是Tiny6410启动方式导致这个按键不能控制LED(我是以SD卡启动的),但一直不能确定。因为从我查到的资料来看,选择SD卡启动时,GPN这一组GPIO口13到15位(GPN[15:13])被用来确定是否由SD卡启动,而Tiny6410的几个按键正好接在GPN这一组GPIO上,因此很可能是由这个原因引起的。如图:


    但突然间我想起,如果以SD卡启动,启动以后把选择开关拨到Nand方式,是否能释放这几个按键呢,一试果然如此,真是太高兴了,两三个月的功夫没白费。编译环境是Linux gcc,程序如下:

程序保存为:led.c

#define GPKCON0  (*(volatile unsigned long *)(0x7f008800))

#define GPKDAT   (*(volatile unsigned long *)(0x7f008808))

#define GPKPUD   (*(volatile unsigned long *)(0x7f00880C))

#define GPNCON  (*(volatile unsigned long *)(0x7f008830))

#define GPNDAT  (*(volatile unsigned long *)(0x7f008834))

#define GPNPUD  (*(volatile unsigned long *)(0x7f008838))

#define GPK4_msk (15<<4*4)  //清空相应的位

#define GPK5_msk (15<<5*4)

#define GPK6_msk (15<<6*4)

#define GPK7_msk (15<<7*4)

#define GPK4_out (1<<4*4) //设置相应的位

#define GPK5_out (1<<5*4)

#define GPK6_out (1<<6*4)

#define GPK7_out (1<<7*4)

#define GPN0_msk (3<<0*2) //清空相应的位

#define GPN1_msk (3<<1*2)

#define GPN2_msk (3<<2*2)

#define GPN3_msk (3<<3*2)

#define GPN0_in (0<<0*2) //设置相应的位

#define GPN1_in (0<<1*2)

#define GPN2_in (0<<2*2)

#define GPN3_in (0<<3*2)

 

int main()

{

    unsignedlong key_data=0;

    GPKCON0&= ~(GPK4_msk | GPK5_msk | GPK6_msk | GPK7_msk);

    GPKCON0|= (GPK4_out | GPK5_out | GPK6_out | GPK7_out);

    GPKPUD= 0xaaaa;

    GPNCON= 0;

    //GPNCON&= ~(GPN0_msk | GPN1_msk | GPN2_msk | GPN3_msk);

    //GPNCON|= (GPN0_in | GPN1_in | GPN2_in | GPN3_in);

    GPNPUD=0xaaaa;

    GPKDAT= 0xffff;

    while(1)  

    {

       key_data= GPNDAT;

       if(key_data& (1<<0))

           GPKDAT|= (1<<4);

       else

           GPKDAT&= ~(1<<4);

       key_data= GPNDAT;

       if(key_data& (1<<1))

           GPKDAT|= (1<<5);

       else

           GPKDAT&= ~(1<<5);

 

       key_data= GPNDAT;  

       if(key_data& (1<<2))

           GPKDAT|= (1<<6);

       else

           GPKDAT&= ~(1<<6);

       key_data= GPNDAT;  

       if(key_data& (1<<3))

           GPKDAT|= (1<<7);

       else

           GPKDAT&= ~(1<<7);

    }

    return0;

}

程序保存为:start.S

.text

.global _start

_start:

@/* 关看门狗 */

@/* 往WTCON(0x7E004000)写0 */

  ldr r0, =0x7E004000

  mov r1, #0

    strr1, [r0]

    ldrsp, =8*1024

    blmain

halt:

    bhalt

其实我觉得没必要这一段汇编程序,因为Tiny6410一上电自动关闭了Watchdog,以及初始化了许多东东,但也许必要吧,因为好像它不自动设置堆栈!

程序保存为:makefile

led.bin: start.o led.o

    arm-linux-ld-Ttext 0 -o led.elf start.o led.o

    arm-linux-objcopy-O binary -S led.elf led.bin

    arm-linux-objdump-D -m arm led.elf > led.dis

%.o: %.S

    arm-linux-gcc-o $@ $< -c

%.o: %.c

    arm-linux-gcc-o $@ $< -c

   

clean:

    rm*.o led.elf led.bin led.dis

 

好了,以上便是所有的源程序了,用Tiny6410自带的编译工具链一下,写在SD卡上运行吧。

注意,一定是先由SD卡启动,这时按键是不起作用的,且有三盏Led灯是亮的,然后把启动选择开关拨到Nand方式(靠近铜柱支架那边),此时Led灯全灭,然后就可以按键控制了,就是这样!

在Linux下写SD卡请看http://blog.csdn.net/zzwpublic/article/details/8273846

如果是>2G的卡,只是写的位置不同,其余一样,下文有例子。也可参考http://blog.csdn.net/jenkinslee/article/details/7219051

不>2G的卡叫SD卡,>2G的叫SDHC,区别就在于容量。对于sd,应写到 (totalSector - 18) 的扇区;对于sdhc卡,应写到(totalSector-1042)的扇区。

下面是一个led.bin写入的例子,使用的是2G的sd卡,所以应该写到 -512 * 18处。我使用的是linux环境,用dd命令就可以对绝对磁盘扇区做读写。还有一个问题就是要知道sd卡的大小,用fdisk命令就可以了:

 $ sudo fdisk -l /dev/sdb

Disk /dev/sdb: 2059 MB, 2059403264 bytes
207 heads, 37 sectors/track, 525 cylinders
Units = cylinders of 7659 * 512 = 3921408 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xb2a60e0e

Device Boot Start End Blocks Id System
/dev/sdb1 1 525 2010469 b W95 FAT32

    所以要写入的地址为 2059403264 - 18 * 512 = 2059394048

    然后用dd命令写入led.bin :

    $ sudo dd if=./led.bin of=/dev/sdbseek=2059394048 bs=1

    至此一张可启动的sd卡就完成了,插入tiny6410, 选择sd卡启动模式。

    注:友善宣称它提供的SDFlasher.exe可以不论sd和sdhc卡都可以支持,从而优于三星提供的IROM_Flushing_Tool,三星的要选择是sd还是sdhc。其实原理很简单,SDFlasher.exe写入时不论是-18扇区还是-1042扇区都写入。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值