热度 19
2013-8-23 11:12
1770 次阅读|
3 个评论
近日得空,又打算折腾折腾这块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 ~(10) #define LED1_ON ~(15) #define LED2_ON ~(16) #define LED3_ON ~(17) #define LED4_ON ~(18) #define BEEP_ON (10) #define LED1_OFF (15) #define LED2_OFF (16) #define LED3_OFF (17) #define LED4_OFF (18) /************************************************* Function name: delay Parameter : times Description : 延时函数 Return : void Argument : void Autor date : **************************************************/ void delay(int times) { int i; for(;times0;times--) for(i=0;i400;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(0x016))) //这两句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 = ~((30)|(310)|(312)|(314)|(316)); rGPBCON |= (10)|(110)|(112)|(114)|(116); } /************************************************* 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 = ~((30)|(33)|(36)|(37)|(311)); } /************************************************* 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(0x016))) //if the KEY6 pressed? { delay(100); if(!(rGPGDAT(0x016))) //if the KEY6 pressed? return 1; else return 0; } else return 0; } Project内包含的文件如下: 个人拙见,希望对和我一样的初学者有用......