近日得空,又打算折腾折腾这块mini2440开发板。说实话,这板子真心不好用,光盘里面给的USB下载工具兼容性差也就算了,连稳定性都成问题。在网上看到的都是USB驱动方面的问题,好在之前已经找到了替代方案(之前博文已经介绍过),但终究是不太稳定,没办法,凑合用着吧!
我希望从裸机程序开始学习ARM,总觉得唯有把ARM当作8位单片机来使,方能更透彻地理解所有硬件资源。可是照着学习视频做了很多遍,也没能成功点亮一颗LED灯,要么make后报出一些莫名其妙的错误,要么make后的BIN文件在ARM里面看不到一丝效果。这让我很没面子啊~加之工作忙,就不了了之了。周末手痒,打算好好研究一下这个问题,下载了几集天祥电子的ARM视频,发现了国嵌视频里面没有的内容,找到了症结所在。
第一个问题,没有搞清楚除了main.c源文件,究竟还需要哪些文件。类比51单片机的C语言编程,应该还需要包含很多宏定义的.h文件,还有.c和.h文件内所include的源文件。与51单片机不同的是,ARM还需要一个.s的引导程序,也即是2440init.s文件。这是在国嵌的视频中看不到的,也难怪搞了半天还不知道那些.s的.h文件从何处来的,怎么用,什么时候用了。
第二个问题,ADS1.2里面要设置编译环境,DebugRel Setting/ARM Linker菜单中,教程里面只是设置了Output页的起始地址0x30000000,殊不知,没有设置Option页的Image entry point为0x30000000,也没有设置Layout页的Object/Symbol和Section,实践证明这是要报错的。多说一句,Object/Symbol和Section到底填写什么内容,是要依据引导代码2440init.s中定义的代码段来决定,如定义如下:AREA Init,CODE,READONLY,那么Object/Symbol就应该是2440init.s对应的“2440init.o”,Section应该是“Init”。
第三个问题,我们看到国嵌的实例代码目录下面有“inc”和“src”文件夹,前者存放着.h文件,后者存放着.c和.s文件。我们自己按照视频来新建project,却没有这两个文件夹。这是怎么回事?原来,和51单片机一样,我们所用到的.h文件和.c、.s文件,都要add to project才对,而且这两个文件夹是自己手动建立的,不是ADS自动产生的。天祥电子的教程告诉我们,可以直接将文件夹add to project以便查找文件。
解决了上述问题,自己试着编写了一个控制LED的程序,make后download到mini2440,果真可以运行!
代码如下:
#define GLOBAL_CLK 1
#include
#include
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"
void Led_port_init(void);
#define BEEP_OFF ~(1<<0)
#define LED1_ON ~(1<<5)
#define LED2_ON ~(1<<6)
#define LED3_ON ~(1<<7)
#define LED4_ON ~(1<<8)
#define BEEP_ON (1<<0)
#define LED1_OFF (1<<5)
#define LED2_OFF (1<<6)
#define LED3_OFF (1<<7)
#define LED4_OFF (1<<8)
/*************************************************
Function name: delay
Parameter : times
Description : 延时函数
Return : void
Argument : void
Autor & date :
**************************************************/
void delay(int times)
{
int i;
for(;times>0;times--)
for(i=0;i<400;i++);
}
/*************************************************
Function name: Main
Parameter : void
Description : 主功能函数,当按下KEY6时所有的LED亮,否则全灭。
Return : void
Argument : void
Autor & date :
**************************************************/
void Main(void)
{
// int i;
Led_port_init();
//Key_port_init();
while(1)
{
//if(Key_scan())
if(!(rGPGDAT&(0x01<<6))) //这两句if的条件有何区别?
{
/* 全亮 */
rGPBDAT = rGPBDAT&(LED1_ON)&(LED2_ON)&(LED3_ON)&(LED4_ON);
delay(100000);
}
else
{
/* 全灭 */
rGPBDAT = rGPBDAT|(LED1_OFF)|(LED2_OFF)|(LED3_OFF)|(LED4_OFF);
delay(100000);
}
}
}
/*************************************************
Function name: Led_port_init
Parameter : void
Description : mini2440开发板有4个引脚连接了LED发光
二极管,分别是GPB5--LED1,GPB6—LED2
GPB7--LED3,GPB8--LED4,GPB0--beep.该函数的作用
是对其个引脚进行初始化。
Return : void
Argument : void
Autor & date : Daniel
**************************************************/
void Led_port_init(void)
{
/*设置GPB0,GPB5-GPB8为输出端口*/
rGPBCON &= ~((3<<0)|(3<<10)|(3<<12)|(3<<14)|(3<<16));
rGPBCON |= (1<<0)|(1<<10)|(1<<12)|(1<<14)|(1<<16);
}
/*************************************************
Function name:Key_port_init
Parameter :void
Description :mini2440开发板有6颗按键,与CPU的GPIO口连接关系如下:
KEY1--EINT8 /GPG0, KEY2--EINT11/GPG3,
KEY3--EINT13/GPG5, KEY4--EINT14/GPG6,
KEY5--EINT15/GPG7, KEY6--EINT19/GPG11.
本函数需要将端口初始化为输入端口。
Return :void
Argument :void
Autor @ date :Eric Fu @ August 18,2013
*************************************************/
void Key_port_init(void)
{
/*Set the GPG0/3/5/6/7/11 as input ports*/
rGPGCON &= ~((3<<0)|(3<<3)|(3<<6)|(3<<7)|(3<<11));
}
/*************************************************
Function name:Key_scan
Parameter :void
Description :scan the action of KEYs。
Return :int
Argument :void
Autor @ date :Eric Fu @ August 18,2013
*************************************************/
int Key_scan(void)
{
if(!(rGPGDAT&(0x01<<6))) //if the KEY6 pressed?
{
delay(100);
if(!(rGPGDAT&(0x01<<6))) //if the KEY6 pressed?
return 1;
else
return 0;
}
else
return 0;
}
Project内包含的文件如下:
个人拙见,希望对和我一样的初学者有用......
用户377235 2013-8-26 09:45
撸主精神可嘉,安步当车,从第一帖到gpio彪了两年,2440芯片都下课了
用户1407078 2013-8-24 10:26
用户403664 2013-8-19 09:42