本科实验指导书修改版(嵌入式实验)

更新时间:2024-04-24 12:50:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1、ADS 1.2集成开发环境练习

1.1 实验目的

了解ADS 1.2集成开发环境的使用方法。

1.2 实验设备

硬件:PC机 一台

软件:Windows98/XP/2000系统,ADS 1.2集成开发环境

1.3 实验内容

1. 建立一个新的工程;

2. 建立一个C源文件,并添加到工程中; 3. 设置编译连接控制选项; 4. 编译连接工程。

1.4 实验预习要求

仔细阅读本书第2.2节ADS工程编辑的内容。

1.5 实验步骤

1. 启动ADS1.2 IDE集成开发环境,选择【File】-> 【New?】,使用ARM Executable Image 工程模板建立一个工程,工程名称为ADS,见图1。

图1 建立ARM指令代码的工程

2. 选择【File】->【New?】建立一个新的文件TEST1.S,设置直接添加到项目中,见 图1.2。输入如程序清单1所示的代码,并保存,见图1.3。

图2 新建文件TEST1.S 程序清单1 TEST1.S文件代码

AREA Example1,CODE,READONLY ; 声明代码段Example1 ENTRY ; 标识程序入口 CODE32 ; 声明32位ARM指令

START MOV R0,#15 ; 设置参数

MOV R1,#8

ADDS R0,R0,R1 ; R0 = R0 + R1

B START END

图3 添加了TEST1.S的工程管理窗口 1. 选择【Edit】->【DebugRel Settings?】,在DebugRel Settings对话框的左边选择ARM Linker项,然后在Output页设置连接地址(见图1.4),在Options页设置调试入口地址(见图 1.5)。

图4 工程连接地址设置

图5 工程调试入口地址设置 4. 选择【Project】->【Make】,将编译连接整个工程。 1.6 思考

工程模板有何作用?(提示:编译控制设置)

如何强行重新编译工程的所有文件?(提示:选择【Project】->【Remove Object Code?】 删除工程中的*.obj文件)

2 汇编指令实验1 2.1 实验目的

1.了解ADS 1.2集成开发环境及ARMulator软件仿真;

2.掌握ARM7TDMI汇编指令的用法,并能编写简单的汇编程序; 3.. 掌握指令的条件执行和使用LDR/STR指令完成存储器的访问。

2.2 实验设备

硬件:PC机 一台

软件:Windows98/XP/2000系统,ADS 1.2集成开发环境

2.3 实验内容

使用LDR指令读取0x40003100上的数据,将数据加1,若结果小于10则使用STR指 令把结果写回原地址,若结果大于等于10,则把0写回原地址。

使用ADS 1.2软件仿真,单步、全速运行程序,设置断点,打开寄存器窗口(Processor Registers)监视R0、R1的值,打开存储器观察窗口(Memory) 监视0x40003100上的值。

2.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第4章ARM指令系统的内容;

仔细阅读本书第2.2、2.3节ADS工程编辑和AXD调试的内容。(本实验使用软件仿真)

2.5 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image工程模板建立一个工程Instruction1。 2. 建立汇编源文件TEST2.S,编写实验程序,然后添加到工程中。

3. 设置工程连接地址RO Base为0x40000000,RW Base为0x40003000。设置调试入 口地址Image entry point为0x40000000。

4. 编译连接工程,选择【Project】->【Debug】,启动AXD进行软件仿真调试。

5. 打开寄存器窗口(Processor Registers),选择Current项监视R0、R1的值。打开存储 器观察窗口(Memory) 设置观察地址为0x40003100,显示方式Size为32Bit,监视 0x40003100地址上的值。

说明:在Memory窗口中点击鼠标右键,Size项中选择显示格式为8Bit、16Bit、32Bit。 如图1.6所示。

6. 可以单步运行程序,可以设置/取消断点,或者全速运行程序,停止程序运行,调试 时观察寄存器和0x40003100地址上的值。运行结果见图1.7。

图6 Memory窗口显示格式设置

图7 汇编实验1程序运行结果 2.6 实验参考程序

汇编指令实验1的参考程序见程序清单2。 程序清单2 汇编指令实验1参考程序

COUNT EQU 0x40003100 ; 定义一个变量,地址为0x40003100

AREA Example2,CODE,READONLY ; 声明代码段Example2 ENTRY ; 标识程序入口

CODE32 ; 声明32位ARM指令

START LDR R1,=COUNT ; R1 <= COUNT

MOV R0,#0 ; R0 <= 0

STR R0,[R1] ; [R1] <= R0,即设置COUNT为0

LOOP LDR R1,=COUNT

LDR R0,[R1] ; R0 <= [R1] ADD R0,R0,#1 ; R0 <= R0 + 1

CMP R0,#10 ; R0与10比较,影响条件码标志

MOVHS R0,#0 ; 若R0大于等于10,则此指令执行,R0 <= 0 STR R0,[R1] ; [R1] <= R0,即保存COUNT B LOOP END

2.7 思考

若使用LDRB/STRB代替程序清单2中的所有加载/存储指令(LDR/STR),程序会得到 正确的执行吗?

LDR伪指令与LDR加载指令的功能和应用有何区别,举例说明?(提示:LDR伪指令 的形式为“LDR Rn,=expr”)

LDR/STR指令的前索引偏移指令如何编写?指令是怎样操作的?

在AXD调试时如何复位程序?(提示:选择【File】->【Reload Current Image】重新加 载映象文件)

3 汇编指令实验2 3.1 实验目的

1. 掌握ARM数据处理指令的使用方法; 2. 了解ARM指令灵活的第2个操作数。

3.2 实验设备

硬件:PC机 一台

软件:Windows98/XP/2000系统,ADS 1.2集成开发环境

3.3 实验内容

1. 使用MOV和MVN指令访问ARM通用寄存器;

2. 使用ADD、SUB、AND、ORR、CMP、TST等指令完成数据加减运算及逻辑运算。

3.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第4章ARM指令系统的内容;

仔细阅读本书第2.2、2.3节ADS工程编辑和AXD调试的内容。(本实验使用软件仿真)

3.5 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image工程模板建立一个工程Instruction2。 2. 建立汇编源文件TEST3.S,编写实验程序,然后添加到工程中。

3. 设置工程连接地址RO Base为0x40000000,RW Base为0x40003000。设置调试入 口地址Image entry point为0x40000000。

4. 编译连接工程,选择【Project】->【Debug】,启动AXD进行软件仿真调试。 5. 打开寄存器窗口(Processor Registers),选择Current项监视各寄存器的值。

说明:使用鼠标左键选择某一个寄存器,然后点击鼠标右键,Format项中选择显示 格式Hex、Decimal等等。如图1.8所示。

图8 设置寄存器显示格式

6. 单步运行程序,观察寄存器值的变化。

说明:有变化的寄存器会以红色显示。如图1.9所示。

图9 寄存器值更新的显示 3.6 实验参考程序

汇编指令实验2的参考程序见程序清单3。 程序清单3 汇编指令实验2参考程序 X EQU 11 ; 定义X的值为11 Y EQU 8 ; 定义Y的值为8

BIT23 EQU (1<<23) ; 定义BIT23的值为0x00800000

AREA Example3,CODE,READONLY ; 声明代码段Example3 ENTRY ; 标识程序入口

CODE32 ; 声明32位ARM指令

START ; 使用MOV、ADD指令实现:R8 = R3 = X + Y

MOV R0,#X ; R0 <= X,X的值必须是8位图数据 MOV R1,#Y ; R1 <= Y,Y的值必须是8位图数据 ADD R3,R0,R1 ; 即是R3 = X + Y MOV R8,R3 ; R8 <= R3

; 使用MOV、MVN、SUB指令实现:R5 = 0x5FFFFFF8 - R8 * 8 MVN R0,#0xA0000007 ; 0xA0000007的反码为0x5FFFFFF8

SUB R5,R0,R8,LSL #3 ; R8左移3位,结果即是 R8 * 8

; 使用CMP指令判断(5*Y/2)>(2*X)吗?若大于则R5 = R5&0xFFFF0000,否则R5 = R5|0x000000FF MOV R0,#Y

ADD R0,R0,R0,LSL #2 ; 计算R0 = Y + 4*Y = 5*Y MOV R0,R0,LSR #1 ; 计算R0 = 5*Y/2 MOV R1,#X

MOV R1,R1,LSL #1 ; 计算R1 = 2*X

CMP R0,R1 ; 比较R0和R1,即(5*Y/2)和(2*X)进行比较

LDRHI R2,=0xFFFF0000 ; 若(5*Y/2)>(2*X),则R2 <= 0xFFFF0000 ANDHI R5,R5,R2 ; 若(5*Y/2)>(2*X),则R5 = R5&R2

ORRLS R5,R5,#0x000000FF ; 若(5*Y/2)≤(2*X),则R5 = R5|0x000000FF

; 使用TST指令测试R5的bit23是否为1,若是则将bit6位清零(使用BIC指令)

TST R5,#BIT23

BICNE R5,R5,#0x00000040 B START END

3.7 思考

指令MOV R0,#0x12345678是否正确?为什么?

将参考程序中应用CMP指令的代码,功能改为若(5*Y/2)>(2*X)则R5 = R5|0x000000FF, 否则R5 = R5&0xFFFF0000,程序应如何修改?

更改参考程序的X的值为200,Y的值为163,单步运行程序,每执行一步程序的结果 是多少?

如何实现64位加法运算(R6、R5) = (R6、R5) + (R3、R2)?(提示:使用ADC指令)

4 汇编指令实验3 4.1 实验目的

1. 掌握ARM乘法指令的使用方法; 2. 了解子程序编写及调用。 4.2 实验设备

硬件:PC机 一台

软件:Windows98/XP/2000系统,ADS 1.2集成开发环境

4.3 实验内容

使用STMFD/LDMFD、MUL指令编写一个整数乘方的子程序,然后使用BL指令调用 子程序计算

的值。

4.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第4章ARM指令系统的内容;

仔细阅读本书第2.2、2.3节ADS工程编辑和AXD调试的内容。(本实验使用软件仿真)

4.5 实验原理

= X*X *X ??*X,其中相乘的X的个数为n个。先将X的值装入R0和R1,使用 寄存器R2进行计数,循环n-1次R0 = R0*R1,运算结果就保存在R0中。(不考虑结果溢 出问题)

注意,若n为0,则运算结果直接赋1;若n为1,则运算结果直接赋X。

4.6 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image工程模板建立一个工程Instruction3。 2. 建立汇编源文件TEST4.S,编写实验程序,然后添加到工程中。

3. 设置工程连接地址RO Base为0x40000000,RW Base为0x40003000。设置调试入 口地址Image entry point为0x40000000。

4. 编译连接工程,选择【Project】->【Debug】,启动AXD进行软件仿真调试。

5. 打开寄存器窗口(Processor Registers),选择Current项监视寄存器R0、R1、R13(SP) 和R14(LR)的值。

6. 打开存储器观察窗口(Memory) 设置观察地址为0x40003EA0,显示方式Size为 32Bit,监视从0x40003F00起始的满递减堆栈区。

7. 单步运行程序,跟踪程序执行的流程,观察寄存器值的变化和堆栈区的数据变化, 判断执行结果是否正确。

8. 调试程序时,更改参数X和n来测试程序,观察是否得到正确的结果。例如:先复 位程序(选择【File】->【Reload Current Image】),接着单步执行到“BL POW” 指令,在寄存器窗口中将R0、R1的值进行修改,然后继续运行程序。

说明:用鼠标双击寄存器窗口的寄存器,即可修改寄存器的值。输入数据可以是十进制 数(如136、198),也可以是十六进数(如0x123,0xF0),输入数据后回车确定。

4.7 实验参考程序

汇编指令实验3的参考程序见程序清单4。

程序清单4 汇编指令实验3参考程序 ; 文件名:TEST4.S

; 功能:计算X的n次方的值 ; 说明:X和n均为无符号整数 X EQU 9 ; 定义X的值为9 n EQU 8 ; 定义n的值为8

AREA Example4,CODE,READONLY ; 声明代码段Example4 ENTRY ; 标识程序入口

CODE32 ; 声明32位ARM指令

START LDR SP,=0x40003F00 ; 设置堆栈(满递减堆栈,使用STMFD/LMDFD指令)

LDR R0,=X LDR R1,=n

BL POW ; 调用子程序POW,返回值为R0 HALT B HALT

; 名称:POW

; 功能:整数乘方运算。 ; 入口参数:R0 底数 ; R1 指数

; 出口参数:R0 运算结果 ; 占用资源:R0、R1

; 说明:本子程序不考虑溢出问题 POW

STMFD SP!,{R1-R12,LR} ; 寄存器入栈保护

MOVS R2,R1 ; 将指数值复制到R2,并影响条件码标志 MOVEQ R0,#1 ; 若指数为0,则设置R0=1 BEQ POW_END ; 若指数为0,则返回 CMP R2,#1

BEQ POW_END ; 若指数为1,则返回。(此时R0没有被更改) MOV R1,R0 ; 设置DO_MUL子程序的入口参数R0和R1 SUB R2,R2,#1 ; 计数器R2 = 指数值减1

POW_L1 BL DO_MUL ; 调用DO_MUL子程序,R0 = R1 * R0

SUBS R2,R2,#1 ; 每循环一次,计数器R2减1

BNE POW_L1 ; 若计数器R2不为0,跳转到POW_L1 POW_END LDMFD SP!,{R1-R12,PC} ; 寄存器出栈,返回

; 名称:DO_MUL

; 功能:32位乘法运算。 ; 入口参数:R0 乘数 ; R1 被乘数

; 出口参数:R0 计算结果 ; 占用资源:R0、R1

; 说明:本子程序不会破坏R1

DO_MUL MUL R0,R1,R0 ; R0 = R1 * R0

MOV PC,LR ; 返回 END

4.8 思考

若需要考虑溢出问题(使用32位运算结果,判断运算是否溢出),如何修改实验参考程 序?(提示:使用UMULL指令)

在实验参考程序中的DO_MUL子程序,是否可以使用B、ADD、SUB指令返回?(提 示:修改程序进行测试)

5 汇编指令实验4 5.1 实验目的

学习ARM微控制器的16位Thumb汇编指令的使用方法。

5.2 实验设备

硬件:PC机 一台

软件:Windows98/XP/2000系统,ADS 1.2集成开发环境

5.3 实验内容

使用Thumb指令ADD、MOV、CMP、B实现1+2+3?+N的运算(N为0时,结果为0; N为1时结果1)。

5.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第4章ARM指令系统的内容;

仔细阅读本书第2.2、2.3节ADS工程编辑和AXD调试的内容。(本实验使用软件仿真)

5.5 实验原理

ARM微控制器复位后处于ARM状态,此时只能执行ARM指令,所以需要使用BX指 令切换到Thumb状态,才能开始执行Thumb指令。

程序使用R0保存结果,所以一开始就要初始化为0;循环执行R0=R0+R1,R1为循环

计数器,从1开始计数,每一次循环R1加1;当循环计数器R1的值到达N时,运算结束。

5.6 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image工程模板建立一个工程Instruction4。 2. 建立汇编源文件TEST5.S,编写实验程序,然后添加到工程中。

3. 设置工程连接地址RO Base为0x40000000,RW Base为0x40003000。设置调试入 口地址Image entry point为0x40000000。

4. 编译连接工程,选择【Project】->【Debug】,启动AXD进行软件仿真调试。 5. 打开寄存器窗口(Processor Registers),选择Current项监视各寄存器的值。 6. 单步运行程序,注意执行BX R0指令前后CPSR寄存器的T位。

说明:在寄存器窗口的CPSR寄存器,大写字母的位表示该位为1,小写字母的位表示 该位为0(比如“T”表示T位为1,“t”表示T位为0)。 5.7 实验参考程序

汇编指令实验4的参考代码见程序清单5。 程序清单5 汇编指令实验4参考程序 ; 文件名:TEST5.S

; 功能:计算1+2+...+N的值

; 说明:N≥0,当N=0时结果为0;当N=1时结果为1。 N EQU 100 ; 定义N的值为100

AREA Example5,CODE,READONLY ; 声明代码段Example5 ENTRY ; 标识程序入口

CODE32 ; 声明32位ARM指令

ARM_CODE LDR SP,=0x40003F00 ; 设置堆栈指针 ADR R0,THUMB_CODE+1

BX R0 ; 跳转并切换处理器状态 LTORG ; 声明文字池

CODE16 ; 声明16位Thumb指令

THUMB_CODE

LDR R0,=N ; 设置子程序SUM_N的入口参数 BL SUM_N ; 调用子程序SUM_N B THUMB_CODE

; 名称:SUM_N

; 功能:计算1+2+...+N的值 ; 入口参数:R0 N的值 ; 出口参数:R0 运算结果 ; 占用资源:R0

; 说明:当N=0时结果为1;当N=1时结果为1。 ; 若运算溢出,结果为0。 SUM_N

PUSH {R1-R7,LR} ; 寄存器入栈保护

MOVS R2,R0 ; 将N的值复制到R2,并影响条件码标志

BEQ SUM_END ; 若N的值为0,则返回。(此时R0没有被更改) CMP R2,#1

BEQ SUM_END ; 若N的值为1,则返回。(此时R0没有被更改) MOV R1,#1 ; 初始化计数器R1=1 MOV R0,#0 ; 初始化结果寄存器R0=0

SUM_L1 ADD R0,R1 ; R0 = R0 + R1 BCS SUM_ERR ; 结果溢出,跳转到SUM_ERR CMP R1,R2 ; 将计数器的值与N比较

BHS SUM_END ; 若计数器的值≥N,则运算结束 ADD R1,#1 B SUM_L1

SUM_ERR MOV R0,#0

SUM_END POP {R1-R7,PC} ; 寄存器出栈,返回 END

5.8 思考

在Thumb指令只有哪一条指令具有条件执行功能? Thumb指令“ADD Rd,Rm”是否会更新条件码标志?

Thumb指令“MOV R8,#0xFF000000”是否正确?如果不正确应如何更改?

6 汇编指令实验5 6.1 实验目的

通过实验了解如何使用ARM汇编指令实现结构化程序编程。 6.2 实验设备

z 硬件:PC机 一台

z 软件:Windows98/XP/2000系统,ADS 1.2集成开发环境 6.3 实验内容

使用ARM汇编指令实现if条件执行; 使用ARM汇编指令实现for循环结构; 使用ARM汇编指令实现while循环结构; 使用ARM汇编指令实现do?while循环结构; 使用ARM汇编指令实现switch开关结构。 6.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第4章ARM指令系统的内容;

仔细阅读本书第2.2、2.3节ADS工程编辑和AXD调试的内容。(本实验使用软件仿真) 6.5 实验步骤

1. 思考如何使用ARM汇编指令实现结构化编程,具体的条件自己设定。比如if条件 执行,if(x>y) z=0,设x为R0,y为R1,z为R2,汇编代码如何编写。

2. 启动ADS 1.2,使用ARM Executable Image工程模板建立一个工程Instruction5。 3. 建立汇编源文件TEST6.S,编写实验程序,然后添加到工程中。

4. 设置工程连接地址RO Base为0x40000000,RW Base为0x40003000。设置调试入 口地址Image entry point为0x40000000。

5. 编译连接工程,选择【Project】->【Debug】,启动AXD进行软件仿真调试。 6. 打开寄存器窗口(Processor Registers),选择Current项监视各寄存器的值。 7. 单步运行程序,判断程序是否按设计的程序逻辑执行。 6.6 实验参考程序

汇编指令实验5的参考程序见程序清单6。 程序清单6 汇编指令实验5参考程序

AREA Example6,CODE,READONLY ; 声明代码段Example6 ENTRY ; 标识程序入口

CODE32 ; 声明32位ARM指令

START ; if(x>y) z=100; ; else z=50;

; 设x为R0,y为R1,z为R2 (x、y、z均为无符号整数) MOV R0,#76 ; 初始化x的值 MOV R1,#243 ; 初始化y的值 CMP R0,R1 ; 判断x>y?

MOVHI R2,#100 ; x>y条件正确,z=100 MOVLS R2,#50 ; 条件失败,z=50 ; for(i=0; i<10; i++) ; { x++; ; }

; 设x为R0,i为R2 (i、x均为无符号整数) MOV R0,#0 ; 初始化x的值

MOV R2,#0 ; 设置i=0

FOR_L1 CMP R2,#10 ; 判断i<10?

BHS FOR_END ; 若条件失败,退出循环 ADD R0,R0,#1 ; 循环体,x++ ADD R2,R2,#1 ; i++ B FOR_L1

FOR_END NOP

; while(x<=y) ; { x *= 2; ; }

; 设x为R0,y为R1 (x、y均为无符号整数) MOV R0,#1 ; 初始化x的值 MOV R1,#20 ; 初始化y的值 B WHILE_L2 ; 首先要判断条件

WHILE_L1 MOV R0,R0,LSL #1 ; 循环体,x *= 2 WHILE_L2 CMP R0,R1 ; 判断x≤y?

BLS WHILE_L1 ; 若条件正确,继续循环

WHILE_END NOP

; do ; { x--;

; } while(x>0);

; 设x为R0 (x为无符号整数) MOV R0,#5 ; 初始化x的值

DOWHILE_L1 ADD R0,R0,#-1 ; 循环体,x—

DOWHILE_L2 MOVS R0,R0 ; R0 <= R0,并影响条件码标志 BNE DOWHILE_L1 ; 若R0不为0(即x不为0),则继续循环 DOWHILE_END NOP ; switch(key&0x0F) ; { case 0: ; case 2: ; case 3: x = key + y; ; break; ; case 5: x = key - y; ; break; ; case 7: x = key * y; ; break; ; default: x = 168; ; break;

; }

; 设x为R0,y为R1,key为R2 (x、y、key均为无符号整数) MOV R1,#3 ; 初始化y的值 MOV R2,#2 ; 初始化key的值

SWITCH AND R2,R2,#0x0F ; switch(key&0x0F) CASE_0 CMP R2,#0 ; case 0:

CASE_2 CASE_3

CMPNE R2,#2 ; case 2: CMPNE R2,#3 ; case 3: BNE CASE_5

ADD R0,R2,R1 ; x = key + y B SWITCH_END ; break

CASE_5 CMP R2,#5 ; case 5:

BNE CASE_7

SUB R0,R2,R1 ; x = key - y B SWITCH_END ; break

CASE_7 CMP R2,#7 ; case 7:

BNE DEFAULT

MUL R0,R2,R1 ; x = key * y B SWITCH_END ; break

DEFAULT MOV R0,#168 ; default: x = 168 SWITCH_END NOP HALT B HALT

END

6.7 思考

使用ARM汇编指令结构化程序编程,如何在for、while结构中实现break、continue? 使用ARM汇编指令结构化程序编程,如何实现嵌套条件语句?嵌套条件语句描述如下: if (表达式1)

{ if (表达式2) 语句1; else 语句2; } else

{ if (表达式3) 语句3; else 语句4; }

7 ARM微控制器工作模式实验 7.1 实验目的

1. 掌握如何使用MRS/MSR指令实现ARM微控制器工作模式的切换; 2. 了解在各个工作模式下的寄存器。 7.2 实验设备

硬件:PC机 一台

软件:Windows98/XP/2000系统,ADS 1.2集成开发环境 7.3 实验内容

1. 使用MRS/MSR指令切换工作模式,并初始化各种模式下堆栈指针; 2. 观察ARM微控制器在各种模式下寄存器的区别。 7.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第4章ARM体系结构的内容;

仔细阅读本书第2.2、2.3节ADS工程编辑和AXD调试的内容。(本实验使用软件仿真) 7.5 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image工程模板建立一个工程MODE。 2. 建立汇编源文件TEST7.S,编写实验程序,然后添加到工程中。

3. 设置工程连接地址RO Base为0x40000000,RW Base为0x40003000。设置调试入 口地址Image entry point为0x40000000。

4. 编译连接工程,选择【Project】->【Debug】,启动AXD进行软件仿真调试。 5. 打开寄存器窗口(Processor Registers),选择Current项监视各寄存器的值。

6. 单步运行程序,注意观察CPSR、SPSR、R13(SP)、R14(LR)、R15(PC)寄存器。 说明:CPSR寄存器显示方式如图1.10所示。显示分为两部分,一部分是各个标志位, 另一部分是工作模式。

标志位NZCVQ为条件码标志N、Z、C、V、Q,显示为大写字母,表示该位为1;显

示为小写字母,表示该位为0。Q标志在ARM体系结构v5及以上版本的E变量中才有效。 标志位IFT为IRQ中断禁止位I、FIQ中断禁止位F、ARM微控制器状态位T,显示为 大写字母,表示该位为1;显示为小写字母,表示该位为0。T标志在ARM体系结构v4及 以上版本的T变量中才有效。

工作模式指示ARM微控制器当前的工作模式,包括User(用户模式)、FIQ(FIQ中断模

式)、IRQ(IRQ中断模式)、SVC(管理模式)、Abort(中止模式)、Undef(未定义模式)、SYS(系 统模式)。

图10 CPSR寄存器显示方式 7.6 实验参考程序

ARM微控制器工作模式实验的参考程序见程序清单7。 程序清单7 ARM微控制器工作模式实验参考程序 ;定义堆栈的大小

USR_STACK_LEGTH EQU 64 SVC_STACK_LEGTH EQU 0 FIQ_STACK_LEGTH EQU 16 IRQ_STACK_LEGTH EQU 64 ABT_STACK_LEGTH EQU 0 UND_STACK_LEGTH EQU 0

AREA Example7,CODE,READONLY ; 声明代码段Example7 ENTRY ; 标识程序入口

CODE32 ; 声明32位ARM指令 START MOV R0,#0 MOV R1,#1 MOV R2,#2 MOV R3,#3 MOV R4,#4 MOV R5,#5 MOV R6,#6 MOV R7,#7 MOV R8,#8 MOV R9,#9 MOV R10,#10 MOV R11,#11 MOV R12,#12

BL InitStack ; 初始化各模式下的堆栈指针

; 打开IRQ中断(将CPSR寄存器的I位清零) MRS R0,CPSR ; R0 <= CPSR BIC R0,R0,#0x80

MSR CPSR_cxsf,R0 ; CPSR <= R0 ; 切换到用户模式

MSR CPSR_c, #0xd0 MRS R0,CPSR ; 切换到管理模式 MSR CPSR_c, #0xdf MRS R0,CPSR HALT B HALT ; 名称:InitStack

; 功能:堆栈初始化,即初始化各模式下的堆栈指针。 ; 入口参数:无 ; 出口参数:无

; 说明:在特权模式下调用此子程序,比如复位后的管理模式 InitStack

MOV R0, LR ; R0 <= LR,因为各种模式下R0是相同的 ;设置管理模式堆栈 MSR CPSR_c, #0xd3 LDR SP, StackSvc ;设置中断模式堆栈 MSR CPSR_c, #0xd2 LDR SP, StackIrq ;设置快速中断模式堆栈 MSR CPSR_c, #0xd1 LDR SP, StackFiq ;设置中止模式堆栈 MSR CPSR_c, #0xd7 LDR SP, StackAbt ;设置未定义模式堆栈 MSR CPSR_c, #0xdb LDR SP, StackUnd ;设置系统模式堆栈 MSR CPSR_c, #0xdf LDR SP, StackUsr MOV PC, R0

StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1)*4 StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)*4 StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)*4 StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)*4 StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)*4 StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)*4 ; 分配堆栈空间

MOV PC,LR ; 返回值为R0 END

9.7 思考

在实验参考程序中,如何以指针形式传递参数?(即设计uint32 Add(uint32 *x, uint32 *y) 函数)

10 GPIO输出控制实验1 10.1 实验目的

1. 掌握LPC2200专用工程模板的使用; 2. 掌握EasyJTAG仿真器的安装和使用;

3. 能够在EasyARM2200开发板上运行第一个程序(无操作系统); 4. 熟悉LPC2000系列ARM7微控制器的GPIO控制。 10.2 实验设备

z 硬件:PC机 一台

EasyARM2200开发板 一套

z 软件:Windows98/XP/2000系统,ADS 1.2集成开发环境 10.3 实验内容

控制EasyARM2200开发板上的蜂鸣器报警。先使用片外RAM(IS61LV25616AL芯片) 进行调试,调试通过后将程序固化到片外FLASH(SST39VF160芯片),然后脱机运行。 10.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第5.7节的LPC2000管脚连接模块,第5.9 节的GPIO。

仔细阅读本书第1章的内容,了解EasyARM2200开发板的硬件结构,注意蜂鸣器的相 关控制电路。

仔细阅读本书第2章的内容,了解ADS 1.2集成开发环境、LPC2200专用工程模板、 EasyJTAG仿真器的应用。 10.5 实验原理

如何在EasyARM2200上运行第一个程序。 z 安装ADS 1.2 (PC) z 了解ADS 1.2 (PC)

z 连接EasyJTAG仿真器和EasyARM2200开发板(硬件) z 安装EasyJTAG驱动程序(PC) z 添加工程模板(PC)

z 用工程模板建立第一个工程(PC) z 仿真调试第一个工程(PC+硬件)

说明: (PC) ---------------- 属于在PC机上操作,即软件的操作 (硬件) ------------- 属于开发板硬件操作

(PC+硬件) --------- 属于在PC机上进行软件操作,硬件上要连接或跳线操作 1. 安装ADS 1.2

运行在ADS目录下Setup.exe,开始安装ADS1.2。

按照安装软件的提示安装,与其它软件安装操作方法基本一致。 2. 了解ADS 1.2

使用ADS1.2建立工程,编译连接设置,调试操作等,参考本书第2章的内容。更详细 的使用方法参考ADS1.2的在线帮助文档或相关资料。 1. 连接EasyJTAG仿真器和EasyARM2200开发板

将EasyJTAG仿真器的25针接口通过并口延长线与PC机的并口连接,将EasyJTAG仿 真器的20针接口通过20 PIN连接电缆接到EasyARM2200开发板的J2上,然后使用配套的 变压器(9V)给开发板供电。

4. EasyJTAG仿真器的安装与应用 参考本书第2.5节的内容。

5. 添加工程模板

参考本书第2.4节的内容。 6. 用工程模板建立第一个工程

使用LPC2200专用工程模板建立工程(比如ARM Executable Image for lpc22xx工程模 板),建立源文件并加入到工程,然后编写程序代码; 编译连接工程,若有错误,则修改程序,然后再次编译。 7. 仿真调试第一个工程

正确设置EasyARM2200开发板上的跳线; 启动AXD进行仿真调试。 10.6 实验步骤

1. 连接EasyJTAG仿真器和EasyARM2200开发板,然后安装EasyJTAG仿真器的驱 动程序(若已经安装过,此步省略)。

2. 为ADS1.2增加LPC2200专用工程模板(若已增加过,此步省略)。

1. 启动ADS 1.2,使用ARM Executable Image for lpc22xx工程模板建立一个工程 BeepCon_C。

4. 建立C源文件BeepCon.c,编写实验程序,然后添加到工程的user组中。 5. 选用DebugInExram生成目标,如图1.12所示,然后编译连接工程。

图12 选择生成目标

6. 将EasyARM2200开发板上的JP9 跳线短接,JP4 跳线断开,JP6 跳线设置为 Bank0-RAM、Bank1-Flash。 7. 选择【Project】->【Debug】,启动AXD进行JTAG仿真调试(需要正确设置仿真器,

参考第2.5节)。

注意:使用DebugInExram生成目标时,使用片外RAM进行仿真调试,JP6跳线要设 置为Bank0-RAM、Bank1-Flash,在AXD中设置仿真器参考如图1.13所示。

图13 片外RAM调试的仿真器设置

8. 若JTAG连接出错,或AXD主窗口没有显示Startup.S源程序,按本书第2.5节介 绍的方法进行处理。

9. 全速运行程序,程序将会在beepcon.c的主函数中停止(因为main函数起始处默认 设置有断点)。

10. 单击Context Variable图标按钮(或者选择【Processor Views】->【Va r ia b le s】)打开变 量观察窗口,通过此窗口可以观察局部变量和全局变量。选择【System Views】-> 【Debugger Internals】即可打开LPC2000系列ARM7微控制器的片内外设寄存器窗 口。

11. 可以单步运行程序,可以设置/取消断点,或者全速运行程序,停止程序运行,观察 变量的值,判断蜂鸣器控制是否正确。

12. 当仿真调试通过后关闭AXD,在ADS 1.2集成开发环境中选用RelOutChip生成目 标,然后编译连接工程。

13. 将EasyARM2200开发板上的JP9跳线短接,JP1、JP4跳线断开,JP6跳线设置为 Bank0-Flash、Bank1-RAM,JP7跳线设置为OUTSIDE。 14. 选择【Project】->【Debug】,启动AXD进行JTAG仿真调试。此时EasyJTAG仿真 器将会把程序下载到片外FLASH上(需要正确设置仿真器,参考第2.5节)。

注意:使用RelOutChip生成目标时,使用片外FLASH进行仿真调试(或固化程序),

JP6跳线要设置为Bank0-Flash、Bank1-RAM,在AXD中设置仿真器参考如图1.14所示。

图14 片外FLASH调试的仿真器设置

15. 按EasyARM2200开发板上的RST复位键,观察程序是否能脱机运行。

16. 实验结束后,在AXD中设置仿真器为片外RAM调试方式的设置,以便于后面实 验的正确操作。 10.7 实验参考程序

GPIO输出控制实验1的参考程序见程序清单1.12。 程序清单1.12 GPIO输出控制实验1参考程序

/**************************************************************************** * 文件名:BEEPCON.C

* 功能:蜂鸣器控制。对蜂鸣器B1进行控制,采用软件延时方法。 * 使用I/O口直接控制,采用灌电流方式。 * 说明:将跳线器JP9短接,JP4断开。

****************************************************************************/ #include \

#define BEEPCON 0x00000080 /* P0.7引脚控制B1,低电平蜂鸣*/

/**************************************************************************** * 名称:DelayNS() * 功能:长软件延时。

* 入口参数:dly 延时参数,值越大,延时越久 * 出口参数:无

****************************************************************************/ void DelayNS(uint32 dly) { uint32 i;

for(; dly>0; dly--) for(i=0; i<5000; i++); }

/**************************************************************************** * 名称:main()

* 功能:控制蜂鸣器蜂鸣。

****************************************************************************/

int main(void)

{ PINSEL0 = 0x00000000; // 设置管脚连接GPIO IO0DIR = BEEPCON; // 设置I/O为输出 while(1)

{ IO0SET = BEEPCON; // BEEPCON = 1 DelayNS(10);

IO0CLR = BEEPCON; // BEEPCON = 0 DelayNS(10); }

return(0); }

10.8 思考

为什么这个实验的工程不需要设置连接地址?(提示:LPC2200专用工程模板已集成了 起动代码、编译选项和连接地址设置等等)

在实验参考程序中,如何控制蜂鸣器报警的速度?

在LPC2000系列ARM7微控制器中,有哪两个管脚作GPIO输出时需要外接上拉电阻?

11 GPIO输出控制实验2 11.1 实验目的

熟悉LPC2000系列ARM7微控制器的GPIO控制,能够使用GPIO模拟SPI总线输出。 11.2 实验设备

z 硬件:PC机 一台

EasyARM2200开发板 一套

z 软件:Windows98/XP/2000系统,ADS 1.2集成开发环境 11.3 实验内容

使用GPIO口模拟SPI总线与74HC595进行连接,控制74HC595驱动8个LED流水灯 显示。

11.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第5.7节的LPC2000管脚连接模块,第5.9 节的GPIO;

仔细阅读74HC595的数据手册,了解如何控制数据移位,锁存数据输出;

仔细阅读本书第1章的内容,了解EasyARM2200开发板的硬件结构,注意键盘及 LED 显示电路。

仔细阅读本书第2章的内容,了解ADS 1.2集成开发环境、LPC2200专用工程模板、 EasyJTAG仿真器的应用。 11.5 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image for lpc22xx工程模板建立一个工程 LedDisp_C。

2. 建立C源文件LedDisp.c,编写实验程序,然后添加到工程的user组中。 3. 选用DebugInExram生成目标,然后编译连接工程。

4. 将EasyARM2200开发板上的JP8 跳线短接,JP6 跳线设置为Bank0-RAM、 Bank1-Flash。

5. 选择【Project】->【Debug】,启动AXD进行JTAG仿真调试。

6. 单步运行程序,通过LED1~LED8的显示判断74HC595数据移位输出是否正确。 全速运行程序,观察LED1~LED8的显示。 11.6 实验参考程序

GPIO输出控制实验2的参考程序见程序清单1.13。 程序清单1.13 GPIO输出控制实验2参考程序

/**************************************************************************** * 文件名:LEDDISP.C * 功能:LED显示控制。

* 通过I/O模拟同步串口与74HC595进行连接,控制74HC595驱动LED显示。 * 说明:将跳线器JP8短接。

****************************************************************************/ #include \

#define SPI_CS 0x00000100 /* P0.8 */ #define SPI_DATA 0x00000040 /* P0.6 */ #define SPI_CLK 0x00000010 /* P0.4 */

#define SPI_IOCON 0x00000150 /* 定义SPI接口的I/O设置字*/

/**************************************************************************** * 名称:DelayNS() * 功能:长软件延时

* 入口参数:dly 延时参数,值越大,延时越久 * 出口参数:无

****************************************************************************/ void DelayNS(uint32 dly) { uint32 i;

for(; dly>0; dly--) for(i=0; i<5000; i++); }

/**************************************************************************** * 名称:HC595_SendDat()

* 功能:向74HC595发送一字节数据 * 入口参数:dat 要发送的数据 * 出口参数:无

* 说明:发送数据时,高位先发送。

****************************************************************************/ void HC595_SendDat(uint8 dat) { uint8 i;

IO0CLR = SPI_CS; // SPI_CS = 0 for(i=0; i<8; i++) // 发送8位数据

{ IO0CLR = SPI_CLK; // SPI_CLK = 0 /* 设置SPI_DATA输出值*/

if( (dat&0x80)!=0 ) IO0SET = SPI_DATA; else IO0CLR = SPI_DATA; dat <<= 1;

IO0SET = SPI_CLK; // SPI_CLK = 1 }

IO0SET = SPI_CS; // SPI_CS = 1,输出显示数据 }

const uint8 DISP_TAB[16] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, 0x81,0x42,0x24,0x18,0x24,0x42,0x81,0x00 };

/**************************************************************************** * 名称:main()

* 功能:根据表DISP_TAB来控制LED显示。

****************************************************************************/ int main(void) { uint8 i;

PINSEL0 = 0x00000000; // 设置管脚连接GPIO IO0DIR = SPI_IOCON; // 设置SPI控制口为输出 while(1)

{ for(i=0; i<16; i++)

{ HC595_SendDat(~DISP_TAB[i]); // 输出LED显示数据

DelayNS(5); // 延时 } }

return(0); }

11.7 思考

要将几个I/O口作GPIO功能时,需要对哪些寄存器设置? 在实验参考程序中,如何控制实现流水灯显示的方式?

12 GPIO输入实验 12.1 实验目的

能够使用GPIO的输入模式读取开关信号。 12.2 实验设备

z 硬件:PC机 一台

EasyARM2200开发板 一套

z 软件:Windows98/XP/2000系统,ADS 1.2集成开发环境 12.3 实验内容

读取P0.14口上的电平值,然后将读到的值输出控制蜂鸣器。 12.4 实验预习要求

仔细阅读《ARM与嵌入式系统基础教程》第5.7节的LPC2000管脚连接模块,第5.9 节的GPIO。

仔细阅读本书第1章的内容,了解EasyARM2200开发板的硬件结构,注意蜂鸣器控制 电路及JP1跳线器的说明。

仔细阅读本书第2章的内容,了解ADS 1.2集成开发环境、LPC2200专用工程模板、 EasyJTAG仿真器的应用。 12.5 实验原理

P0.14口设置为输入模式时,口线内部无上拉电阻,当与按键或跳线器连接使用时需要 外接上拉电阻,防止口线悬空。GPIO输入实验原理图如图1.15所示。 图15 GPIO输入实验原理图

12.6 实验步骤

1. 启动ADS 1.2,使用ARM Executable Image for lpc22xx工程模板建立一个工程 ReadPin_C。

2. 建立C源文件ReadPin.c,编写实验程序,然后添加到工程的user组中。

3. 选用DebugInExram生成目标,然后编译连接工程。

4. 将EasyARM2200开发板上的JP9 跳线短接,JP4 跳线断开,JP6 跳线设置为 Bank0-RAM、Bank1-Flash。 5. 选择【Project】->【Debug】,启动AXD进行JTAG仿真调试。

6. 单步运行程序,先短接JP1,观察IO0PIN寄存器的值,然后断开JP1,观察IO0PIN 寄存器的值。全速运行程序,短接/断开JP1,控制蜂鸣器的蜂鸣。

说明:可以通过Watch窗口观察寄存器的值。选择【Processor Views】->【Watch】打 开Watch窗口,在Watch窗口内点击鼠标右键,选择Add Watch?项添加变量,如图1.16 所示。

图16 Watch窗口

在Add Watch窗口中的Expression项输入*((unsigned long *) 0xE0028000),然后回车, 如图1.17所示,然后选择Add To View按钮,即可在Watch窗口观察IO0PIN寄存器(IO0PIN 寄存器的地址0xE0028000)。

图17 Add Watch对话框

在Watch窗口中选择一个观察变量,按Del键即可删除此观察变量。 注意:有些寄存器不能读出显示或读操作会影响到其它寄存器的值。 12.7 实验参考程序

GPIO输入实验的参考程序见程序清单1.14。 程序清单1.14 GPIO输入实验参考程序

/**************************************************************************** * 文件名:READPIN.C

* 功能:读取I/O引脚值,并输出控制蜂鸣器。 * 使用I/O口输入方式对P0.14口进行扫描。

* 说明:将跳线器JP9短接,JP4断开,然后短接/断开JP1(使P0.14为低/高电平)。

****************************************************************************/ #include \

#define BEEPCON 0x00000080 /* P0.7引脚控制B1,低电平蜂鸣*/ #define PIN_P014 0x00004000 /* 定义P0.14屏蔽字*/

/**************************************************************************** * 名称:main()

* 功能:读取P0.14口的值,并输出控制蜂鸣器B1。

****************************************************************************/ int main(void) { uint32 i;

PINSEL0 = 0x00000000; // 设置管脚连接GPIO

IO0DIR = BEEPCON; // 设置B1控制口为输出,其它I/O为输入 while(1)

{ if( (IO0PIN&PIN_P014)!=0 ) IO0SET = BEEPCON; else IO0CLR = BEEPCON; for(i=0; i<1000; i++); }

return(0); }

12.8 思考

如果将P0.30设置为GPIO输入模式,且管脚悬空,那么读取P0.30得到的值是0还是 1?或者是不确定?

如果需要读取当前P0.7的输出值(不是管脚上的电平),如何实现?

本文来源:https://www.bwwdw.com/article/yepp.html

Top