5 STC15F2K60S2单片机的程序设计 例题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第5章STC15F2K60S2单片机的程序设计
例题
例5.1 分析ORG在下面程序段中的控制作用
ORG 1000H
START:
MOV R0,#60H
MOV R1,#61H
……
ORG 1200H
NEXT:
MOV DPTR,#1000H
MOV R2,#70H
……
解:以START开始的程序汇编后机器码从1000H单元开始连续存放,不能超过1200H 单元;以NEXT开始程序汇编后机器码从1200H单元开始连续存放。
例5.2 分析END在下面程序段中的控制作用。
START:
MOV A,#30H
……
END START
NEXT:
……
RET
解:汇编程序对该程序进行汇编时,只将END伪指令前面的程序转换为对应的机器代码程序,而以NEXT标号为起始地址的程序将予以忽略。因此,若NEXT标号为起始地址的子程序是本程序的有效子程序的话,应将整个子程序段放到END伪指令的前面。
例5.3 分析下列程序中EQU指令的作用
AA EQU R1 ;给AA赋值R1
DA TA1 EQU 10H ;给DA TA1赋值10H
DELAY EQU 2200H ;给DELAY赋值2200H
ORG 2000H
MOV R0,DATA1 ;R0←(10H)
MOV A,AA ;A←(R1)
LCALL DELAY ;调用起始地址为2200H的子程序
END
解:经EQU定义后,AA等效于R1,DATA1等效于10H,DELAY等效于2200H,该程序在汇编时,自动将程序中AA换成R1、DATA1换成10H、DELAY换成2200H,再汇编为机器代码程序。
使用赋值伪指令EQU的好处在于程序占用的资源数据符号或寄存器符号用占用源的英文或英文缩写字符名称来定义,后续编程中凡是出现该数据符号或寄存器符号就用该字符名称代替,这样,采用有意义的字符名称进行编程,更容易记忆和不容易混淆,也便于阅读。
例5.4 试将8位二进制数据转换为十进制(BCD码)数据。
解:8位二进制数据对应的最大十进制数是255,说明一个8位二进制数据需要3位BCD 码来表示,既百位数、十位数与个位数。如何求解呢?
(1)用8位二进制数据减100,够减百位数加1,直至不够减为止;再用剩下的数去减10,够减十位数加1,直至不够减为止;剩下的数即为个位数。
(2)用8位二进制数据除以100,商为百位数,再用余数除以10 ,商为十位数,余数为个位数。
很显然,第(1)种方法更复杂,应选用第(2)种算法。设8位二进制数据存放在20H 单元,转换后十位数、个位数存放在30H单元,百位数存放在31H单元。
参考程序如下:
ORG 0000H
MOV A, 20H ;取8位二进制数据
MOV B, #100
DIV AB ;转换数据除以100,A为百位数
MOV 31H, A ;百位数存放在31H单元
MOV A, B ;取余数
MOV B, #10
DIV AB ;余数除以10,A为十位数,B为个位数
SW AP A ;将十位数从低4位交换到高4位
ORL A, B ;十位数、个位数合并为压缩BCD码
MOV 30H, A ;十位数、个位数存放在30H(高4位为十位数,低4位为个位数)
SJMP $
END
例5.5 求8位有符号数的补码。设8位二进制数存放在片内RAM 30H单元内。
解:对于负数的补码为除符号位以外取反加1,而正数的补码就是原码,因此,关键的地方是判断数据的正负,最高位为0,表示为正数,最高位为1,表示为负数。
参考程序如下:
ORG 0000H
MOV A,30H
JNB ACC.7,NEXT ;为正数,不进行处理
CPL A ;负数取反
ORL A,#80H ;恢复符号位
INC A ;加1
MOV 30H,A
NEXT:
SJMP NEXT ;结束
END
例5.6 试编写计算下式的程序:
100 (X≥0)
Y =
-100 (X < 0)
解:该例是一个双分支程序,本题关键是判断X是正数,还是负数?判断方法同例5.5。设X存在40H单元中,结果Y存放于41H中。
程序流程图如图5.5所示。
图5.5 例5.6程序流程图
参考程序如下:
X EQU 40H ;定义X的存储单元
Y EQU 41H ;定义Y存储单元
ORG 0000H
MOV A,X ;取X
JB ACC.7,BRANCH1 ;若ACC.7为1则转向BRANCH1,否则顺序执行
MOV A,#64H ;X≥0,Y=100
SJMP COMMON ;转向COMMON(分支公共处)
BRANCH1:
MOV A,#9CH ;X<0,Y= -100,把-100的补码(9CH)送A COMMON:
MOV Y,A ;保存A
SJMP $;程序结束
END
例5.7 设各分支的分支号码从0开始按递增自然数排列,执行分支号存放在R3中,编写多分支处理程序。
解:首先,在程序存储器中建立一个分支表,分支表中按从0开始的分支顺序从起始地址(表首地址,如TABLE)开始存放各分支的一条转移指令(AJMP或LJMP,AJMP占用2个字节,LJMP占用3个字节),各转移指令的目标地址就是各分支程序的入口地址。
根据各分支程序的分支号,转移到分支表中对应分支的入口处,执行该分支的转移指令,再转到分支程序的真正入口处,从而执行该分支程序。
参考程序如下:
ORG 0000H
MOV A, R3 ;取分支号
RL A ;分支号乘2,若分支表中用LJMP,则改分支号乘3
MOV DPTR, #TABLE ;分支表表首地址送DPTR
JMP @A+DPTR ;转到分支表该分支的对应入口处
TABLE:
AJMP ROUT0 ;分支表,采用短转移指令,每个分支占用2个字节
AJMP ROUT1 ;各分支在分支表的入口地址=TAB+分支号×2
AJMP ROUT2
……
ROUT0:
……;分支0程序
LJMP COMMON ;分支程序结束后,转各个分支的汇总点
ROUT1:
……;分支1程序
LJMP COMMON ;分支程序结束后,转各个分支的汇总点
ROUT2:
……;分支2程序
LJMP COMMON ;分支程序结束后,转各个分支的汇总点
……
COMMON:
SJMP COMMON ;各个分支的汇总点
END
注意:不管哪个分支程序执行完毕后,都必须回到所有分支公共回合处,如各分支程序中的“LJMP COMMON”指令。