嵌入式程序复习.docx

上传人:b****6 文档编号:13468008 上传时间:2023-06-14 格式:DOCX 页数:22 大小:234.35KB
下载 相关 举报
嵌入式程序复习.docx_第1页
第1页 / 共22页
嵌入式程序复习.docx_第2页
第2页 / 共22页
嵌入式程序复习.docx_第3页
第3页 / 共22页
嵌入式程序复习.docx_第4页
第4页 / 共22页
嵌入式程序复习.docx_第5页
第5页 / 共22页
嵌入式程序复习.docx_第6页
第6页 / 共22页
嵌入式程序复习.docx_第7页
第7页 / 共22页
嵌入式程序复习.docx_第8页
第8页 / 共22页
嵌入式程序复习.docx_第9页
第9页 / 共22页
嵌入式程序复习.docx_第10页
第10页 / 共22页
嵌入式程序复习.docx_第11页
第11页 / 共22页
嵌入式程序复习.docx_第12页
第12页 / 共22页
嵌入式程序复习.docx_第13页
第13页 / 共22页
嵌入式程序复习.docx_第14页
第14页 / 共22页
嵌入式程序复习.docx_第15页
第15页 / 共22页
嵌入式程序复习.docx_第16页
第16页 / 共22页
嵌入式程序复习.docx_第17页
第17页 / 共22页
嵌入式程序复习.docx_第18页
第18页 / 共22页
嵌入式程序复习.docx_第19页
第19页 / 共22页
嵌入式程序复习.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

嵌入式程序复习.docx

《嵌入式程序复习.docx》由会员分享,可在线阅读,更多相关《嵌入式程序复习.docx(22页珍藏版)》请在冰点文库上搜索。

嵌入式程序复习.docx

嵌入式程序复习

一、写出下列各条指令的执行含义。

1.ADDR0,R0,#1;指令实现的功能是将R0+1的结果送R0是保存.

2.ADDR0,R1,[R2];指令实现的功能是将以R2中的内容为地址的单元中的值与R1相加,结果送R0保存.

3.LDRR0,[R1+4];指令实现的功能是将R1的内容加4后送R0。

4.LDRR0,[R1+4]!

;指令实现的功能是将R1的内容加4后送R0,然后R1的内容自增4个字节。

5.BLable;程序无条件跳转到标号Lable处执行。

MOVR1,R0;指令实现的功能是将寄存器R0的值传送到寄存器R1.

7.CMPR1,R0;指令实现的功能是寄存器R1的值与寄存器R0的值相减,根据结果设置CPSR的标志位。

8.CMNR1,R0;指令实现的功能是将寄存器R1的值与寄存器R0的值相加,根据结果设置CPSR的标志位。

9.ORRR0,R0,#3;该指令设置R0的0、1位,其余位保持不变。

10.MRSR0,SPSR;传送SPSR的内容到R0。

11.CMPR1,R2;指令实现的功能是寄存器R1的值与寄存器R2的值相减,根据结果设置CPSR的标志位。

12.MRSR0,CPSR;传送CPSR的内容到R0

13.MOVR2,R0;指令实现的功能是将寄存器R0的值传送到寄存器R2。

14.ADDR1,R1,#3;指令实现的功能是将R1+3的结果送R1是保存。

15.ADDR2,R1,[R0];指令实现的功能是将以R0中的内容为地址的单元中的值与R1相加,结果送R2保存。

16.LDRR1,[R0+4];指令实现的功能是将R0的内容加4后送R1.

17.LDRR1,[R0+4]!

;指令实现的功能是将R0的内容加4后送R1,然后R0的内容自增4个字节。

18.ANDR0,R0,#3;该指令保持R0的0、1位,其余位清零。

19.B0x1200;跳转到绝对地址0x1200处执行.

20.CMNR1,R2;指令实现的功能是将寄存器R1的值与寄存器R2的值相加,根据结果设置CPSR的标志位。

1、写一条ARM指令,完成操作r1=r2*4

MOVR1,R2,LSL#2

2。

写一条ARM指令,完成操作r1=r2*3

ADDR1,R2,R2,LSL#1

 

3.初始值R1=23H,R2=0FH执行指令BICR0,R1,R2,LSL#1后,寄存器R0,R1的值分别是多少?

R0=21H,R1=23H

4.初始值R2=5,R3=9,R4=3,执行指令SUBSR2,R3,R4,LSR#2后,寄存器R2,R3的值分别是多少?

R2=9,R3=9

5。

ADDR0,R0,R0,LSL#2;执行结果R0=5*R0

ADDR5,R3,R1,LSL#2;R5←R3+R1*4

SUBR1,R1,R2,LSR#2;R1=R1-R2÷4,因为R2右移2位相当于R2除以4。

LSL#n;逻辑左移n位(1≤n≤31),低端空位补0。

LSR#n;逻辑右移n位(1≤n≤32),高端空位补0

6.LDRR2,[R3,#0x0C];前变址,传数前计算地址

;读取R3+0x0C地址上的存储单元的内容,放入R2。

STRR1,[R0,#-4]!

;[R0-4]←[R1],R0=R0-4,符号“!

”表明指令在完成数据传送后应该更新基址寄存器,否则不更新;属于回写前变址。

LDRR0,[R1],#4  ;后变址:

先进行R1—>R0操作然后R1+4—〉R1,操作完毕后,R1=R1+4.不需要"!

”号。

7。

多寄存器寻址即是一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。

多寄存器寻址指令举例如下:

LDMIAR1!

,{R2-R7,R12}

;将R1指向的单元中的数据读出到R2~R7、R12中

;(R1自动增加)

LDMIA R0!

 {R1, R2, R3, R4}

; R1←[R0] 

; R2←[R0+4] 

; R3←[R0+8] 

; R4←[R0+12] 

STMIAR0!

,{R2-R7,R12}

;将寄存器R2~R7、R12的值保存到R0指向的存储单元中,

;(R0自动增加)

STMIAR0!

,{R1—R7}

;将R1~R7的数据保存到存储器中.存储指针在保存第一

;个值之后增加,增长方向为向上增长

;R0←R1

;[R0+4]←R2

;[R0+8]←R3

;[R0+12]←R4

;[R0+16]←R5

;[R0+20]←R6

;[R0+24]←R7

;R0保持自动增值

8.LDRR2,[R3,#0x0C]

读取R3+0x0C地址上的一个字数据内容,放入R2.属前变址。

参看教材第125页。

STRR1,[R0,#-4]!

[R0-4]←[R1],R0=R0-4,符号“!

”表明指令在完成数据传送后应该更新基址寄存器,否则不更新;属回写前变址。

LDRR1,[R0,R3,LSL#1]

将R0+R3×2地址上的存储单元的内容读出,存入R1.属前变址。

9写一段ARM汇编程序:

循环累加队列myarray中的所有元素,直到碰上零值元素,结果放在r4中。

程序框架如下,补充代码完成上述功能。

AREAtotal,CODEREADONLY

ENTRY

start

MOVr4,#0

ADRr0,myarray

;在此补充代码

loop

LDRr1,[r0],#4

ADDr4,r4,r1

CMPr1,#0

BNEloop

stop

Bstop

myarray

DCD0x11

DCD0x22

……

DCD0x0

END

 

10并编写了如下的汇编程序:

问:

现执行上述程序,请列出R0,R1,R2的最终值,并告知整个程序的功能。

R0=1

R1=2

R2=1

功能:

对R0和R1分别赋值0,1,在R1为5的条件下循环给R0赋值R0和R1之和,给R1加1,

取得RESULT的地址赋值于R2,将R0的值保存在RESULT中

11读如下程序

test.s:

test。

c:

请列出上述程序执行后R0,R1的值,并说明上述程序的作用。

R0=31

R1=23

功能:

test。

c调用s_program函数,将54赋值R0,23赋值R1,两者相减后,赋值给R0,R0作为返回值赋值给num,然后输出num。

 

12有如下C语言定义的函数mypro

intmypro(inta,intb)

a=a*b;

return(a);

请补充完成调用上述函数的汇编程序,实现11与22相乘,并要求将结果保存在地址为0x40001000处:

areatest3,code,readonly

importmypro

entry

code32

start

movr0,#11

(1)

movr1,#22

(2)

BLmypro(3)

Ldrr3,=0x40001000(4)

Strr0,[r3](5)

END

13程序段如下,实现下面流程图,试补充编写ARM汇编代码.\

程序段:

MOVr2,#15

MOVr3,#9

start

;补充代码

stop

Bstop

END

程序:

Start:

CMPr2,r3

SUBLTr3,r3,r2

SUBGTr2,r2,r3

BNEstart

14明指令STMIAr8!

,{r0—r7}的操作功能.

将R0—R7八个寄存器中的32位数据,存储到R8地址指针为起始地址的内存中,地址的操作方式是先操作、后增加,并更新地址.

 

15汇编程序调用C程序的方法为:

首先在汇编程序中使用IMPORT伪指令事先声明将要调用的C语言函数;然后通过BL指令来调用C函数。

(写出注释能把程序写出来,给出程序能将注释写出来)

例如在一个C源文件中定义了如下求和函数:

intprom(intx,inty){

return(x&y);

调用prom()函数的汇编程序结构如下:

IMPORTprom;声明要调用的C函数

MOVr0,1

MOVr1,2

BLprom;调用C函数prom

 

16C程序调用汇编子程序的方法为:

首先在汇编程序中使用EXPORT伪指令声明被调用的子程序,表示该子程序将在其他文件中被调用;然后在C程序中使用extern关键字声明要调用的汇编子程序为外部函数。

(写出注释能把程序写出来,给出程序能将注释写出来)

例如在一个汇编源文件中定义了如下求和函数:

EXPORTprom;声明prom子程序将被外部函数调用

prom;求与子程序prom

ANDr0,r0,r1

MOVpc,lr

在一个C程序的main()函数中对prom汇编子程序进行了调用:

externintprom(intx,inty);//声明prom为外部函数

voidmain(){

inta=1,b=2,c;

c=prom(a,b);//调用prom子程序

}

综合编程

1、教材第六章关于GPIO的应用,列举了一个I/O管脚控制4个LED发光二极管的例子,但我们实验箱所提供的LED发光二极管位于不同的引脚,它们分别使用了S3C2410的GPC5,GPC6,GPC7,如下图,请修改原程序段以实现三个灯的交替闪烁(注:

未用引脚设置为input状态)。

(写出注释能把程序写出来,给出程序能将注释写出来)

博创经典版LED接线原理图

相关寄存器定义:

#definerGPCCON(*(volatileunsigned*)0x56000020)

#definerGPCDAT(*(volatileunsigned*)0x56000024)

#definerGPCUP(*(volatileunsigned*)0x56000028)

端口初始化:

voidport_init(void)

{

rGPCCON=0x56aa;

rGPCUP=0xff;//GPF所有端口都不加上拉电阻

所有LED交替亮灭:

voidled_on_off(void)

{

inti;

rGPCDAT=0;//所有LED全亮

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

rGPCDAT=0xE0;//所有LED全灭

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

2.例程:

4个led灯循环亮(会配置端口)

#definerGPEDAT(*(volatileunsigned*)0x56000044)//PortEdata

#definerGPEUP(*(volatileunsigned*)0x56000048)//Pull-upcontrolE

#definerGPHCON(*(volatileunsigned*)0x56000070)//PortHcontrol

#definerGPHDAT(*(volatileunsigned*)0x56000074)//PortHdata

#definerGPHUP(*(volatileunsigned*)0x56000078)//Pull—upcontrolH

/*主程序*/

externvoiddelay(inttimes);

voidxmain(void)

{

rGPECON&=~(3<〈22);

rGPECON|=(1<<22);//GPE11设置为output

rGPECON&=~(3〈〈24);

rGPECON|=(1<<24);//GPE12设置为output

rGPHCON&=~(3<<8);

rGPHCON|=(1<〈8);//GPH4设置为output

rGPHCON&=~(3〈〈12);

rGPHCON|=(1<〈12);//GPH6设置为output

while

(1)

{

rGPEDAT&=~(1<<11);//GPE11output0

rGPEDAT|=(1<<12);//GPE12output1

rGPHDAT|=(1〈〈4);//GPH4output1

rGPHDAT|=(1〈〈6);//GPH6output1

delay(200000);//delay

rGPEDAT|=(1〈<11);//GPE11output1

rGPEDAT&=~(1<<12);//GPE12output0

rGPHDAT|=(1〈〈4);//GPH4output1

rGPHDAT|=(1〈<6);//GPH6output1

delay(200000);//delay

rGPEDAT|=(1<〈11);//GPE11output1

rGPEDAT|=(1〈<12);//GPE12output1

rGPHDAT&=~(1〈〈4);//GPH4output0

rGPHDAT|=(1〈<6);//GPH6output1

delay(200000);//delay

rGPEDAT|=~(1<〈11);//GPE11output1

rGPEDAT|=(1<<12);//GPE12output1

rGPHDAT|=(1〈〈4);//GPH4output1

rGPHDAT&=~(1<<6);//GPH6output0

delay(200000);//delay

3.通过对G口的操作控制CPU板左下角的LED1和LED2实现轮流闪烁。

(写出注释能把程序写出来,给出程序能将注释写出来)

voidMain(void){

intflag,i;

Target_Init();//进行硬件初始化操作,包括对I/O口的初始化操作

for(;;){

if(flag==0){

for(i=0;i〈1000000;i++);//延时

rGPGCON=rGPGCON&0xffff00ff|0x00002800;//配置第6、第7位为输出引脚

rGPGDAT=rGPGDAT&0x8f|0x8f;//第6位输出为低电平第7位输出高电平

for(i=0;i<10000000;i++);//延时

flag=1;

}

else{

for(i=0;i<1000000;i++);//延时

rGPGCON=rGPGCON&0xffff00ff|0x00002800;//配置第6、第7位为输出引脚

rGPGDAT=rGPGDAT&0x4f|0x4f;//第6位输出为高电平第7位输出低电平

for(i=0;i〈1000000;i++);//延时

flag=0;

}

4、列举了一个通过按钮产生中断请求的实验例子,但我们实验箱所提供的按钮位于不同的引脚,如下图,按键接到INT5中断。

博创经典版中断实验电路图

请修改原程序段以实现实例中要求的功能(即当按钮按下,向CPU发出中断请求,当CPU受理中断后,进入相应的中断服务程序,通过超级终端的主窗口显示当前进入的中断号)(有关EXTINTn参数配置请参考附件“EXTINTn参数.doc”(注:

直接在原来的程序上修改,并删除同此实验要求无关的原有代码部分)。

相关寄存器定义:

#definerGPFCON(*(volatileunsigned*)0x56000050)//端口F的控制寄存器

#definerEXTINT0(*(volatileunsigned*)0x56000088)//外部中断控制寄存器0

#definerEINTMASK(*(volatileunsigned*)0x560000a4)//外部中断屏蔽寄存器

#definerEINTPEND(*(volatileunsigned*)0x560000a8)//外部中断挂起寄存器

#definerINTMSK(*(volatileunsigned*)0x4a000008)//中断屏蔽寄存器

#definerSRCPND(*(volatileunsigned*)0x4a000000)//源挂起寄存器

#definerINTPND(*(volatileunsigned*)0x4a000010)//中断挂起寄存器

中断初始化:

(下面程序写出注释能把程序写出来,给出程序能将注释写出来)

voidint_init(void)

{

rGPFCON=(rGPFCON&~(3<〈0))|(0x2<<0);//将GPF0配置为EINT5

pISR_EINT5=(UINT32T)int0_int;//注册中断处理函数

rEINTPEND=0xffffff;//清除所有外部中断挂起状态

rSRCPND=BIT_EINT5;//清除源的挂起状态

rINTPND=BIT_EINT5;//清除挂起状态

rEXTINT0=(rEXTINT0&~(7〈<0))|(0x2<<0);//EINT5下降沿触发

rINTMSK&=~(BIT_EINT0);//打开INTMSK中的中断0

}

中断处理函数:

void__irqint0_int(void)//外部中断0处理函数

uart_printf("EINT0interruptoccurred。

\n”);

ClearPending(BIT_EINT0);//清除中断源

}

#defineClearPending(bit)

{rSRCPND=bit;

rINTPND=rINTPND;}//precentwritewrongdata

}//清除中断源,注意清除的顺序,要从源头开始清除

5.阅读下列与看门狗有关的寄存器描述,解释每一行代码的功能。

看门狗定时器控制寄存器(WTCON)

寄存器

地址

读/写

描述

初始值

WTCON

0x53000000

读/写

看门狗定控制寄存器

0x8021

WTCON的标识位

WTCON

Bit

描述

初始值

PrescalerValue

[15:

8]

预装比例值,有效范围值为0~255

0x80

Reserved

[7:

6]

保留

00

WatchdogTimer

[5]

使能和禁止看门狗定时器

0=禁止看门狗定时器

1=使能看门狗定时器

0

ClockSelect

[4:

3]

这两位决定时钟分频因素

00:

1/1601:

1/32

10:

1/6411:

1/128

00

InterruptGeneration

[2]

中断的禁止和使能

0=禁止中断产生

1=使能中断产生

0

Reserved

[1]

保留

0

Reset

Enable/Disable

[0]

禁止很使能看门狗复位信号的输出

1=看门狗复位信号使能

0=看门狗复位信号禁止

1

看门狗定时器数据寄存器(WTDAT)

寄存器

地址

读/写

描述

初始值

WTDAT

0x53000004

读/写

看门狗数据寄存器

0x8000

看门狗计数寄存器(WTCNT)

寄存器

地址

读/写

描述

初始值

WTCNT

0x53000008

读/写

看门狗计数器当前值

0x8000

#definerWTCON(*(volatileunsigned*)0x53000000)//第1行

#definerWTDAT(*(volatileunsigned*)0x53000004)//第2行

#definerWTCNT(*(volatileunsigned*)0x53000008)//第3行

voidwatchdog_test(void)

{

rWTCON=((PCLK/1000000—1)<<8)|(3<〈3)|(1<<2);//第4行

rWTDAT=7812;//第5行

rWTCNT=7812;//第6行

rWTCON|=(1〈〈5);//第7行

}

第1-3行:

定义看门狗控制寄存器、数据寄存器和计数寄存器为rWTCON、rWTDAT和rWTCNT.

第4行:

设置看门狗的预装比例值为1000000,分频因素为1/128,并使能中断。

第5—6行:

对数据寄存器和计数寄存器赋值为7812。

第7行:

启动看门狗。

6。

阅读下列与定时器有关的寄存器描述,解释每一行代码的功能.

(1)定时器预分频器配置寄存器(TCFG0)的含义

(2)定时器控制寄存器(TCON)

TCON

表述

初始状态

保留

[7:

5]

保留

死区

[4]

0:

死区使无效;1:

死区使能

0

定时器0自动加载

[3]

0不自动加载,1自动加载

0

定时器0输出反转

[2]

0不反转,1反转

0

定时器0手动更新位

[1]

0:

无用,

1:

将TCNTBn/TCMPBn寄存器的值装入内部寄存器TCNTn\TCMPn中

0

定时器0开启停止位

[0]

0:

停止定时器,1:

开始定时器

0

(3):

DMA模式与分频选择寄存器(TCFG1)

(4)定时器计数缓冲寄存器(TCNTBn)

程序:

#definerTCFG0(*(volatileunsigned*)0x51000000)//第1行

#definerTCFG1(*(volatileunsigned*)0x51000004)//第2行

#definerTCON(*(volatileunsigned*)0x51000008)//第3行

#definerTCNTB4(*(volatileunsigned*)0x5100003c)//第4行

⏹voidinit_Time0()

{

//定时器输入时钟频率=PCLK/{预分频值+1}/分频值

rTCFG0=49;//预分频值=49;

  rTCFG1&=~(0xf<<0);

        rTCFG1|=(1<<0);         

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

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2