Chinaunix首页 | 论坛 | 博客
  • 博客访问: 260582
  • 博文数量: 128
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 487
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-24 17:43
个人简介

人生境界:明智、中庸、诚信、谦逊

文章分类

全部博文(128)

文章存档

2014年(12)

2013年(116)

我的朋友

分类: 嵌入式

2013-03-04 15:49:37

原文地址:S3C2410子板LED灯点亮程序 作者:stuyou

主机环境:WindowsXP+EmbestIED(深圳英蓓特公司提供)
开发板环境:EdukitIII实验箱+s3c2410子板
问题描述:在没有LINUX操作系统的情况下,编写程序点亮实验箱上的LED灯,点亮顺序如下:先把4个LED灯全部熄灭,然后依次点亮4个LED灯,最后把4个LED灯全部点亮,用ARM汇编和C程序两种方式实现
【1.硬件原理】
  
                                         图1 LED硬件连接图
如图1所示,LED硬件连接图(参考ARM9实验基础教程),4个LED灯分别和GPF4-7连接,首先应该把GPF4-7设置为输出功能,当GPF4-7输出为1时,相应的LED灯熄灭,当GPF4-7输出为0时,相应的LED灯点亮
 
 
                                         图2 GPF各寄存器地址
通过查询s3c2410硬件手册(um_s3c2410_manual_r10.pdf),可以知道,GPF各寄存器的地址如图2所示,这里只用到F端口的控制寄存器GPFCON和F端口的数据寄存器GPFDAT,首先应该把GPF4-7设置为输出功能,通过查询GPFCON各位的功能,就可以得知如何设置,见图3(um_s3c2410_manual_r10.pdf)
 
 
                                    图3 GPFCON各位含义
由图3,查询GFPCON各位的含义得知,如果要把GFP4-7设置为输出(Output),那么GPFCON的[15:8]=01010101,转换成32位的16进制就是0x00005500。
 
                                        图4 GPFDAT各位含义
由图4(um_s3c2410_manual_r10.pdf)可知,如果想让GPF4-7输出0或1,那么就直接把0或1写入GPFDAT[7:4],这样与之相应的LED灯就点亮或熄灭。
 
【2.ARM汇编程序实现】
 
 
@******************************************************************************
@Name: ledtestarm.s
@Desc: led灯全灭,然后依次点亮4个LED灯,最后把4个LED灯全部点亮
@Parameter:
@Return:
@Author: yoyoba(stuyou@126.com)
@Date: 2011-5-7
@Modify: 2011-5-7
@*******************************************************************************

.text
.global _start
_start:
    ldr r0,=0x56000050    @GPFCON地址为0x56000050
    mov r1,#0x00005500    
    str r1,[r0]            @GPFCON写入0x00005500,即GFP4-7设置为输出功能
    
loop:    
    ldr r0,=0x56000054 @GPFDAT地址为0x56000054
    mov r1,#0x000000f0
    str r1,[r0]            @GPFDAT写入0x000000f0,即GPFDAT[7:4]=1111,4个LED灯全灭
    
    mov r1,#0x000000e0
    str r1,[r0]            @GPFDAT写入0x000000e0,即GPFDAT[7:4]=1110,LED4点亮
    
    mov r1,#0x000000d0
    str r1,[r0]            @GPFDAT写入0x000000d0,即GPFDAT[7:4]=1101,LED5点亮
    
    mov r1,#0x000000b0
    str r1,[r0]            @GPFDAT写入0x000000b0,即GPFDAT[7:4]=1011,LED6点亮
    
    mov r1,#0x00000070
    str r1,[r0]            @GPFDAT写入0x00000070,即GPFDAT[7:4]=0111,LED7点亮
    
    mov r1,#0x00000000
    str r1,[r0]            @GPFDAT写入0x00000000,即GPFDAT[7:4]=0000,4个LED灯全亮

    b loop
.end


在EmbestIED中新建一个名为ledtestarm的工程,把该源代码添加到工程中,工程设置需注意以下两点:1.project/setting/debug/download中的下载地址设置为0x00000000,即ARM启动后运行的第一条代码就是该程序的第一条指令;2.project/setting/linker中的Link Options应添加选项-Ttext 0x00000000,表示把该程序连接到地址0x00000000。然后就可以编译,连接,下载运行了,运行时为了观察LED灯的亮灭情况,可以单步运行程序。

【3.C语言实现】

C语言执行的第一条指令,并不在main函数中,生成一个C程序的可执行文件时,编辑器通常会在我们的代码中加上几个被称为启动文件的代码——crt1.o、crti.o、crtend.o、crtn.o等,它们是标准库文件,这些代码设置C程序的堆栈等,然后调用main函数,它们依赖于操作系统,在裸板上这些代码无法执行,所以需要自己写一个,名字为ctr0.S,内容如下:

@******************************************************************************
@Name: crt0.s
@Desc: 自己编写的C语言程序的启动程序,通过它转入C程序
@Parameter:
@Return:
@Author: yoyoba(stuyou@126.com)
@Date: 2011-5-7
@Modify: 2011-5-7
@*******************************************************************************/
.text
.global _start
_start:
    ldr r0,=0x53000000    @WATCHDOG寄存器地址
    mov r1,#0x0
    str r1,[r0]            @写入0,禁止WATCHDOG,否则CPU会不断重启

    ldr sp,=1024*4        @设置堆栈,注意:不能超过4KB,因为现在可用的内存只有4KB
    
    bl Main                @调用C程序中的main函数,注意这里写成Main,或__gccmain,
                        @C程序的主函数名相应的也应该写为Main()或__gccmain()
                        @具体原因可参考ARM9基础实验教程中的3.7实验(ARM汇编与C相互调用)
halt_loop:
    b halt_loop
.end


下面是C语言实现的点亮LED灯的程序

/******************************************************************************
*Name: ledtestc.c
*Desc: led灯全灭,然后依次点亮4个LED灯,最后把4个LED灯全部点亮
*Parameter:
*Return:
*Author: yoyoba(stuyou@126.com)
*Date: 2011-5-7
*Modify: 2010-5-7
********************************************************************************/

#define GPFCON    (*(volatile unsigned long *)0x56000050)    //GPFCON地址为0x56000050

#define GPFDAT    (*(volatile unsigned long *)0x56000054)    //GPFDAT地址为0x56000054


int Main()                //注意Main函数名的写法

{
    GPFCON=0x00005500;    //GPFCON写入0x00005500,即GFP4-7设置为输出功能

    while(1)
    {       
        GPFDAT=0x000000f0;    //GPFDAT写入0x000000f0,即GPFDAT[7:4]=1111,4个LED灯全灭
        
        GPFDAT=0x000000e0;    //GPFDAT写入0x000000e0,即GPFDAT[7:4]=1110,LED4点亮
        
        GPFDAT=0x000000d0;    //GPFDAT写入0x000000d0,即GPFDAT[7:4]=1101,LED5点亮
        
        GPFDAT=0x000000b0;    //GPFDAT写入0x000000b0,即GPFDAT[7:4]=1011,LED6点亮
 
        GPFDAT=0x00000070;    //GPFDAT写入0x00000070,即GPFDAT[7:4]=0111,LED7点亮
       
        GPFDAT=0x00000000;    //GPFDAT写入0x00000000,即GPFDAT[7:4]=0000,4个LED灯全亮
    }
    return 0;
}


工程设置及程序运行方法与ARM汇编程序相同。 
阅读(510) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~