Chinaunix首页 | 论坛 | 博客
  • 博客访问: 918019
  • 博文数量: 84
  • 博客积分: 4334
  • 博客等级: 上校
  • 技术积分: 1610
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-27 07:49
文章分类

全部博文(84)

文章存档

2012年(5)

2011年(21)

2010年(58)

分类: 嵌入式

2010-10-23 11:54:46

S3C2440共有130个I/O 端口,共分为GPA,GPB,...,GPJ.对于这几组GPIO引脚,他们的寄存器是相似的:
GPxCON:用于配置(configure),选择引脚的功能。
GPxDAT:用于读/写数据。
GPxUP:确定是否使用内部上拉电阻。(没有GPAUP寄存器。)
 
PORTB~PORTJ在寄存器操作方面完全相同。GPxCON中每两位控制一根引脚:00表示输入,01表示输出,10表示特殊功能,11保留不用。
一。使用汇编代码点亮一个LED。参照韦东山大哥的,上图是从韦大哥的书中截图的,而我的开发板对应的是GPF接口。仅此区别。
(1)led_on.S汇编代码。

@******************************************************************************
@ File:led_on.S
@ 功能:LED点灯程序,点亮LED1
@******************************************************************************
            
.text              @伪代码指令,指定下面开始是代码段,
.global _start
_start:
            LDR R0,=0x56000050          @ R0设为GPFCON寄存器。此寄存器
                                        @ 用于选择端口F各引脚的功能:.
                                        @ 是输出、是输入、还是其他
            MOV R1,#0x00000001
            STR R1,[R0]                 @ 设置GPF0为输出口,[1:0]=0b01
            
            LDR R0,=0x56000058          @ R0设为GPFUP寄存器。此寄存器
                                        @ 用于选择端口F使能禁止上拉的功能:
            MOV R1,#0x00000000
            STR R1,[R0]                 @ 使能GPF0上拉
            
            LDR R0,=0x56000054          @ R0设为GPFDAT寄存器。此寄存器
                                        @ 用于读/写端口F各引脚的数据
            MOV R1,#0x00000000          @ 此值改为0x00000001,
                                        @ 可让LED1熄灭
            STR R1,[R0]                 @ GPF0输出0,LED1点亮
            
MAIN_LOOP:
            B MAIN_LOOP

(2)Makefile文件:

led_on.bin : led_on.S
    arm-linux-gcc -g -c -o led_on.o led_on.S
    arm-linux-ld -Ttext 0x0000000 -g led_on.o -o led_on_elf
    arm-linux-objcopy -O binary -S led_on_elf led_on.bin
clean:
    rm -f led_on.bin led_on_elf *.o

其中:arm-linux-ld -Ttext 0x0000000 -g led_on.o -o led_on_elf:指定了代码段的运行地址为0x0000_0000,并指定生成连接文件led_on_elf,由于没有定义数据段和BSS段的起始地址,它们呗依次放在代码段的后面。arm-linux-objcopy -O binary -S led_on_elf led_on.bin:由连接文件生产可执行文件led_on.bin,下载进开发板即可观察到led1点亮了。

重要说明:玩单片机的时候我们一般是把程序下载到单片机的自身带的flash中,而s3c2440不是这样的,我们是把程序下载到它的外部存储器中,如Norflash或者NandFlash.只有s3c2440是不能运行的,它的最小系统包括了,SDRAM(即内存),FLASH(Nand或者Nor,即相当于硬盘)。我们把程序下载到NandFlash中而不是CPU本身,那么当选择从NandFlash启动CPU的时候(即OM0,OM1设置为00的时候)S3C2440会自动根据内部的硬件结构将NandFlash中的前4K代码复制到S3C2440的内部RAM中,此时内部RAM的地址为0,程序将从0开始执行。

一。使用C语言点亮一个LED。
(1)crt0.S

@******************************************************************************
@ 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

(2)len_on.c

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

int main()
{
    GPFCON = 0x00000004; // 设置GPF1为输出口, 位[3:2]=0b01
    GPFUP = 0x0;//使能上拉
    GPFDAT = 0x00000000; // GPF1输出0,LED1点亮

    return 0;
}


(3)Makefile:

led_on.bin : crt0.S led_on.c
    arm-linux-gcc -g -c -o crt0.o crt0.S
    arm-linux-gcc -g -c -o led_on.o led_on.c
    arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on.o -o led_on_elf
    arm-linux-objcopy -O binary -S led_on_elf led_on.bin
    arm-linux-objdump -D -m arm led_on_elf > led_on.dis
clean:
    rm -f led_on.dis led_on.bin led_on_elf *.o


比较疑惑的一点是crt0.S中bl main @ 调用C程序中的main函数,怎么实现的,我是这么理解的,arm-linux-ld连接生成了led_on_elf文件,这是一个文件。
阅读(2696) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~