纯led驱动-arm平台

来源:互联网 发布:淘宝网面膜 编辑:程序博客网 时间:2024/05/22 09:09

转:http://linux.chinaunix.net/techdoc/develop/2009/07/19/1125042.shtml


纯led驱动-arm平台来源: ChinaUnix博客  日期: 2009.07.19 22:10 (共有条评论) 我要评论 纯led驱动

第一章 纯驱动... 1
第二章 纯汇编led. 1
第三章 一个简单的led驱动... 2
第四章 按键驱动led程序... 3

第一章 纯驱动
以往我们介绍的都是linux下的led驱动的写法,今天给大家介绍没有操作系统的led写法,这种写法和单片机的led驱动几乎一样,通过此,更容易了解硬件本身。

第二章 纯汇编led
@******************************************************************************
@ File:led_on.S
@ 功能:LED点灯程序,点亮LED1
@******************************************************************************       
            
.text
.global _start
_start:     
@设置控制寄存器
            LDR     R0,=0x56000010      @ R0设为GPBCON寄存器。此寄存器
                                        @ 用于选择端口B各引脚的功能:
                                        @ 是输出、是输入、还是其他
            MOV     R1,#0x00000400        
            STR     R1,[R0]             @ 设置GPB5为输出口, 位[10:9]=0b01

@设置数据寄存器
            LDR     R0,=0x56000014      @ R0设为GPBDAT寄存器。此寄存器
                                        @ 用于读/写端口B各引脚的数据
            MOV     R1,#0x00000000      @ 此值改为0x00000020,
                                        @ 可让LED1熄灭
            STR     R1,[R0]             @ GPB5输出0,LED1点亮
MAIN_LOOP:
            B       MAIN_LOOP
第三章一个简单的led驱动
#define    GPBCON              (*(volatile unsigned long *)0x56000010)  // 控制和数据端口地址
#define    GPBDAT        (*(volatile unsigned long *)0x56000014)

#define    GPB5_out       (1
#define    GPB6_out       (1
#define    GPB7_out       (1
#define    GPB8_out       (1

/** 软件延时**/
void  wait(unsigned long dly)
{
       for(; dly > 0; dly--);
}

int main(void)
{
       unsigned long i = 0;
       
       GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;            // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出

       while(1){
              wait(30000);
              GPBDAT = (~(i         // 根据i的值,点亮LED1-4
              if(++i == 16)
                     i = 0;
       }

       return 0;
}

当c语言被编译成汇编之后,是不能直接在裸机上运行的。因为需要一些堆栈和一些xpu设置。

用下面的汇编来处理
@******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************       

.text
.global _start
_start:
            ldr     r0, =0x56000010     @ WATCHDOG寄存器地址
            mov     r1, #0x0                     
            str   r1, [r0]              @ 写入0,禁止WATCHDOG,否则CPU会不断重启
            
            ldr     sp, =1024*4         @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
                                        @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
            bl      main                @ 调用C程序中的main函数
halt_loop:
            b       halt_loop

将两者链接起来就可以了。


第四章 按键驱动led程序
#define GPBCON      (*(volatile unsigned long *)0x56000010)
#define GPBDAT      (*(volatile unsigned long *)0x56000014)

#define GPFCON      (*(volatile unsigned long *)0x56000050)
#define GPFDAT      (*(volatile unsigned long *)0x56000054)

#define GPGCON      (*(volatile unsigned long *)0x56000060)
#define GPGDAT      (*(volatile unsigned long *)0x56000064)

/*
* LED1-4对应GPB5、GPB6、GPB7、GPB8
*/
#define GPB5_out        (1
#define GPB6_out        (1
#define GPB7_out        (1
#define GPB8_out        (1

/*
* K1-K4对应GPG11、GPG3、GPF2、GPF0
*/
#define GPG11_in    ~(3
#define GPG3_in     ~(3
#define GPF2_in     ~(3
#define GPF0_in     ~(3

int main()
{
        unsigned long dwDat;
        // LED1-LED4对应的4根引脚设为输出
        GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ;

        // K1-K2对应的2根引脚设为输入
        GPGCON = GPG11_in & GPG3_in ;
        
        // K3-K4对应的2根引脚设为输入
        GPFCON = GPF2_in & GPF0_in ;

        while(1){
            //若Kn为0(表示按下),则令LEDn为0(表示点亮)
            dwDat = GPGDAT;             // 读取GPG管脚电平状态
        
            if (dwDat & (1        // K1没有按下
                GPBDAT |= (1       // LED1熄灭
            else    
                GPBDAT &= ~(1      // LED1点亮
                
            if (dwDat & (1         // K2没有按下
                GPBDAT |= (1       // LED2熄灭
            else    
                GPBDAT &= ~(1      // LED2点亮
    
            dwDat = GPFDAT;             // 读取GPF管脚电平状态
            
            if (dwDat & (1         // K3没有按下
                GPBDAT |= (1       // LED3熄灭
            else    
                GPBDAT &= ~(1      // LED3点亮
    
            if (dwDat & (1         // K4没有按下
                GPBDAT |= (1       // LED4熄灭
            else    
                GPBDAT &= ~(1      // LED4点亮
    }

    return 0;
}

在没有linux操作系统下写驱动,只需要操作相应的端口,就可以了。从这一点来说比较简单,而且用的代码也比较少。有了linux操作系统之后,需要在相应的框架下写驱动,虽然比较麻烦,但和其他功能相搭配,则功能会更加的丰富。

注意C语言的代码是不能直接运行的,必须加上一些相应的启动代码,各种启动代码基本差不多,上面已经介绍过了。

当链接之后,直接拷贝到系统内存中就可以了运行了。



文件:
arm 硬件结构中了解led驱动V1.rar
大小:
9KB
下载:
下载

0 0
原创粉丝点击