首先说我也是菜鸟,但相信只要认真学习菜鸟总会变成老鸟的。相信你学习嵌入式、学习ARM有着各种各样的原因,但不管怎样,最终目的都是想掌握甚至精通嵌入式的设计和开发。大多数人都在入门时如无头苍蝇到处乱撞,而不得要领。鉴于此,特写此专题,算是抛砖引玉,希望和大家一起学习。废话就不多说,进主题。
一、硬件平台准备:ARM开发板一块(本人用的S3C2410),PC机(最好台式的,笔记本貌似串并口可能没有,相对来说就麻烦点)。
二、软件环境:相信大多数人都是Windows,那就需要虚拟机安装Linux发行版和交叉工具链(本人用Vmware+RedHat9.0+交叉工具链)或Windows下模拟软件Cygwin+交叉工具链。当然也可以使用ADS1.2等。烧写软件:Windows下的sjf2410(三星公司的)或改进版都行,当然Linux下有对应的工具Jflash-s3c2410,其用法也很相似。当然可以选择H-Jtag,这里只烧写简单的小程序就没必要了。sjf2410.exe使用:在命令行(开始--->运行--->cmd)下执行"sjf2410.exe /f *.bin /d=5",来烧写编译生成的bin文件。
三、上面准备了一大通,想来这是必须的。工欲善其事,必先利其器嘛。下面一步步实现点灯**。
1.通俗的说,GPIO(General Purpose I/O Ports,通用输入/输出端口)是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚状态---是高电平还是低电平。S3C2410有117个I/O端口,分A~H共8组。每组的寄存器是类似的:GPxCON用于选择引脚功能;GPxDAT用于读/写引脚数据;GPxUP用于确定是否使用内部上拉电阻(注:没有GPAUP)。使用软件访问单个引脚的操作无非3种情况:输出高低电平、检测引脚状态和中断。
2.点灯**的思路就是设置开发板上的LED灯所接端口的GPxCON寄存器为输出状态,然后向GPxDAT寄存器的相应位输出高/低电平---高电平熄灭LED灯,低电平点亮LED灯。所以首先要根据你的开发板找到LED所接端口,然后对应S3C2410的Datasheet来设置相应寄存器。故实现步骤为:编写源代码、生成可执行程序、烧写bin文件和运行程序。下面给出相应的汇编语言和C语言的实现(注:主要参考嵌入式Linux应用开发完全手册)。GPF各寄存器的Datasheet描述如下图所示:
3.汇编代码实现:
.text /*表示下面的语句属于代码段*/
.global _start /*定义全局标号_start*/
_start:
LDR R0,=0x56000050 /* GPFCON寄存器,此寄存器用来选择端口各引脚的功能是输出/输入/其他。我开发板的LED灯接在F端口的4~7引脚*/
MOV R1,#0x00000100 /*位[9:8]=0b01*/
STR R1,[R0] /*设置GPF4为输出*/
LDR R0,=0X56000054 /* GPFDAT寄存器,此寄存器用来读/写端口F各引脚的数据*/
MOV R1,#0X00000000
STR R1,[R0] /*GPF4输出0,点亮LED*/
main_loop:
b main_loop
4.C语言实现:在裸板上执行C代码时必须有个启动程序,通过它跳转到C程序使C代码能正常执行。
4.1启动代码:
.text
.global _start
_start:
ldr r0, =0x56000010 /*WATCHDOG寄存器地址*/
mov r1, #0x0
str r1, [r0] /*写入0,禁止WATCHDOG,通常说的关门喂狗*/
ldr sp, =1024*4 /*设置堆栈<=4k*。NandFlash中的代码在复位后会移到内部ram中,此ram只有4K*/
bl main /*调用C程序中的main函数,执行C代码点灯*/
halt_loop:
b halt_loop
4.2C代码:
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
int main()
{
GPFCON = 0x00000100; // 设置GPF4为输出口, 位[9:8]=0b01
GPFDAT = 0x00000000; // GPF4输出0,LED1点亮
return 0;
}
5.编写Makefile文件,只给出汇编的Makefile文件说明(C的类似)。
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 #ELF格式转换成二进制格式
clean:
rm -f led.bin led_elf *.o #清除生成文件
|