首页 理论教育 汇编语言程序设计举例:单片机原理与接口技术

汇编语言程序设计举例:单片机原理与接口技术

时间:2023-11-16 理论教育 版权反馈
【摘要】:1 数据排序程序在单片机应用程序中,有时要对数据进行排序。2 算术计算程序指令系统中有加、减、乘、除、加1、减1等指令,可通过设计程序来处理一般不太复杂的算术运算。设计中要注意程序执行对PSW的影响。例3-54:用程序实现c=a2+b2。设a、b、c存于片内RAM的3个单元R2、R3、R4中,可用子程序来实现。通过两次调用查平方表的子程序来得到a2和b2,并在主程序中完成相加。解:取n=5,程序结构为“计数控制循环结构”。

汇编语言程序设计举例:单片机原理与接口技术

1 数据排序程序

单片机应用程序中,有时要对数据进行排序。排序有从小到大,从大到小排等。

例3-52:设计一个排序程序,将单片机内RAM中若干单字节无符号的正整数,按从小到大的顺序重新排列。

解:先将不等的11个任意数据置于内RAM的50H~5AH中,设依次为56H、88H、34H、57H、18H、62H、42H、24H、01H、31H、11H。

设计程序如下(俗称冒泡法):

ORG 0000H

SOP:MOV R0,#50H;指针送R0

MOV R7,#0AH;每次冒泡比较的次数

CLR F0;交换标志清0

LOOP:MOV A,@R0;取前数

MOV R2,A;暂存前数于R2

INC R0;取后一个数

MOV 30H,@R0;后数暂存于R3

CLR C;清进位为0

CJNE A,30H,LP1;前后两数相比较

SJMP LP2

LP1:JC LP2;前数≤后数,不交换

MOV A,@R0

DEC R0;前数>后数,则交换

XCH A,@R0

INC R0

MOV @R0,A

SETB F0;置交换标志

LP2:DJNZ R7,LOOP;进行下一次比较

JB F0,SOP;一趟循环中有交换,进行下一趟冒泡

SJMP $;无交换退出

END

结果:RAM从小到大在50H~5AH中的排列依次为01H、11H、18H、24H、31H、34H、42H、56H、57H、62H、88H。

2 算术计算程序

指令系统中有加、减、乘、除、加1、减1等指令,可通过设计程序来处理一般不太复杂的算术运算。设计中要注意程序执行对PSW的影响。

例3-53:设计一个顺序程序,求解Y=(3×X+4)×5÷8-1。X的取值范围为0~15,X值存放于30H中,设(X)=4,计算结果Y存放在31H中。

解:设计程序如下:

ORG 0000H

LJMP STAR

ORG 0100H

STAR:MOV 30H,#4;X=4,(30H)=4

MOV A,30H

CLR C

RLC A,2X

ADD A,30H;(A)=3X

MOV 31H,A;(31H)=(A)=3X

MOV A,#4

ADD A,31H;(A)=3X+4

MOV B,#5

MUL AB;(A)=5(3X+4)

MOV B,#8

DIV AB;(A)=5(3X+4)/8

DEC A;(A)=[5(3X+4)/8]-1

MOV 31H,A;结果在31H中,余数在B中。

SJMP $

END

结果:(31H)=9。

例3-54:用程序实现c=a2+b2。设abc存于片内RAM的3个单元R2、R3、R4中,可用子程序来实现。通过两次调用查平方表的子程序来得到a2b2,并在主程序中完成相加。(设ab为0~9之间的数,若a=6,b=4)

解:设计程序如下:

ORG 0000H

MOV R2,#6;赋值(R2)=6

MOV R3,#4;赋值(R3)=4

MOV A,R2;取第一个被加的数据a

ACALL SQR;第一次调用,得a2

MOV R1,A;暂存a2于R1中

MOV A,R3;取第二个被加的数据a

ACALL SQR;第二次调用,得b2

ADD A,R1;完成a2+b2

MOV R4,A;存a2+b2结果到R4

SJMP $

SQR:INC A;查表位置调整

MOVC A,@A+PC;查平方表

RET;子程序返回

TAB:DB 0,1,4,9,16,25,36,49,64,81

END

结果:(R4)=34H=52。

例3-55:设计n个正整数的求和程序。设Xi均为单字节数,并按顺序存放在内RAM以50H为首址的连续的存储单元中。数据长度(个数)n存在R2中,求S=X1+X2+…Xn,并将和数S(双字节)存放在R3、R4中(设和数<65536)。

解:取n=5,程序结构为“计数控制循环结构”。

设计程序如下:

ORG 0000H

MOV 50H,#23H;寄存器50H~54H预置数据

MOV 51H,#05H

MOV 52H,#0FFH

MOV 53H,#44H

MOV 54H,#60H;以下四条指令为置循环初值

MOV R2,#5;数据个数计数器R2置数

MOV R3,#00H;结果高位存储器R3清0

MOV R4,#00H;结果低位存储器R4清0

MOV R0,#50H;寄存器(R0)=50H

LOOP:MOV A,R4

ADD A,@R0

MOV R4,A

CLR A

ADDC A,R3

MOV R3,A;以下三条分别为循环修改、循环控制、退出循环

INC R0;循环修改

DJNZ R2,LOOP;循环控制

SJMP $;退出循环

END

结果:高位(R3)=01H;低位(R4)=CBH。

例3-56:设单片机片内存储区首地址为30H,片外存储区首地址为3000H,存取数据字节个数为16个,并将片内存储区的这16个字节的内容设置为01H~10H,将片内首地址为30H开始的16个单元的内容传送到片外首地址为3000H开始的数据存储区中保存。

解:程序代码如下。

ORG 0000H

DADDR EQU 30H;片内数据区首地址

XADDR EQU 3000H;片外数据区首地址

COUNT EQU 10H;传送数据大小,共16个字节

MAIN:MOV SP,#60H;重置堆栈指针

MOV R0,#DADDR;设置片内数据区首地址

MOV R2,#COUNT;设置传送数据区大小即16个字节

/**********片内数据区初始化**********/

INIT:MOV A,#01H

LOOP1:MOV @R0,A

INC A

INC R0

DJNZ R2,LOOP1

/**********片内外数据传送**********/

DXMOV:MOV R0,#DADDR;设置片内数据区首地址

MOV DPTR,#XADDR;设置片外数据区首地址

MOV R2,#COUNT;设置传送数据区大小即16个字节

LOOP2:MOV A,@R0

MOVX @DPTR,A

INC R0

INC DPTR

DJNZ R2,LOOP2

END

运行结果:内部数据区30H~3FH单元内容为01H~10H,片外数据区3000H~300FH内容

为01H~10H。

3 累加器A或工作寄存器Rn传递参数

例3-57:把A中一个十六进制数的ASCII字符转换为一位十六进制数。

解:主程序部分如下:

START:

MOV A,#34H;设置入口参数于A中

LCALL ASCH;子程序入口地址为ASCH

子程序:

ASCH:CLR C

SUBB A,#30H

CJNE A,#10,$+3;$+3为下条指令的首址

JC NEXT;<10,转NEXT

SUBB A,#07H;≥0AH,则再减07H(共减37H)

NEXT:NOP

RET

4 用寄存器作为指针来传递参数

例3-58:在内RAM的40H、50H开始的空间中,分别存有单字节的无符号数据块,长度分别为12和8。编程求这两个数据块中的最大数,存入MAX单元。

思路:用子程序求某数据块的最大值。

入口参数:数据块的首地址存入R0,长度存入R2,出口参数在A中,即最大数。

解:程序如下:

FMAX:MOV A,@R0;取第一个数

LOOP0:INC R0

MOV B,@R0;取下一个数

CJNE A,B,$+3;比较

JNC LOOP1

MOV A,B;把大的数送A

LOOP1:DJNZ R2,LOOP0

RET;出口参数在A中

/***主程序***/

ORG 1000H

MAX EQU 30H

MOV R0,#40H;设置入口参数R0,R2

MOV R2,#12-1

ACALL FMAX(www.xing528.com)

MOV MAX,A;出口参数暂存MAX中

MOV R0,#50H;设置入口参数R0,R2

MOV R2,#8-1

ACALL FMAX

CJNE A,MAX,$+3;比较两个数中较大值

JC NEXT

MOV MAX,A

NEXT:SJMP $

5 非数值运算程序设计举例

例3-59:将8位二进制数据转换为压缩式BCD码。设该数已在A中,转换后存在内RAM的30H、31H单元中。

解:程序如下:

MOV R0,#31H;地址指针

MOV B,#100

DIV AB;把该数据除100,得到A中的商即为BCD码的百位数

MOV @R0,A;存结果的百位数

DEC R0;修改指针

MOV A,#10;把刚才除100所得余数再去除10

XCH A,B

DIV AB;所得商为BCD码的十位数,余数即为BCD码的个位数

SWAP A;为了压缩,先把低4位送到高4位

ADD A,B;A中高字节的十位数与B中低半字节的个位数合成存入A

MOV @R0,A;存放结果的十位数和个位数

SJMP $

6 算术运算程序设计举例

例3-60:多字节数求补运算。注意:在MCS-51系列单片机的指令系统中没有求补指令,通过末位取反加1得到。

解:程序如下:

CMPT:MOV A,@R0

CPL A

ADD A,#01;最低字节采用取反加1

MOV @R0,A

DEC R2

LOOP:INC R0

MOV A,@R0

CPL A

ADDC A,#00;其余字节采用取反加进位

MOV @R0,A

DJNZ R2,LOOP

RET

例3-61:一个双字节与一个单字节无符号数乘法子程序。

入口参数:被乘数R3R4,乘数R2。

出口参数:积有3个字节,按先低后高的顺序放在片内RAM以MULADR为首地址的空间。

解:程序如下:

MUL:PUSH PSW;保护现场

SETB RS0;选择第二组工作寄存器

PUSH ACC

PUSH B

MUL0:MOV R0,#MULADR;首地址→R0

MOV A,R2;取乘数

MOV B,R4

MUL AB

MOV @R0,A;存积的最低字节

INC R0

MOV R1,B;暂存中间值

MUL1:MOV A,R2;取乘数

MOV B,R3

MUL AB

ADD A,R1

MOV @R0,A;存积的次高字节

INC R0

MOV A,B

ADDC A,#00H

MOV @R0,A;存积的高字节

POP B;恢复现场

POP A

POP PSW

RET

7 I/O控制程序设计举例

例3-62:要求在P1.0脚上产生周期为20ms的方波

解:程序如下:

FB:CPL P1.0;P1.0取反

ACALL DL10MS

SJMP FB

DL10MS:…;延时10ms子程序

RET

例3-63:如图3-19所示,编程实现当按K一次蜂鸣器“嘀、嘀”响两声。解:程序如下:

STA:MOV R2,#2

CLR P1.4

STA1:JB P1.0,STA1

LCALL DL10MS

JB P1.0,STA1

JNB P1.0,$

LOOP:SETB P1.4;产生两个短脉冲

LCALL DL300MS

CLR P1.4

LCALL DL300MS

DJNZ R2,LOOP

LJMP STA

DL10MS:…;延时10ms的子程序

RET

978-7-111-54295-7-Chapter03-51.jpg

图3-19 蜂鸣器电路

例3-64:如图3-20所示,2个按键开关K1、K2分别与单片机P3.2、P3.3相连,P1端口接有8只发光二极管,编一控制程序实现按K1键,发光二极管从上到下依次点亮;按K2键,发光二极管从下到上依次点亮,点亮间隔时间都为1s。无键按下时,灯全灭。

978-7-111-54295-7-Chapter03-52.jpg

图3-20 按键控制LED电路

解:程序如下:

START:MOV P1,#0FFH;设置输出口初值,灯全灭

MOV P3,#0FFH;设置输入方式

LOOP:MOV A,P3;读入键盘状态

CJNE A,#0FFH,LP0;是否有键按下

JMP LOOP;无键按下等待

LP0:ACALL DELAY1;调用延时去抖动

MOV A,P3;重新读入键盘状态

CJNE A,#0FFH,LP1;非误读则跳转

JMP LOOP

LP1:JNB P3.2,A1;K1按下则发光点从上到下依次点亮

JNB P3.3,A2;K2按下则发光点从下到上依次点亮

JMP START;无键按下则返回

A1:MOV R0,#8;设置左移位数

MOV A,#0FEH;设置左移初值

LOOP1:MOV P1,A;输出至P1

ACALL DELAY;调用延时1s子程序

RL A

DJNZ R0,LOOP1;判断移动位数

JMP START

A2:MOV R0,#8;设置右移位数

MOV A,#7FH;设置右移初值

LOOP2:MOV P1,A

ACALL DELAY

RR A

DJNZ R0,LOOP2

JMP START

DELAY1:…;消抖延时子程序

RET

DELAY:…;延时1s子程序

RET

END

8 逻辑运算程序设计举例

例3-65:编写一程序,实现图3-21所示的逻辑运算电路。其中,X、Y、Z代表输入项,F代表输出项。

可以看到,图中运用位与、位或、位非,以及位异或等逻辑运算形式。但单片机指令中只提供了与、或、非等位运算指令,故位异或运算必须由与、或、非指令组合而成。

解:程序如下:

X BIT 01H

Y BIT 02H

Z BIT 03H

F BIT 00H

ORG 0000H

LJMP START

ORG 0030H

START:MOV C,X

ANL C,Y

MOV F,C;实现X和Y的逻辑与运算

MOV C,Z

ANL C,/Y

MOV 10H,C

MOV C,Y

ANL C,/Z

ORL C,10H;实现Y和Z的逻辑异或

CPL C;异或之后,再取反

ORL C,F;逻辑或运算

MOV F,C;输出F

END

978-7-111-54295-7-Chapter03-53.jpg

图3-21 布尔电路图

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈