第一课:GPIO操作——LED & 按键
2013-04-11 16:28
204 查看
前言
学习嵌入式已经快一年了,却是第一次正经的开始从ARM的裸板程序开始学习,有些汗颜……准备学习裸板程序的一部分,然后接着学习相应的设备驱动开发。第一次学博文,欢迎拍砖
第一课:GPIO操作——LED & 按键
环境:
软件:Ubuntu9.10 source insight3.5 oflash JTAG等驱动
硬件:ARM 2440 (韦东山配套教材)
参考教材:嵌入式Linux应用开发完全手册 韦东山著
一系列的环境搭建,操作步骤书中和视频教材解释也挺详细的
只是记录下学习过程的心得
按键点亮 LED (C语言 )
最终文件:
led_key.c :C程序文件,实现点亮led
crt0.s :裸板程序中的启动代码(汇编)
led_key.lds
:连接脚本
Makefile :实现程序的预处理、编译、汇编和链接以及清除工作
实现:
此处GPIO的操作需要:
1.判断key
2.点亮/灭led
a.配置功能:输出/输入/其他
key为输入,led引脚为输出功能
b.读key引脚,根据值来设置led引脚高电平LED熄灭,低电平LED点亮(参看电路图)
写程序之前先了解一下ARM2440的两种启动方式
1.Nand flash启动
a.在开发板上电启动的时候,CPU将Nand Flash开始的前4K数据复制到SRAM,即“Steppingstone”(此时内部RAM的起始地址为0);
b.CPU跳转地址0开始执行。
以上两步均为硬件执行
2.Nor flash启动
Nor flash可以像内存一样进行读操作,却不可想内存一样写
a.0地址指向Nor flash
b.CPU 从0地址取址执行
由于是裸板程序,因此需要在C语言文件之前实现一系列的初始化工作。
1)软件相关的初始化:
a.设置栈,即初始化SP指针,指向内存的某一块区域。如果是SRAM,可直接使用,如果是SDAM,还需要初始化(韦东山的板子都是直接映射到SRAM的,因此可以直接使用)
b.设置C语言中的main返回地址
c.调用main函数
(以上两步直接通过bl main可实现,返回地址保存到了LR寄存器)
d.清理工作
(通过死循环来实现的
halt_loop : b halt_loop )
2)硬件初始化:
a.关看门狗,关中断
b.初始化时钟
c.初始化SDAM
(此次程序只关了看门狗)
这两步是由crt0.s来实现的,之后调用main函数
@****************************************************************************** @ File:crt0.S @ 功能:通过它转入C程序 @******************************************************************************
@.text部分是处理器开始执行代码的地方 @.global关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用 @.global _start让_start符号成为链接器可见的标识符 @这样链接器就知道跳转到程序中的什么地方并开始执行 @linux寻找这个_start标签作为程序的默认进入点
@转载自:http://hi.baidu.com/ahauwangjie/item/10e988e740160ee5fb42baa5
.text .global _start _start: ldr r0,= 0x53000000; @watchdog寄存器地址 mov r1,#0x0 str r1,[r0] ldr sp,= 1024 * 4 bl main halt_loop: b halt_loop
程序的具体实现:
//引脚定义 #define GPFCON (*(volatile unsigned long *)0x56000050) #define GPFDAT (*(volatile unsigned long *)0x56000054) #define GPGCON (*(volatile unsigned long *)0x56000060) #define GPGDAT (*(volatile unsigned long *)0x56000064) //LED引脚初始化定义 #define GPF4_MSK (3<<(4*2)) #define GPF5_MSK (3<<(5*2)) #define GPF6_MSK (3<<(6*2)) //按键引脚初始化定义 #define GPF0_MSK (3<<(0*2)) #define GPF2_MSK (3<<(2*2)) #define GPG3_MSK (3<<(3*2)) //led引脚输出定义 #define GPF4_out (1<<(4*2)) #define GPF5_out (1<<(5*2)) #define GPF6_out (1<<(6*2)) int main() { unsigned long temp; //先将led相应引脚置0,其他位保留 GPFCON &= ~(GPF4_MSK | GPF5_MSK |GPF6_MSK); //定义led引脚为输出 GPFCON |= (GPF4_out | GPF5_out | GPF6_out); //定义按键引脚为输入 GPFCON &= ~(GPF0_MSK | GPF2_MSK); GPGCON &= ~(GPG3_MSK); while(1) { //读取key值 temp = GPFDAT; //key值为0说明按键按下,为1表示没有按下 if(temp & (1<<0)) GPFDAT |= (1<<4); //熄灭led else GPFDAT &= ~(1<<4); //点亮led if(temp & (1<<2)) GPFDAT |= (1<<5); else GPFDAT &= ~(1<<5); temp = GPGDAT; if(temp & (1<<3)) GPFDAT |= (1<<6); else GPFDAT &= ~(1<<6); } return 0; }
led_key.lds:
SECTIONS { . = 0x00; .text : { *(.text) } .rodata ALIGN(4) : {*(.rodata)} .data ALIGN(4) : { *(.data) } .bss ALIGN(4) : { *(.bss) *(COMMON) } }关于连接脚本的细节,请参照相关文章:
http://blog.csdn.net/chepwavege/article/details/7401794
http://johnylai.i.sohu.com/blog/view/31725442.htm
Makefile:
led_key.bin : led_key.c crt0.s #依赖关系 arm-linux-gcc -g -c -o crt0.o crt0.s #编译crt0.s arm-linux-gcc -g -c -o led_key.o led_key.c #编译led_key.c arm-linux-ld -Tled_key.lds crt0.o led_key.o -o led_key_elf #通过连接脚本链接,生成led_key_elf文件 arm-linux-objcopy -O binary -S led_key_elf led_key.bin #生成二进制可执行文件 arm-linux-objdump -D -m arm led_key_elf > led_key.dis #生成反汇编文件 clean: rm -f led_key_elf led_key.bin led_key.dis *.o *~ #make clean
至此按键控制led的裸板程序写好,中间还有不少迷惑的地方,诸如Makefile中诸多参数的定义,连接脚本的编写,启动汇编程序的完善……
相关文章推荐
- stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)
- 02.ARM-mini2440-GPIO操作-led_on_c
- TI CC2530基础实验(普通GPIO操作——点亮led灯)
- STM32F407学习笔记——GPIO_按键控制LED亮灭
- STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
- [转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
- jz2440裸板开发之GPIO:用按键控制led
- 混杂设备LED驱动程序(GPIO操作函数实现)
- LPC2124--GPIO按键控制LED灯的闪烁
- S3C6410的GPIO基本操作(点亮LED)
- GPIO输出操作—使用固件库点亮LED--- 调试总结
- Linux中Ctrl+C、Ctrl+D等按键操作&进程相关命令
- TI CC2530基础实验(普通GPIO操作——按一下按键亮一下灯)
- Linux中Ctrl+C、Ctrl+D等按键操作&进程相关命令
- TI CC2530基础实验(GPIO通用I/O中断操作——按键控制灯的亮灭)
- stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)
- 单片机小白学步系列(二十一) IO口:基本的LED和按键操作
- Linux中Ctrl+C、Ctrl+D等按键操作&进程相关命令
- Contiki 3.0: GPIO操作
- 树莓派 Learning 003 — GPIO 002 输入模式 — 按键控制LED