ARM工作原理实验指导书.docx
《ARM工作原理实验指导书.docx》由会员分享,可在线阅读,更多相关《ARM工作原理实验指导书.docx(69页珍藏版)》请在冰豆网上搜索。
ARM工作原理实验指导书
嵌入式系统原理实验指导书
(Ver1.0)
刘永平编写
西安邮电学院
2009-5-10
目录
实验一ARM集成开发工具——ADS练习5
1.1实验目的5
1.2实验设备5
1.3实验内容5
1.4实验预习要求5
1.5实验步骤5
1.6思考19
实验二汇编指令实验120
2.1实验目的20
2.2实验设备20
2.3实验内容20
2.4实验预习要求20
2.5实验步骤21
2.6实验参考程序23
2.7思考24
实验三汇编指令实验225
3.1实验目的25
3.2实验设备25
3.3实验内容25
3.4实验预习要求25
3.5实验步骤26
3.6实验参考程序27
3.7思考30
实验四GPIO控制实验32
4.1实验目的41
4.2实验设备41
4.3实验内容41
4.4实验原理41
4.5实验硬件原理图43
4.6实验预习44
4.7实验过程44
4.8实验参考程序44
4.9思考45
实验五UART通信实验48
5.1实验目的48
5.2实验设备48
5.3实验内容48
5.4实验原理49
5.5实验硬件原理图49
5.6实验预习50
5.7实验过程50
5.8实验参考程序51
5.9思考61
实验六中断实验62
6.1实验目的62
6.2实验设备62
6.3实验内容62
6.4实验原理63
6.5实验硬件原理图63
6.6实验预习63
6.7实验过程63
6.8实验参考程序63
6.9思考66
总论
本实验包含两部分,前面三个实验是ARM7指令系统指令实验,使用ADS的编译器和调试器进行仿真调试,主要目的是掌握ARM7的指令系统和开发工具的使用,理解ARMCPU的工作过程。
后面三个实验是真实的ARM系统,硬件微控制器芯片为LPC2131(ARMCPU核+GPIO部件、UART0部件、UART1部件、Timer1、Timer2、VIC部件等),硬件电路板为广州周立功公司开发的EasyARM2131,学习配置ARM芯片内各模块部件,初步掌握简单嵌入式系统的构成原理和简单应用。
开发软件为ADS,调试接口为硬件JTAG模块(仿真器)+JTAG驱动程序构成开发系统。
这部分时需要查看LPC2131芯片的外部特性、内部模块原理和配置方法。
实验一ARM集成开发工具——ADS练习
1.1实验目的
了解ADS1.2集成开发环境的使用方法
1.2实验设备
●硬件:
PC机一台
●软件:
WindowsXP/2000系统,ADS1.2集成开发环境
1.3实验内容
在ADS环境下创建工程、编辑源文件、编译、链接、调试。
(1)建立一个新的工程。
(2)建立一个汇编文件,并添加到工程中。
(3)设置文本编辑器支持中文。
(4)设置编译链接控制选项。
(5)编译链接工程。
(6)调试工程。
1.4实验预习要求
仔细阅读文档《ADS集成开发环境及EasyJTAG-H仿真器应用》或《深入浅出ARM7——LPC213x/214x(上册)》书第二章的内容,了解ADS工具的组成(重要的软件功能模块——ARM汇编器、ARM的C/C++编译器、Thumb的C/C++编译器、ARM链接器、AXD调试器、ARMulator指令模拟器等)、ADS的各模块选项配置、工程编辑的内容。
1.5实验步骤
创建工程
启动ADS1.2IDE集成开发环境,选择File-〉New,使用ARMExecutableImage工程模板建立一个工程,工程名为Project1,如图1.1所示。
图1.1新建Project操作界面
图1.2新建Project操作界面
(2)
添加源文件,编辑源代码
选择File-〉New,建立一个新的汇编文件TEST1.S,设置直接添加到项目中,如图1.3所示。
在该文件中输入汇编指令代码,并保存,如图1.5所示。
图1.3新建File操作界面
图1.4编辑源文件选择操作界面
图1.5编辑源代码界面
程序TEST1.S源代码(功能:
计算两数的加法,被加数和加数分别放在R0、R1中,结果保存到R0中。
)
AREAEXAMPLE1,CODE,READONLY;声明代码段Example1
ENTRY;标识程序入口
CODE32;声明32位ARM指令
STARTMOVR0,#15;设置参数
MOVR1,#8
ADDSR0,R0,R1;R0=R0+R1
BSTART
END
在输入源代码的过程中,标号(此处如START)必须顶格输入,否则编译器不认,编译通不过。
编辑选项配置
由于ADS安装后默认字体是CourierNew,对于中文支持不完善,因此建议修改字体。
选择Edit-〉Perferences,弹出如图1.7所示对话框。
在Font选项设置字体为Fixedsys,Script为CHINESE,由于Tab在不同文本编辑器解释不同,建议在TabInsertsSpaces前打勾,使Tab键插入的是多个空格。
图1.6编辑选项配置界面
图1.7编辑器字体和Tab选项配置界面
图1.8编辑器字体和Tab选项配置界面
(2)
链接选项配置
选择Edit-〉DebugRelSettings,在DebugRelSetting对话框的左边选择ARMLinker项,然后在Output页设置连接地址,如图1.10所示;在Options页设置调试入口地址,如图1.11所示。
图1.9DebugRelSetttings选项配置界面
图1.10ARMLinker链接地址配置界面
图1.11Imageentrypoint地址配置界面
编译链接工程
选择Project-〉Make,将编译链接整个工程。
若编译成功,如图1.12所示,Errors&Warnings对话框会报告编译错误为0,此时即可对工程进行仿真。
图1.12MakeProject界面
图1.13MakeProject报告界面
调试工程
选择Project-〉Debug,或者单击快捷键F5,IDE环境就会启动AXD调试软件,如图1.15所示。
图1.14DebugProject界面
断点调试方法:
图1.15AXD调试界面
图1.16AXD调试中设置断点选择界面
图1.17AXD调试中断点设置成功界面
图1.18AXD调试运行代码界面
图1.19AXD调试运行到断点处界面
以图1.16为例,首先设置断点,只需双击第6行(ADDSR0,R0,R1)的灰色区域即可,若出现红色实心圆点,则表示断点设置成功,然后选择Execute-〉Go全速运行,(从MOVR0,#15开始运行)可以发现程序运行停止在第6行(ADDSR0,R0,R1)。
还有一种比较简单的调试方法就是用RuntoCursor命令,单击鼠标第8行灰色区域,若AXD将第8行点亮,则表示设置成功,然后选择ExecuteRuntoCursor运行到光标,可以发现程序停止在第8行。
通过断点调试可以观察ARM寄存器的数值变化,如图1.20首先添加寄存器观察窗口,注意查看R0、R1、运行以后R0、R1的值,以十六进制和十进制两种方式观察。
图1.20添加寄存器观察界面
图1.21添加寄存器观察界面
图1.22添加寄存器观察界面
图1.23寄存器值界面(代码没有运行前)
图1.24寄存器值界面(代码运行到第6行)
图1.25寄存器值界面(代码运行到第7行)
注意观察此时R0=R0+R1=15+8=23=0x17
图1.26寄存器值界面(以十六进制显示)
图1.27寄存器值界面(以十进制显示)
1.6思考
(1)工程模板有哪些作用?
(提示:
编译控制设置)
(2)如何强行重新编译工程的所有文件?
(提示:
选择Project-〉RemoveObjectCode删除工程中的*.obj文件。
)
实验二汇编指令实验1
2.1实验目的
●了解ADS1.2集成开发环境及ARMulator软件仿真。
●掌握ARM7TDMI汇编指令的用法,并能编写简单的汇编程序。
●掌握指令的条件执行以及使用LDR/STR指令完成存储器的访问。
2.2实验设备
●硬件:
PC机一台
●软件:
WindowsXP/2000系统,ADS1.2集成开发环境
2.3实验内容
(1)在存储器地址为0x40003100上开辟一个计数器变量(COUNT),对其进行计数(每次加1),记到10后重新开始计数。
C语言描述的伪算法为
for(intcount=0;count<=10;count++)
需要将存储器的值放到CPU寄存器中参与计算。
具体算法为:
使用LDR指令读取0x40003100上的数据,将数据加1,若结果小于10,则使用STR指令把结果写回原地址;若结果大于或等于10,则把0写回原地址。
ARM处理器是加载、存储体系结构的典型的RISC处理器,对存储器的访问只能使用加载和存储指令实现。
LDR/STR指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的控制操作等。
(2)使用ADS软件仿真,单步、全速运行程序,设置断点,打开寄存器窗口(ProcessorRegister)监视R0和R1的值,打开存储器观察窗口(Memory)监视0x40003100上的值。
2.4实验预习要求
(1)仔细阅读课本第3章的内容
(2)仔细阅读文档《ADS集成开发环境及EasyJTAG-H仿真器应用》或其他相关资料,了解ADS工程编辑和AXD调试的内容。
(本实验使用软件仿真)
2.5实验步骤
创建工程
启动ADS1.2,使用ARMExecutableImage工程模板建立一个工程Project2。
添加源文件,编辑源代码
建立汇编文件TEST2.S,输入源代码,参考源代码附后,然后添加到工程中。
链接选项配置
设置工程链接地址ROBase为0x40000000,RWBase为0x40003000。
设置调试入口地址Imageentrypoint为0x40000000。
编译链接工程
选择Project--〉Debug,启动AXD进行软件仿真调试。
调试工程
打开寄存器窗口(ProcessorRegister),选择Current项监视R0和R1的值。
打开存储器观察窗口(Memory)设置观察地址为0x40003100,显示方式Size为32Bit,监视0x40003100地址上的值。
说明:
在Memory窗口中右击空白处,在快捷菜单的Size项中可以选择显示格式为8Bit、16Bit或32Bit,如图2.2所示。
图2.1查看Memory选择界面
图2.2Memory数据显示方式选择界面
可以单步运行程序(F10),如图2.3所示。
可以设置/取消断点,或者全速运行程序,停止程序运行,调试时观察寄存器和0x40003100地址上的值。
图2.3单步调试运行界面
调试过程如图2.4所示。
图2.4单步调试运行界面
2.6实验参考程序
汇编指令实验1的参考程序见程序清单2.2。
程序清单2.2汇编指令实验1参考程序
COUNTEQU0x40003100;定义一个变量,地址为0x40003100
AREAExample2,CODE,READONLY;声明代码段Example2
ENTRY;标识程序入口
CODE32;声明32位ARM指令
STARTLDRR1,=COUNT;加载COUNT变量的地址
MOVR0,#0;R0=0;
STRR0,[R1];将R0的值(0)存储到R1址址指向的存储单元,R0值不变,即设置COUNT为0
LOOPLDRR1,=COUNT
LDRR0,[R1];将R1指向的地址单元(COUNT)值装入R0
ADDR0,R0,#1;R0加1保存到R0
CMPR0,#10;R0和10比较,影响条件标志
MOVHSR0,#0;若R0>=10,则此指令执行,R0=0,进行下一次循环
STRR0,[R1];将R0的值保存到COUNT变量中
BLOOP;循环
END
2.7思考
(1)若使用LDRB/STRB代替程序清单中的所有加载存储指令(LDRSTR),程序还能正确执行吗?
(2)LDR伪指令与LDR加载指令的功能和应用有哪些区别,举例说明?
(提示:
LDR伪指令的形式为“LDRRn,=expr”。
)
(3)LDR、STR指令的前索引偏移指令应如何编写?
指令是怎样操作的?
(4)在AXD调试时如何复位程序?
(提示:
选择File-〉ReloadCurrentImage重新加载映像文件。
)
实验三汇编指令实验2
3.1实验目的
●掌握ARM数据处理指令的使用方法
●了解ARM指令灵活的第2操作数
●掌握ARM乘法指令的使用方法
●了解子程序编写及调用
3.2实验设备
●硬件:
PC机
●软件:
Windows98、XP2000系统,ADS1.2集成开发环境
3.3实验内容
(1)使用MOV和MVN指令访问ARM通用寄存器。
(2)使用ADD、SUB、AND、ORR、CMP和TST等指令完成数据加减运算及逻辑运算。
(3)使用MOV和ADD指令实现:
R8=R3=X+Y。
(4)使用MOV、MVN和SUB指令实现:
R5=0x5FFFFFF8–R8
8
(5)使用CMP指令判断(5
Y/2)>(2
X),若大于,则R5=R5&0xFFFF0000,否则R5=R5|0x000000FF
(6)使用TST指令测试R5的BIT23是否为1,若是则将BIT6位清0(使用BIC指令)
(7)使用STMFD/LDMFD、MUL指令编写一个整数乘方的子程序,然后使用BL指令调用子程序计算
的值。
3.4实验预习要求
(1)仔细阅读课本第3章的内容
(2)仔细阅读文档《ADS集成开发环境及EasyJTAG-H仿真器应用》或其他相关资料,了解ADS工程编辑和AXD调试的内容。
(本实验使用软件仿真)
3.5实验步骤
创建工程,添加源文件,编辑源代码
启动ADS1.2,使用ARMExecutableImage工程模板建立一个工程Project3。
建立汇编源文件TEST3.S,编写实验程序,然后添加到工程中。
链接选项配置
设置工程链接地址ROBase为0x40000000,RWBase0x40003000,设置调试入口地址Imageentrypoint为0x40000000。
编译链接工程
选择Project-〉Debug,启动AXD进行软件仿真调试。
打开寄存器窗口(ProcessorRegisters),选择Current项监视各寄存器的值。
调试工程
单步运行程序,观察寄存器值的变化。
●R8=R3=X+Y,单步运行调试寄存器窗口如图3.1所示。
图3.1单步调试运行界面
●R5=0x5FFFFFF8–R8
8,单步运行调试寄存器窗口如图3.2所示。
图3.2单步调试运行界面
3.6实验参考程序
汇编指令实验2的参考程序见程序清单2.3。
程序清单2.3汇编指令实验2参考程序
XEQU11;定义X的值为11
YEQU8;定义Y的值为8
BIT23EQU(1<<23);定义BIT23的值为0x00800000
AREAExample3,CODE,READONLY;声明代码段Example3
ENTRY;标识程序入口
CODE32;声明32位ARM指令
START;使用MOV和ADD指令实现:
R8=R3=X+Y
MOVR0,#X;X的值传入R0,X的值必须是8位图数据
MOVR1,#Y;Y的值传入R0,Y的值必须是8位图数据
ADDR3,R0,R1;R3=R0+R1=X+Y
MOVR8,R3;将R3的值传入R8
;使用MOV、MVN和SUB指令实现:
R5=0x5FFFFFF8–R8
8
MVNR0,#0xA0000007;0xA0000007的反码为0x5FFFFFF8
SUBR5,R0,R8,LSL#3;R8左移3位,结果即是R8
8
;使用CMP指令判断(5
Y/2)>(2
X)吗?
若大于,则R5=R5&0xFFFF0000,否则R5=R5|0x000000FF
MOVR0,#Y
ADDR0,R0,R0,LSL#2;计算R0=Y+4
Y=5
Y
MOVR0,R0,LSR#1;计算R0=5
Y/2
MOVR1,#X
MOVR1,R1,LSL#1;计算R1=2
X
CMPR0,R1;比较R0和R1,即(5
Y/2)>(2
X)进行比较
LDRHIR2,=0xFFFF0000;若(5
Y/2)>(2
X),则R2=0xFFFF0000
ANDHIR5,R5,R2;若(5
Y/2)>(2
X),则R5=R5&R2
ORRLSR5,R5,#0x000000ff;若(5
Y/2)<=(2
X),则R5=R5|0x000000ff
;使用TST指令测试R5的BIT23是否为1,若是则将BIT6位清0(使用BIC指令)
TSTR5,#BIT23
BICNER5,R5,#0x00000040
BSTART
END
汇编指令实验3的参考程序见程序清单2.4。
功能:
计算
=X
X
X
X,其中相乘的X的个数为n。
先将X的值装入R0和R1,使用寄存器R2进行计数,循环n-1次R0=R0
R1,运算结果保存在R0中。
(不考虑结果溢出问题)
注意:
若n为0,则运算结果直接赋1;若n为1,则运算结果直接赋X。
实验过程
建立工程,编辑源文件
启动ADS1.2,使用ARMExecutableImage工程模板建立一个工程Project4
建立汇编源文件TEST4.S,编写实验程序,然后添加到工程中。
编译链接工程
配置工程链接地址ROBase为0x40000000,RWBase为0x40003000。
设置调试入口地址Imageentrypoint为0x40000000
调试程序
选择Project-〉Debug,启动AXD进行软件仿真调试。
打开寄存器窗口(ProcessorRegisters),选择Current项监视寄存器R0、R1、R13(SP)和R14(LR)的值。
打开存储器观察窗口(Memory)设置观察地址为0x40003EA0,显示方式Size为32Bit,监视从0x40003F00起始的满递减堆栈区。
单步运行程序,跟踪程序执行的流程,观察寄存器值的变化和堆栈区的数据变化,判断执行结果是否正确。
调试程序时,更改参数X和n来测试程序,观察是否得到正确的结果。
例如,先复位程序(选择File-〉ReloadCurrentImage),接着单步执行到“BLPOW”指令,在寄存器窗口中将R0和R1的值进行修改,然后继续运行程序。
说明:
双击寄存器窗口的寄存器,即可修改寄存器的值。
输入的数据可以是十进制数,例如136和198),也可以是十进制数(例如0x123和0xF0),输入数据后回车确定。
程序清单2.4汇编指令实验3参考程序
文件名:
TEST4.S
所在工程名:
Project4
;文件名:
TEST4.S
;功能:
计算X的n次方的值
;说明:
X和n均为无符号整数
XEQU9;定义X的值为9
nEQU8;定义Y的值为8
AREAExample4,CODE,READONLY;声明代码段Example4
ENTRY;标识程序入口
CODE32;声明32位ARM指令
STARTLDRSP,=0x40003F00;设置堆栈(满递减堆栈,使用STMFD/LMDFD指令)
LDRR0,=X
LDRR1,=n
BLPOW;调用子程序POW,返回值为R0
HALTBHALT
;子程序:
POW
;功能:
整数乘方运算
;入口参数:
R0底数
R1指数
;出口参数R0运算结果
;占用资源:
R0、R1
;说明:
本子程序不考虑溢出问题
POWSTMFDSP!
{R1-R12,LR};寄存器入栈保护
MOVSR2,R1;将指数值复制到R2,并影响条件标志
MOVEQR0,#1;若指数为0,则设置R0=1
BEQPOW_END;若指数为0,则返回
CMPR2,#1
BEQPOW_END;若指数为1,则返回(此时R0没有被更改)
MOVR1,R0;设置DO_MUL子程序的入口参数R0和R1
SUBR2,R2,#1;计数器R2=指数值减1
POW_L1BLDO_MUL;调用DO_MUL子程序,R0=R1
R0
SUBSR2,R2,#1;每循环一次,计数器R2减1
BNEPOW_L1;若计数器R2不为0,跳转到POW_L1
POW_ENDLDMFDSP!
{R1-R12,PC};寄存器出栈,返回
;子程序:
DO_MUL
;功能:
32位乘法运算
;入口参数:
R0乘数
R1被乘数
;出口参数:
R0计算结果
;占用资源:
R0、R1
;说明:
本子程序不会破坏R1
DO_MULMULR0,R1,R0;R0=R1
R0
MOVPC,LR;返回
END
3.7思考
(1)指令“MOVR0,#0x12345678”是否正确?
为什么?
(2)将参考程序中应用CMP指令的代码功能改为:
若(5
Y/2)>(2
X),则R5=R5|0x000000FF,否则R5=R5&0xFFFF0000,程序应如何修改?
(3)更改参考程序的X值为200,Y值为163,单步运行程序,每执行一步程序的结果是多少?
(4)如何实现64位加法运算(R6、R5)=(R6、R5)+(R3、R2)?
(提示:
使用ADC指令。
)
(5)若需要考虑溢出问题(使用32位运算结果,判断运算是否溢出),如何修改实验参考程序?
(提示:
使用UMULL指令)
(6)实验参考程序中的DO_MUL子程序,是否可以使用B、ADD和SUB指令返回?
(提示:
修改程序进行测试)
开发板的连接和JTAG驱动程序的安装和配置
硬件连接
将开发板(本实验采用周立功EasyARM2131电路板,主控芯片为LPC2131)通过JTAG硬件模