5 STC15F2K60S2单片机的程序设计 例题

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
解:该例是一个双分支程序,本题关键是判断 X 是正数,还是负数?判断方法同例 5.5。 设 X 存在 40H 单元中,结果 Y 存放于 41H 中。
程序流程图如图 5.5 所示。
图 5.5 例 5.6 程序流程图
参考程序如下:
X EQU 40H ;定义 X 的存储单元
Y EQU 41H ;定义 Y 存储单元
文或英文缩写字符名称来定义,后续编程中凡是出现该数据符号或寄存器符号就用该字符名
称代替,这样,采用有意义的字符名称进行编程,更容易记忆和不容易混淆,也便于阅读。
88
例 5.4 试将 8 位二进制数据转换为十进制(BCD 码)数据。 解:8 位二进制数据对应的最大十进制数是 255,说明一个 8 位二进制数据需要 3 位 BCD 码来表示,既百位数、十位数与个位数。如何求解呢?
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
例 5.2 分析 END 在下面程序段中的控制作用。 START:
MOV A,#30H …… END START NEXT: …… RET 解:汇编程序对该程序进行汇编时,只将 END 伪指令前面的程序转换为对应的机器代码 程序,而以 NEXT 标号为起始地址的程序将予以忽略。因此,若 NEXT 标号为起始地址的子 程序是本程序的有效子程序的话,应将整个子程序段放到 END 伪指令的前面。
根据各分支程序的分支号,转移到分支表中对应分支的入口处,执行该分支的转移指令,
再转到分支程序的真正入口处,从而执行该分支程序。
参考程序如下:
ORG 0000H
MOV A, R3
;取分支号
RL A
;分支号乘 2,若分支表中用 LJMP,则改分支号乘 3
MOV DPTR, #TABLE ;分支表表首地址送 DPTR
INC R2
;传送字符个数计数器加 1
SJMP LOOP0
;继续下一个循环
STOP:
SJMP $
;程序结束
END
93
例 5.9 将内部 RAM 中起始地址为 DATA 的字符串数据传送扩展 RAM 中起始地址为
BUFFER 的存储区域内,字符串的结束字符是“$”。
解:程序功能与例 5.8 基本一致,但字符串的结束字符 “$”是字符串中的一员,也是
ORG 0000H MOV A,30H
JNB ACC.7,NEXT CPL A ORL A,#80H INC A MOV 30H,A NEXT:
SJMP NEXT
; 为正数,不进行处理 ; 负数取反 ;恢复符号位 ;加 1
;结束
END
90
例 5.6 试编写计算下式的程序: 100 (X≥0)
Y= -100 (X < 0)
(1)用 8 位二进制数据减 100,够减百位数加 1,直至不够减为止;再用剩下的数去减 10,够减十位数加 1,直至不够减为止;剩下的数即为个位数。
(2)用 8 位二进制数据除以 100,商为百位数,再用余数除以 10 ,商为十位数,余数 为个位数。
很显然,第(1)种方法更复杂,应选用第(2)种算法。设 8 位二进制数据存放在 20H 单元,转换后十位数、个位数存放在 30H 单元,百位数存放在 31H 单元。
设 DATA 为 20H,BUFFER 为 0200H,参考程序如下:
ORG 00000H
DATA EQU 20H
BUFFER EQU 0200H
MOV R2, #00H
;统计传送字符个数计数器清零
百度文库
MOV R0, #DATA
;设置源操作数指针
MOV DPTR, #BUFFER ;设置目标操作数指针
LOOP0:
解:本例中,数据传送的次数是固定的,为 16 次;因此,可用一个计数器来控制循环体 程序的执行次数。既可以用加 1 计数来实现控制(采用 CJNE 指令),也可以采用减 1 计数来 实现控制(采用 DJNZ 指令)。一般情况下,采用减 1 计数控制居多。
参考程序如下:
ORG 0000H MOV DPTR,#1000H MOV R0,#20H MOV R2,#10H LOOP: MOVX A,@DPTR MOV @R0,A INC DPTR INC R0 DJNZ R2,LOOP
MOV A, @R0
;取被传送数据
CJNE A, #20H, LOOP1 ;判断是否为空格字符(ASCII 码为 20H)
SJMP STOP
;是空格字符,停止传送
LOOP1:
MOVX @DPTR, A ;不是空格字符,传送数据
INC R0
;指向下一个被传送地址
INC DPTR
;指向下一个传送目标地址
解:软件延时程序是应用编程中的基本子程序,是通过反复执行空操作指令(NOP)和
循环控制指令(DJNZ)占用时间来达到延时目的的。因为执行一条指令的时间非常短,一般
都需要采用多重循环才能满足要求。
参考程序如下:
源程序
系统时钟数
占用时间
DELAY:
MOV R1,#100
2
1/6μs
DELAY1:
MOV R2,#200
;设置被传送数据的地址指针 ;设置目的地地址指针 ;用 R2 作计数器,设置传送次数
;取被传送数 ; 传送到目的地 ;指向下一个源操作数地址 ;指向下一个目的操作数地址
;计数器 R2 减 1,不为 0 继续,否则结束传送
SJMP $
END
95
例 5.11 已知单片机系统的系统时钟频率 12MHZ,试设计一软件延时程序,延时时间为 10ms。
;余数除以 10,A 为十位数,B 为个位数 ;将十位数从低 4 位交换到高 4 位 ;十位数、个位数合并为压缩 BCD 码 ;十位数、个位数存放在 30H(高 4 位为十位数,低 4 位为个
SJMP $
END
89
例 5.5 求 8 位有符号数的补码。设 8 位二进制数存放在片内 RAM 30H 单元内。 解:对于负数的补码为除符号位以外取反加 1,而正数的补码就是原码,因此,关键的 地方是判断数据的正负,最高位为 0,表示为正数,最高位为 1,表示为负数。 参考程序如下:
参考程序如下:
ORG 0000H MOV A, 20H
;取 8 位二进制数据
MOV B, #100 DIV AB MOV 31H, A MOV A, B
;转换数据除以 100,A 为百位数 ;百位数存放在 31H 单元
;取余数
MOV B, #10 DIV AB SWAP A ORL A, B MOV 30H, A 位数)
MOV A, @R0
;取被传送数据
MOVX @DPTR, A
INC R0
;指向下一个被传送地址
INC DPTR
;指向下一个传送目标地址
CJNE A, #24H, LOOP0 ;判断是否为“$”字符(ASCII 码为 24H),若不是继续
SJMP $
;是“$”字符,停止传送
END
94
例 5.10 编程将扩展 RAM1000H 为起始地址的 16 个数据传送到片内基本 RAM20H 为起 始地址的单元中。
……
LJMP COMMON ……
;分支 0 程序 ;分支程序结束后,转各个分支的汇总点
;分支 1 程序 ;分支程序结束后,转各个分支的汇总点
;分支 2 程序 ;分支程序结束后,转各个分支的汇总点
COMMON: SJMP COMMON
;各个分支的汇总点
END 注意:不管哪个分支程序执行完毕后,都必须回到所有分支公共回合处,如各分支程序
COMMON: MOV Y,A SJMP $
;保存 A ;程序结束
END
91
例 5.7 设各分支的分支号码从 0 开始按递增自然数排列,执行分支号存放在 R3 中,编 写多分支处理程序。
解:首先,在程序存储器中建立一个分支表,分支表中按从 0 开始的分支顺序从起始地 址(表首地址,如 TABLE)开始存放各分支的一条转移指令(AJMP 或 LJMP,AJMP 占用 2 个字节,LJMP 占用 3 个字节),各转移指令的目标地址就是各分支程序的入口地址。
MOVC A,@A+PC
;使用查表指令求平方
RET TAB:
DB 0,1,4,9, ,16,25,36,49,64,81
END SQR 子程序的入口参数和出口参数都是通过 A 进行传递的。
97
例 5.13 有两个 32 位无符号数分别存放在片内基本 RAM20H 和 30H 为起始地址的存储 区域内,低字节在低地址,高字节在高地址。编程将两个 32 位无符号数相加结果存在扩展 RAM0020H 为起始地址的存储区域中。
中的“LJMP COMMON”指令。
92
例 5.8 将内部 RAM 中起始地址为 DATA 的字符串数据传送扩展 RAM 中起始地址为 BUFFER 的存储区域内,并统计传送字符的个数,直到发现空格字符停止传送。
解:题目中已明确发现空格字符时就停止传送,因此,编程时应先对传送数据进行判断,
再决定是否传送。
2
1/6μs
DELAY2:
NOP
1
NOP
1
DJNZ R2,DELAY2
4
1/12μs 1/12μs 1/3μs






DJNZ R1,DELAY1
4
1/3μs
RET
4
1/3μs
96
例 5.12 编程实现 C=a2+b2。设 a、b 均小于 10 且分别存于扩展 RAM 的 1000H、1001H 单元,要求运算结果 C 存于外部 RAM1002H 单元。
LCALL DELAY
;调用起始地址为 2200H 的子程序
END
解:经 EQU 定义后,AA 等效于 R1,DATA1 等效于 10H,DELAY 等效于 2200H,该程
序在汇编时,自动将程序中 AA 换成 R1、DATA1 换成 10H、DELAY 换成 2200H,再汇编为
机器代码程序。
使用赋值伪指令 EQU 的好处在于程序占用的资源数据符号或寄存器符号用占用源的英
JMP @A+DPTR
;转到分支表该分支的对应入口处
TABLE:
AJMP ROUT0
;分支表,采用短转移指令,每个分支占用 2 个字节
AJMP ROUT1
;各分支在分支表的入口地址=TAB+分支号×2
AJMP ROUT2 ……
ROUT0: ……
LJMP COMMON ROUT1:
……
LJMP COMMON ROUT2:
87
例 5.3 分析下列程序中 EQU 指令的作用
AA EQU R1
;给 AA 赋值 R1
DATA1 EQU 10H
;给 DATA1 赋值 10H
DELAY EQU 2200H
;给 DELAY 赋值 2200H
ORG 2000H
MOV R0,DATA1 ;R0←(10H)
MOV A, AA
;A←(R1)
需要传送的,因此,编程时应先传送,再对传送数据进行判断,以判断字符串数据传送是否
结束。
设 DATA 为 20H,BUFFER 为 0200H,参考程序如下:
DATA EQU 20H
BUFFER EQU 0200H
ORG 0000H
MOV R0, #DATA
MOV DPTR, #BUFFER
LOOP0:
第 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 单元开始连续存放。
解:本题可利用子程序完成求单字节数据的平方,然后通过调用子程序求出 a2 和 b2。 参考程序如下:
;主程序
ORG 0000H START:
MOV DPTR,#1000H MOVX A,@DPTR LCALL SQUARE MOV R1,A
; 取 a 的值 ;调用子程序求 a 的平方
; a2 暂存于 R1 中
INC DPTR MOVX A,@DPTR ACALL SQUARE ADD A,R1
;取 b 的值 ;调用子程序求 b 的平方
;A←a2+b2
INC DPTR MOVX @DPTR,A
;存结果
SJMP $ ;子程序如下
ORG 2500H
SQUARE:
INC A
;表首地址与查表指令相隔 1 个字节,故加 1 调整
相关文档
最新文档