A RET 4.3 汇编语言实用程序设计

Download Report

Transcript A RET 4.3 汇编语言实用程序设计

第十一课
复习
4.3 汇编语言实用程序设计
4.3.9 码制转换程序设计
补充:数据的拼拆
小结
4.3
汇编语言实用程序设计-码制转换程序设计
4.3.9 码制转换程序设计
在单片机应用程序的设计中,经常涉及到各种码制的
转换问题。在单片机系统内部进行数据计算和存储时,经
常采用二进制码,具有运算方便、存储量小的特点。在输
入/输出中,按照人的习惯均采用代表十进制数的BCD码
(用4位二进制数表示的十进制数)表示。此外,打印机
要打印某数字字符,则需要将该数字的二进制码转换为该
字符的ASCII码,才能送到打印机去打印。
1、二进制码到BCD码的转换 例4-18、19
2、 BCD码到二进制码的转换 例4-20
3、二进制码与ASCII码之间的转换 例4-21、22、23
4.3
汇编语言实用程序设计-码制转换程序设计
1、二进制码到BCD码的转换
BCD码有两种形式:一种是1个字节放1位BCD码,它适用
于显示或输出,一种是压缩的BCD码,即1个字节放两位
BCD码,可以节省存储单元。
例4-18 单字节二进制数转换
为BCD码
BINBCD: MOV B, #64H
DIV AB
MOV 51H, A
MOV A, #0AH
XCH A, B
DIV AB
SWAP A
ADD A, B
MOV 50H, A
RET
4.3
汇编语言实用程序设计-码制转换程序设计
例4-19 将双字节二进制数转换成BCD码(十进制数)。
解:将二进制数转换成BCD码的数学模型为:
(a15a14…a1a0)2=(a15×215+a14×214+…+a1×21+a0×20)10
上式右侧即为欲求的BCD码。它可作如下变换
(a15×214+a14×213+…+a1)×2+a0
括号里的内容可变为:(a15×213 +a14×212+a13×211+…+a2)×2+a1
括号里的内容可变为:(a15×212+a14×211+a13×210+…+a3)×2+a2
……
经过16次的变换后,括号里的内容可变为:
(0×2+a15)×2+a14
所以括号里的内容的通式为ai+1×2+ai ,即为二进制数转换成
BCD码的公因式。
4.3
汇编语言实用程序设计-码制转换程序设计
在程序设计中,可利用左移
指令(乘以2)实现ai+1×2,采
用循环计算16次公因式的方法来
完成二进制数转换成BCD码。
入口参数:16位无符号数送R3,
R2。
出口参数:共有5位BCD数,万
位→R6;千、百位→R5;十、
个位→R4位。
程序流程图如右图所示。
4.3
汇编语言实用程序设计-码制转换程序设计
程序如下:
ORG 1000H
BINBCD2: CLR A
; A 清0
MOV R4, A
; 清0出口参数寄存器
MOV R5, A
MOV R6, A
MOV R7, #10H ; 设置循环次数16
LOOP: CLR C
; 标志位Cy清0,
为二进制数×2作准备
MOV A, R2
;ai+1×2
RLC A
MOV R2, A
MOV A, R3
RLC A
MOV R3, A
MOV A, R4
4.3
汇编语言实用程序设计-码制转换程序设计
ADDC A, R4 ; 带进位自身相加,相当于乘2
DA A
MOV R4, A
MOV A, R5
ADDC A, R5
DA A
MOV R5, A
MOV A, R6
ADDC A, R6
MOV R6, A
; 双字节十六进制数的万位
数不超过6,不用调整
DJNZ R7, LOOP ; 若16位未循环完,转向LOOP继续循环,否则继续执行
RET
END
4.3
汇编语言实用程序设计-码制转换程序设计
2、BCD码与二进制数的转换
例:单字节BCD码转换为二进制码
入口参数:R2; 出口参数:R2及A
BCDBIN: MOV A,R2
ANL A,#0F0H ;取高位BCD码,屏蔽低4位
SWAP A
MOV B,#0AH
MUL AB
MOV R3,A
MOV A,R2
ANL A,#0FH
ADD A,R3
;加低位BCD码
MOV R2,A
RET
4.3
汇编语言实用程序设计-码制转换程序设计
例4-20 将4位BCD码转换成二进制数。
开始
取高字节BC D数
开始
调用子程序
高位BC D数
结果×10 0
乘以10
取低字节BC D数
加低位BC D数
调用子程序
两结果相加
保存结果
返回
保存结果
返回
图 BCD码(十进制)转换成二进制数程序流程图
4.3
汇编语言实用程序设计-码制转换程序设计
程序清单如下:
MAIN:MOV A,R5
MOV R2,A
;给子程序入口参数
ACALL BCDBIN ;调用子程序
MOV B,#64H
MUL AB
MOV R6,A
XCH A,B
MOV R5,A
MOV A,R4
MOV R2,A
ACALL BCDBIN ;调用子程序
ADD A,R6
MOV R4,A
MOV A,R5
ADDC A,#00H
MOV R5,A
RET
4.3 汇编语言实用程序设计-码制转换程序设计
3、二进制数与ASCII码之间的转换
例4-21 16进制数(00H—0FH)转ASCII码子程序。
算法:凡≥10的十六进制数加37H;凡<10的十六进制数加30H。
ie. 0~9 → 30H~39H, A~F → 41H~46H
BTOASC:
LOOP0 :
ORG 2000H
MOV A,R2 ;取待转换的数据(入口)
ADD A,#0F6H ;判此数是否≥10 ?
若≥10,则C=1;<10,则C=0
MOV A,R2 ;重取待转换的数据
JNC LOOP0 ;小于10就跳去加30H
ADD A,#07H ;≥10就先加7 再去加30H
ADD A,#30H
MOV R2,A ;存结果(出口)
RET
4.3
例4-22
汇编语言实用程序设计-码制转换程序设计
用查表法将单字节的2位十六进制数转换为ASCII码
入口参数:R0,出口参数:R1、R2
HTA1: MOV A, R0
ANL
A,#0FH ;取出入口参数低4位
MOV DPTR, # ASCTABL
MOVC A,@A+DPTR ;查相应ASCII码
MOV R2, A
MOV A, R0
SWAP A
ANL A,#0FH ;取出入口参数高4位
MOVC A,@A+DPTR ;查相应ASCII码
MOV
R1, A
RET
ASCTABL:DB ‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’
DB ‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’
4.3
汇编语言实用程序设计-码制转换程序设计
例4-23、编程实现十六进制数表示的ASC1I代码转换成4位
二进制数(1位十六进制数)。
ASCHIN:
分析:
MOV A,R2
;取操作数
CLR C
;清进位标志位C
“字符0”~“字符9”的ASCII码值为“30H”~“39H”,
SUBB A,#30H
;ASCII码减去30H,实现0-9的转换
它们与30H之差恰好为“00H”~“09H”,结果均<0AH。
MOV R2,A
;暂存结果
“字符A”~“字符F”的ASCII码值为“41H”~“46H”,
SUBB A,#0AH
;结果是否>9?
它们各自减去37H后恰好为“0AH”~“0FH”,结果均>0AH。
JC LOOP
;若≤9则转换正确
XCH A,R2
;此时R2中的数为16H~11H
SUBB A,#07H
;若>9则减37H
MOV R2,A
LOOP: RET
补充:数据的拼拆
例:拆字。将片内20H单元的内容拆成两段,分别存
放于21H22H,高4位放22H
ABC: MOV A, 20H
ANL
A, #0FH
MOV
21H, A
MOV A, 20H
SWAP A
ANL
A, #0FH
MOV
22H, A
RET
补充:数据的拼拆
例.
设在30H和31H单元中各有一个8位数据:
(30H)=x7x6x5x4x3x2x1x0 ,(31H)=y7y6y5y4y3y2y1y0
现在要从30H单元中取出低5位,并从31H单元中取出低3位完成拼
装,拼装结果送40H单元保存,并且规定:(40H)=y2y1y0x4x3x2x1x0
MOV 40H,30H
;将x7~x0传送到40H单元
分析:利用逻辑指令ANL、ORL来完成数据的拼拆。
ANL 40H,#00011111B
;将高3位屏蔽掉
MOV A,31H
;将y7~y0传送到累加器中
SWAP A
;将A的内容左移4次
RL A
;y2~y0移到高3位
ANL A,#111000OOB
;将低5位屏蔽掉
ORL 40H,A
;完成拼装任务
补充:多字节十进制数(BCD码)加法
(33H) (32H)
(31H) (30H)
BCDADD:MOV
R0,#30H
MOV (42H)
R1,#40H
+(43H)
(41H) (40H)
CLR (32H)
C
(33H)
(31H) (30H)
LOOP0: MOV A,@R0
;取被加数
上述单元中是两个四字节的压缩的BCD码,求和。
ADDC A,@R1
;两数相加
DA A
;十进制调整
MOV @R0,A
INC R0
;指针加1
INC R1
DJNZ R3,LOOP0 ;作完加法否
RET
小结
1、程序功能模块化的优点
2、划分模块的原则
3、编程技巧
4、单片机源程序的基本格式
5、常见的软件错误
1、程序功能模块化的优点
单个模块结构的程序功能单一,易于编写、调试和修改。
便于分工,从而可使多个程序员同时进行程序的编写和调
试工作,加快软件研制进度。
程序可读性好,便于功能扩充和版本升级。
对程序的修改可局部进行,其它部分可以保持不变。
对于使用频繁的子程序可以建立子程序库,便于多个模块
调用。
2、划分模块的原则
每个模块应具有独立的功能,能产生一个明确的结果,即单
模块的功能高内聚性。
模块之间的控制耦合应尽量简单,数据耦合应尽量少,即模
块间的低耦合性。控制耦合是指模块进入和退出的条件及方式,
数据耦合是指模块间的信息交换方式、交换量的多少及交换频
繁程度。
模块长度适中。20条~100条的范围较合适。
3、编程技巧
尽量采用循环结构和子程序。
尽量少用无条件转移指令。
对于通用的子程序,考虑到其通用性,除了用于存放子程
序入口参数的寄存器外,子程序中用到的其他寄存器的内容
应压入堆栈(返回前再弹出),即保护现场。
在中断处理程序中,除了要保护处理程序中用到的寄存器
外,还要保护标志寄存器。
用累加器传递入口参数或返回参数比较方便,在子程序中,
一般不必把累加器内容压入堆栈。
5. 常见的软件错误
(1)逻辑错误:主要是语法错误。
(2)功能错误:主要是设计思想或算法导致不能实现软件功能
的错误。
(3)指令错误:是指在编辑应用指令时所产生的错误。如:指
令疏漏、位置不妥、指令不当和非法调用等。
(4)程序跳转错误:是指程序运行不到指定的地方,或发生死
循环等。
(5)子程序错误:
(6)动态错误:是指系统动态性能没有达到设计指标的错误。
如:控制系统的实时响应速度、显示器的亮度、定时器的精度等。
(7)上电复位电路的错误:
(8)中断程序错误:是指现场的保护与恢复错误、触发方式错
误等。
练习
1、试编写程序,将R1中的低4位数与R2中的高4位数
合并成一个8位数,并将其存放在R1中。
2、外部数据RAM中有一个数据块,存有若干个字符、
数字,首地址为SIURCE。
要求:将数据块传送到内部RAM以DIST开始的区域,
直到遇到字符“$”(24H)结束,要求$也要传送。