logo资料库

ARM裸机实验之用按键控制LED灯.doc

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
ARM 裸机实验之用按键 控制 LED 灯 嵌入式可以说是一门很复杂的学科,要想学透并不 容易,初学者可以从裸机实验开始学起,所以我为大 家准备了一些裸机实验,供大家学习参考,高手就不 用看了,呵呵额。。。。。 想当初我学嵌入式时,觉的有点单片机的基础,学 起 ARM 来应该不难,没想到事实并不是我想的那样, 单片机相比 ARM 来说差的远了,呵呵,也并不是说 ARM 很不好学,只要找到合适的方法,肯下功夫,一 段时间之后,你就会收到满意的效果的,好了,进入 主题。。。。。。。 主机操作系统:linux redhat9.0 目标板 :TQ2440 ARM: S3C2440 SDRAM:64M NOR FLASH : 2M NAND FLASH:256M 记得当初刚开始学的时候,总是想先弄明白 ARM 是通过什么方式控制它的 IO 端口的,现在我还是先从 这方面开始讲起吧。。。。。。 通过三星公司 S3C2440 的数据手册可知,它有 9 组 GPIO 端口,分别是 GPA-GPJ(没有 GPI), 它的每组端口的输入和输出都是通过配置相关的寄 存器来实现的,比如说 GPB 这一组,GPB 共有 11 个 IO 端 口 GPB0-GPB10 , 相 应 的 控 制 寄 存 器 为
GPBCON、GPBDAT、GPBUP。 GPBCON 用来设置 GPB 端口是用来输出还是输入 还是用来做第二功能,GPBDAT 则是控制 IO 口的输 出电平或从中得到输入电平,GPBUP 是决定各个端口 是否使用上拉电阻功能。 正因为这样给了我们很大方便,使得我们通过修改 寄存器就可以控制端口。下面就来看看我们的程序吧。 首先说要实现的功能:用开发板上的 4 个按键来控 制 4 个 LED 灯的亮灭,哪个键按下,相应的灯就亮起, 键松开,灯就灭掉。 电路连接情况:4 个按键分别接的是 GPF0、GPF1、 GPF2、GPF4 4 个 LED 灯分别接的是 GPB5 、GPB6、 GPB7、GPB8 先来一个简单的程序,让 4 个 LED 灯全亮,看一下 整个程序的流程: .text .global start _start: ldr r0,=0x56000010 mov r1,#0x15400 str r1,[r0] ldr r0,=0x56000014 mov r1,#0x0 str r1,[r0] main_loop: b main_loop 整个程序只有几行,下面咱们来一行一行分析: ldr r0,=0x56000010 查看 S3C2440 数据手册可知其中 0x56000010 就是寄存器 GPBCON 的地址。这句意思
值先赋给 r1. mov r1,#0x15400 这句是把要传到 GPBCON 中的 str r1,[r0]这句的意思就是把 r1 的值传给以 r0 中的值 为 地 址 所 指 向 的 存 储 空 间 中 , 这 就 完 成 了 设 置 GPBCON 的值。 是把这个地址值赋给 r0. ldr r0,=0x56000014 mov r1,#0x0 str r1,[r0] 后面这三行 就是给控制 GPB 端口高低电平的寄存器赋值,使引脚 都输出低电平,根据电路图,这时 4 个 LED 灯就会全 部点亮了。 这是源程序,放到 linux 系统里面,在同一文件夹下还 要 编 写 Makefile 文 件 , 这 样 编 译 起 来 比 较 省 事 。 Makefile 文件内容如下: led.bin:led.S arm-linux-gcc -g -c -o led.o led.S arm-linux-ld -Ttext 0x0000000 -g led.o -o led_elf arm-linux-objcopy -O binary -S led_elf led.bin clean: rm -f led.bin led_elf *.o 这里暂不介绍 Makefile 文件的写法,以后会有专门章 节讲解的。 下面是通过按键控制 LED 灯亮灭的程序,程序分为两 部分,由于我们打算用 C 语言编写,所以要先用汇编
语言做一下初始化工作,包括关闭看门狗和设置堆栈。 汇编语言程序: .text .global start _start: ldr r0,=0x53000000 mov r1,#0 ;关闭看门狗 str r1,[r0] ldr sp,=1024*4 ;设置堆栈 bl main ;跳转到 main 函数 main_loop: bl main_loop 保存为 :led2.S C 语言程序: /*定义各个端口寄存器,GPB 用于 LED 灯的输出控制, GPF 用于按键的输入控制*/ #define GPBCON *((volatile *)0x56000010) #define GPBDAT *((volatile *)0x56000014) #define GPFCON *((volatile *)0x56000050) unsigned unsigned unsigned long long long
unsigned long #define GPFDAT *((volatile *)0x56000054) /*初始化各个端口寄存器*/ void IO_init() { GPBCON=0x55<<10;//将 GPB5-8 端口设为输出,用 于控制 LED 灯的两灭 GPBDAT=0x0f<<5;//初始化 LED 灯,使其初始状态 //GPF 初始状态即为输入,可取默认值, 为熄灭 不做更改 } void LED1() { //////////////////////////////////在死循环中依次查询各个按 键的状态,若键按下,相应的灯亮,若抬起,灭 while(1) { if(!(GPFDAT&0x02)) GPBDAT=GPBDAT&~(0x01<<5);
else GPBDAT=GPBDAT|(0x01<<5); if(!(GPFDAT&0x10)) GPBDAT=GPBDAT&~(0x01<<6); else GPBDAT=GPBDAT|(0x01<<6); if(!(GPFDAT&0x04)) GPBDAT=GPBDAT&~(0x01<<7); else GPBDAT=GPBDAT|(0x01<<7); if(!(GPFDAT&0x01)) GPBDAT=GPBDAT&~(0x01<<8); else GPBDAT=GPBDAT|(0X01<<8); } } /////////////////////////C 语言主函数 void main() { IO_init(); LED1(); }
保存为 main.c 如果上面那个让 LED 灯全亮的程序大家能理解的话, 那这个程序也很好理解,它只不过是多了对 GPF 几个 端口的电平读取,然后根据电平判断某个按键是否被 按下,来决定让哪个 LED 灯点亮或是熄灭。 这个程序的功能是某个按键按下 LED 灯就点亮, 等按键松开 LED 灯就熄灭,如果你能将这个程序理解 了的话,为了加深印象,你可自己试着做做改动,比 如某个按键按下后它控制的 LED 灯点亮,直到有另一 个按键按下它才会熄灭,相应的 LED 灯又会点亮。 下面是本程序的 Makefile 文件: led2.bin:led2.S main.c arm-linux-gcc -g -c -o led2.o led2.S arm-linux-gcc -g -c -o main.o main.c arm-linux-ld -Ttext 0x0000000 -g led2.o main.o -o led2_elf arm-linux-objcopy -O binary -S led2_elf led2.bin arm-linux-objdump -D -m arm led2_elf > led2.dis clean: rm -f led2_elf *.o led2.dis
分享到:
收藏