ARM课程设计.docx

上传人:b****8 文档编号:10478511 上传时间:2023-02-13 格式:DOCX 页数:27 大小:647.05KB
下载 相关 举报
ARM课程设计.docx_第1页
第1页 / 共27页
ARM课程设计.docx_第2页
第2页 / 共27页
ARM课程设计.docx_第3页
第3页 / 共27页
ARM课程设计.docx_第4页
第4页 / 共27页
ARM课程设计.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

ARM课程设计.docx

《ARM课程设计.docx》由会员分享,可在线阅读,更多相关《ARM课程设计.docx(27页珍藏版)》请在冰豆网上搜索。

ARM课程设计.docx

ARM课程设计

 

Arm课程实践

参考文献

1.张蛤.32位嵌入式系统硬件设计与调试【M].北京:

机械工业出版社,2005.

2.孙天泽,袁文菊,张海峰.嵌入式设计及Linux驱动开发设计——基于ARM9处理器[M].北京:

电子工业出版社。

2005.

3.CorbetJ,RubiniA,eta1.Linux设备驱动程序(第二版)[M].魏永明,骆刚,等译.北京:

中国电力出版社,2002.

4.唐泽圣,周嘉玉,李新友.计算机图形学基础[M].北京:

清华大学出版社,1995

 

设计目的

 

1.学习4X4键盘的与CPU的接口原理;

2.掌握键盘芯片HD7279的使用,及8位数码管的显示方法;

一.设计思路

本实验为模拟输入输出接口的实验,其基本原理就是使用一片缓冲芯片74LS244来把CPU外面的输入数据写入CPU的并行总线上,之后,并行总线上的数据被一片数据锁存芯片74LS273保留,CPU通过选中锁存芯片,并读取预先设给锁存器地址内的内容,就可以把数据读出,来确定外面的数据的高低。

本实验的输入是用8个带锁的按键的按下和未按下两种工作状态来表示输入接口的高低状态,然后,再通过8个LED灯亮和灭两种工作状态,以及LCD上用数据值来清楚的反映各状态的输出显示,从而完成模拟的输入输出接口的实现。

二.关键技术

1.ARM9处理器:

EL-ARM-830型教学实验系统属于一种综合的教学实验系统,该系统采用了目前在国内普遍认同的ARM920T核,32位微处理器,实现了多模块的应用实验。

它是集学习、应用编程、开发研究于一体ARM实验教学系统。

用户可根据自己的需求选用不同类型的CPU适配板,兼容ARM7与ARM9,而不需要改变任何配置,同时,实验系统上的Tech_V总线能够拓展较为丰富的实验接口板。

用户在了解Tech_V标准后,更能研发出不同用途的实验接口板。

除此之外,在实验板上有丰富的外围扩展资源(数字、模拟信号发生器,数字量IO输入输出,语音编解码、人机接口等单元),可以完成ARM的基础实验、算法实验和数据通信实验、以太网实验。

 

 

图1-1-1EL-ARM-830实验教学系统的功能框图

2.ARMC语言程序的基本规则

在ARM程序的开发中,需要大量读写硬件寄存器,并且尽量缩短程序的执行时间的代码一般使用汇编语言来编写,比如ARM的启动代码,ARM的操作系统的移植代码等,除此之外,绝大多数代码可以使用C语言来完成。

C语言使用的是标准的C语言,ARM的开发环境实际上就是嵌入了一个C语言的集成开发环境,只不过这个开发环境和ARM的硬件紧密相关。

在使用C语言时,要用到和汇编语言的混合编程。

当汇编代码较为简洁,则可使用直接内嵌汇编的方法,否则,使用将汇编文件以文件的形式加入项目当中,通过ATPCS的规定与C程序相互调用与访问。

ATPCS,就是ARM、Thumb的过程调用标准(ARM/ThumbProcedureCallStandard),它规定了一些子程序间调用的基本规则。

如寄存器的使用规则,堆栈的使用规则,参数的传递规则等。

在C程序和ARM的汇编程序之间相互调用必须遵守ATPCS。

而使用ADS的C语言编译器编译的C语言子程序满足用户指定的ATPCS的规则。

但是,对于汇编语言来说,完全要依赖用户保证各个子程序遵循ATPCS的规则。

具体来说,汇编语言的子程序应满足下面3个条件:

●在子程序编写时,必须遵守相应的ATPCS规则;

●堆栈的使用要遵守相应的ATPCS规则;

●在汇编编译器中使用-atpcs选项。

汇编程序调用C程序

汇编程序的设置要遵循ATPCS规则,保证程序调用时参数正确传递。

在汇编程序中使用IMPORT伪指令声明将要调用的C程序函数。

在调用C程序时,要正确设置入口参数,然后使用BL调用。

C程序调用汇编程序

汇编程序的设置要遵循ATPCS规则,保证程序调用时参数正确传递。

在汇编程序中使用EXPORT伪指令声明本子程序,使其他程序可以调用此子程序。

在C语言中使用extern关键字声明外部函数(声明要调用的汇编子程序)。

在C语言的环境内开发应用程序,一般需要一个汇编的启动程序,从汇编的启动程序,跳到C语言下的主程序,然后,执行C程序,在C环境下读写硬件的寄存器,一般是通过宏调用,在每个项目文件的Startup2410/INC目录下都有一个2410addr.h的头文件,那里面定义了所有关于2410的硬件寄存器的宏,对宏的读写,就能操作2410的硬件。

具体的编程规则同标准C语言。

3.ADS1.2开发环境:

a.ADS1.2下建立工程

1.运行ADS1.2集成开发环境(CodeWarriorforARMDeveloperSuite),点击File|New,在New对话框中,选择Project栏,其中共有7项,ARMExecutableImage是ARM的通用模板。

选中它即可生成ARM的执行文件。

同时,如图2-1-1

图2-1-1

还要在,Projectname栏中输入项目的名称,以及在Location中输入其存放的位置。

按确定保存项目。

2.在新建的工程中,选择Debug版本,如图2-1-2,使用Edit|DebugSettings菜单对Debug版本进行参数设置。

图2-1-2

3.在如图2-1-3中,点击DebugSetting按钮,弹出2-1-4图,选中TargetSetting项,在Post-linker栏中选中ARMfromELF项。

按OK确定。

这是为生成可执行的代码的初始开关。

 

 

图2-1-3

图2-1-4

4.在如图2-1-5中,点击ARMAssembler,在ArchitectureorProcesser栏中选ARM920T。

这是要编译的CPU核。

图2-1-5

5.在如图2-1-6中,点击ARMCCompliler,在ArchitectureorProcesser栏中选ARM920T。

这是要编译的CPU核。

图2-1-6

6.在如图2-1-7中,点击ARMlinker,在outpur栏中设定程序的代码段地址,以及数据使用的地址。

图中的ROBase栏中填写程序代码存放的起始地址,RWBase栏中填写程序数据存放的起始地址。

该地址是属于SDRAM的地址。

图2-1-7

图2-1-8

在options栏中,如图2-1-8,Imageentrypoint要填写程序代码的入口地址,其他保持不变,如果是在SDRAM中运行,则可在0x30000000—0x33ffffff中选值,这是64MSDRAM的地址,但是这里用的是起始地址,所以必须把你的程序空间给留出来,并且还要留出足够的程序使用的数据空间,而且还必须是4字节对齐的地址(ARM状态)。

通常入口点Imageentrypoint为0x30000000,ro_base也为0x30000000。

在Layout栏中,如图2-1-9,在Placeatbeginningofimage框内,需要填写项目的入口程序的目标文件名,如,整个工程项目的入口程序是2410init.s,那么应在Object/Symbol处填写其目标文件名2410init.o,在Section处填写程序入口的起始段标号。

它的作用是通知编译器,整个项目的开始运行,是从该段开始的。

图2-1-9

7.在如图2-1-10中,即在DebugSetting对话框中点击左栏的ARMfromELF项,在Outputfilename栏中设置输出文件名*.bin,前缀名可以自己取,在Outputformat栏中选择Plainbinary,这是设置要下载到flash中的二进制文件。

图2-1-10中使用的是test.bin.

图2-1-10

8.到此,在ADS1.2中的基本设置已经完成,可以将该新建的空的项目文件作为模板保存起来。

首先,要将该项目工程文件改一个合适的名字,如S3C2410ARM.mcp等,然后,在ADS1.2软件安装的目录下的Stationary目录下新建一个合适的模板目录名,如,S3C2410ARMExecutableImage,再将刚刚设置完的S3c2410ARM.mcp项目文件存放到该目录下即可。

这样,就能在图2-1-10中看到该模板。

9.新建项目工程后,就可以执行菜单Project|AddFiles把和工程所有相关的文件加入,ADS1.2不能自动进行文件分类,用户必须通过Project|CreateGroup来创建文件夹,然后把加入的文件选中,移入文件夹。

或者鼠标放在文件填加区,右键点击,即出!

如图2-1-11

图2-1-11

先选AddFiles,加入文件,再选CreateGroup,创建文件夹,然后把文件移入文件夹内。

读者可根据自己习惯,更改Edit|Preference窗口内关于文本编辑的颜色、字体大小,形状,变量、函数的颜色等等设置。

如图2-1-12。

图2-1-12

2.ADS1.2下仿真、调试

在ADS1.2下进行仿真调试,首先需要一根仿真调试电缆。

其驱动程序的安装和使用在光盘中的\实验软件\ARM9_RDI中,里面有相关的文档。

在连上调试电缆后,给实验箱上电,打开调试软件AXDDebugger。

点击File|loadimage加载文件ADS.axf(\实验程序\HARDWARE\ADS\实验一\ADS\ADS_data目录下)。

打开超级终端,设置其参数为:

波特率为115200,数据位数8,奇偶校验无,停止位无1,数据流控无。

点击全速运行,出现图2-1-13的界面:

图2-1-13

在最后介绍调试按钮

上图,左起第一个是全速运行,第二个是停止运行,第三个跳入函数内部,第四个单步执行,第五个跳出函数。

4.模拟输入输出接口单元

8bit的数字量输入(由八个带自锁的开关产生),通过74LS244缓冲;8bit的数字量输出(通过八个LED灯显示),通过74LS273锁存。

数字量的输入输出都映射到CPU的IO空间。

数字值的显示的通过八个LED灯和LCD屏,按下一个键,表示输入一个十进制的“0”值,8个键都不按下,则数字量的十进制数值为255,8个键都按下,则数字量的十进制数值为0,通过LED灯,和LCD的显示可以清楚的看到实验结果。

三.程序流程

1.本实验使用实验教学系统的CPU板,LCD单元。

在进行本实验时,音频的左右声道开关、触摸屏中断选择开关、AD通道选择开关等均应处在关闭状态。

2.在PC机并口和实验箱的CPU板上的JTAG接口之间,连接仿真调试电缆,以及串口间连接公/母接头串口线。

3.检查连接是否可靠,可靠后,接入电源线,系统上电。

按下LCD电源开关。

4.打开ADS1.2开发环境,从里面打开\实验程序\HARDWARE\ADS\实验十\IO_SIM.mcp项目文件,进行编译。

5.编译通过后,进入ADS1.2调试界面,加载实验程序\HARDWARE\ADS\实验十\IO_SIM_Data\Debug中的映象文件程序映像IO_SIM.axf。

6.在ADS调试环境下全速运行映象文件。

LCD上有图形显示后,按下实验箱下部一排中的任一模拟输入的带锁键值,观察8位数码管上方的8个LED灯的亮灭情况,以及LCD上的显示情况。

每个按键代表1个数字位,按键均不按下,代表数字量为255,全按下为0,每个按键的都是2的权值,在不按下时,最靠近键盘的按键代表1,之后依次是2;4;8;16;32;64;128。

按下时均代表0。

该实验是从数据总线上把检测到的数据变化,锁存到锁存器中,然后又从总线上读出数据,显示到LCD上,来模拟I/O实现。

四.主要源代码

#include

#include"2410addr.h"

#include"2410lib.h"

#include"def.h"

#include"..\inc\lcdlib.h"

U32(*frameBuffer16BitTft640480)[SCR_XSIZE_TFT_640480/2];

unsignedlongLcd_Init(inttype)

{

switch(type)

{

caseMODE_TFT_16BIT_640480:

//frameBuffer16BitTft640480=(U32(*)[SCR_XSIZE_TFT_640480/2])LCDFRAMEBUFFER;

rLCDCON1=(CLKVAL_TFT_640480<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0;

//TFTLCDpanel,16bppTFT,ENVID=off

rLCDCON2=(VBPD_640480<<24)|(LINEVAL_TFT_640480<<14)|(VFPD_640480<<6)|(VSPW_640480);

rLCDCON3=(HBPD_640480<<19)|(HOZVAL_TFT_640480<<8)|(HFPD_640480);

rLCDCON4=(MVAL<<8)|(HSPW_640480);

rLCDCON5=(1<<11)|(1<<9)|(1<<8)|

(1);//FRM5:

6:

5,HSYNCandVSYNCareinverted

//rLCDSADDR1=(((U32)frameBuffer16BitTft640480>>22)<<21)|M5D((U32)frameBuffer16BitTft640480>>1);

rLCDSADDR1=((LCDFRAMEBUFFER>>22)<<21)|M5D(LCDFRAMEBUFFER>>1);

//rLCDSADDR2=M5D(((U32)frameBuffer16BitTft640480+(SCR_XSIZE_TFT_640480*LCD_YSIZE_TFT_640480*2))>>1);

rLCDSADDR2=M5D(((U8)LCDFRAMEBUFFER+(640*480*2))>>1);

//rLCDSADDR3=((0)<<11)|(480);

rLCDSADDR3=0x0;

rLCDINTMSK|=(3);//MASKLCDSubInterrupt

rLPCSEL&=(~7);//DisableLPC3600

rTPAL=0;//DisableTempPalette

break;

default:

break;

}

return0;

}

voidLcd_CstnOnOff(intonoff)

{

//1:

CSTNPanelon0:

CSTNPaneloff//

if(onoff==1)

rLCDCON1|=1;//ENVID=ON

else

rLCDCON1=rLCDCON1&0x3fffe;//ENVIDOff

rGPBUP=rGPBUP|(1<<5);//Pull-updisable

rGPBDAT=rGPBDAT&(~(1<<5))|(onoff<<5);//GPB5=OnorOff

rGPBCON=rGPBCON&(~(3<<10))|(1<<10);//GPD9=output

}

voidLcd_EnvidOnOff(intonoff)

{

if(onoff==1)

rLCDCON1|=1;//ENVID=ON

else

rLCDCON1=rLCDCON1&0x3fffe;//ENVIDOff

}

voidLcd_Lpc3600Enable(void)

{

rLPCSEL&=~(7);

//rLPCSEL|=(7);//240320,EnableLPC3600:

LTS350Q1-PD1

rLPCSEL=(0);//240320,disableLPC3600:

LTS350Q1-PE2

}

voidLcd_PowerEnable(intinvpwren,intpwren)

{

//GPG4issettedasLCD_PWREN

rGPGUP=rGPGUP&(~(1<<4))|(1<<4);//Pull-updisable

rGPGCON=rGPGCON&(~(3<<8))|(3<<8);//GPG4=LCD_PWREN

//EnableLCDPOWERENABLEFunction

rLCDCON5=rLCDCON5&(~(1<<3))|(pwren<<3);//PWREN

rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5);//INVPWREN

}

#include"..\..\Startup2410\inc\2410addr.h"

#include"..\..\Startup2410\inc\2410lib.h"

#include"..\..\Startup2410\inc\option.h"

#include"..\inc\Uart_driver.h"

#include"..\..\Startup2410\inc\def.h"

#include

#include

#include

#include

#include

staticintwhichUart=0;

voidUart_Init(intpclk,intbaud)

{

inti;

if(pclk==0)

pclk=PCLK;

rUFCON0=0x0;//UARTchannel0FIFOcontrolregister,FIFOdisable

rUFCON1=0x0;//UARTchannel1FIFOcontrolregister,FIFOdisable

rUFCON2=0x0;//UARTchannel2FIFOcontrolregister,FIFOdisable

rUMCON0=0x0;//UARTchaneel0MODEMcontrolregister,AFCdisable

rUMCON1=0x0;//UARTchaneel1MODEMcontrolregister,AFCdisable

//UART0

rULCON0=0x3;//Linecontrolregister:

Normal,Noparity,1stop,8bits

//[10][9][8][7][6][5][4][3:

2][1:

0]

//ClockSel,TxInt,RxInt,RxTimeOut,Rxerr,Loop-back,Sendbreak,TransmitMode,ReceiveMode

//010,0100,0101

//PCLKLevelPulseDisableGenerateNormalNormalInterruptorPolling

rUCON0=0x245;//Controlregister

//rUBRDIV0=((int)(pclk/16./baud)-1);//Baudratedivisiorregister0

rUBRDIV0=((int)(pclk/16./baud+0.5)-1);//Baudratedivisiorregister0

//UART1

rULCON1=0x3;

rUCON1=0x245;

rUBRDIV1=((int)(pclk/16./baud)-1);

//UART2

rULCON2=0x3;

rUCON2=0x245;

rUBRDIV2=((int)(pclk/16./baud)-1);

for(i=0;i<100;i++);

}

voidUart_Select(intch)

{

whichUart=ch;

}

voidUart_TxEmpty(intch)

{

if(ch==0)

while(!

(rUTRSTAT0&0x4));//Waituntiltxshifterisempty.

elseif(ch==1)

while(!

(rUTRSTAT1&0x4));//Waituntiltxshifterisempty.

elseif(ch==2)

while(!

(rUTRSTAT2&0x4));//Waituntiltxshifterisempty.

}

charUart_Getch(void)

{

if(whichUart==0)

{

while(!

(rUTRSTAT0&0x1));//Receivedataready

returnRdURXH0();

}

elseif(whichUart==1)

{

while(!

(rUTRSTAT1&0x1));//Receivedataready

returnRdURXH1();

}

elseif(whichUart==2)

{

while(!

(rUTRSTAT2&0x1));//Receivedataready

returnRdURXH2();

}

else

return0;

}

charUart_GetKey(void)

{

if(whichUart==0)

{

if(rUTRSTAT0&0x1)//Receivedataready

returnRdURXH0();

else

return0;

}

elseif(whichUart==1)

{

if(rUTRSTAT1&0x1)//Receivedataready

returnRdURXH1();

else

return0;

}

elseif(whichUart==2)

{

if(rUTRSTAT2&0x1)//Receivedataready

returnRdURXH2();

else

return0;

}else

return0;

}

voidUart_GetString(char*string)

{

char*string2=string;

charc;

while((c=Uart_Getch())!

='\r')

{

if(c=='\b')

{

if((int)string2<(int)string)

{

Uart_Printf("\b\b");

string--;

}

}

else

{

*string++=c;

Uart_SendByte(c);

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 管理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1