ARM裸机实验
来源:互联网 发布:ubuntu单用户模式 编辑:程序博客网 时间:2024/05/02 04:06
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的地址。这句意思
是把这个地址值赋给r0.
mov r1,#0x15400 这句是把要传到GPBCON中的
值先赋给r1.
str r1,[r0]这句的意思就是把r1的值传给以r0中的值
为地址所指向的存储空间中,这就完成了设置
GPBCON的值。
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 unsigned long
*)0x56000010)
#define GPBDAT *((volatile unsigned long
*)0x56000014)
#define GPFCON *((volatile unsigned long
*)0x56000050)
#define GPFDAT *((volatile unsigned long
*)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
- ARM裸机实验
- ARM LED裸机实验(gun汇编)
- ARM裸机实验 UART串口(S3C2440A) TQ2440
- ARM裸机程序--GPIO实验 LED(1)
- ARM裸机程序--GPIO实验 LED(2)
- tiny6410裸机实验第1章--------------ARM汇编和编程基础(ARM汇编简介)
- ARM裸机重新开始
- arm 裸机程序
- arm裸机编程
- 学习arm裸机程序
- ARM裸机串口UART
- arm裸机开发
- arm裸机编程
- ARM裸机开发学习方法
- ARM裸机MMU调试
- ARM裸机入门简介
- ARM裸机-S5PV210简析
- ARM裸机之ADC
- C 语言可变参数实现原理
- C/C++混合编程
- 需求分析概述
- iphone开发中的delegate的理解一
- 在线考试系统设计时必须考虑的问题之一------------批改试卷问题
- ARM裸机实验
- ASP.NET验证控件之CompareValidator
- VS2010 这个warning怎么解决?
- 为什么使用 !!(双重否等?)
- Linux下tmpfs与ramfs的区别
- 函数指针的强制转换用法
- Android 访问权限设置
- open_Call_b2g();open_Call_g2b();
- 夫妻相处歌谣