Download - 【 例 3-1】 ( A ) =53H , ( R0 ) =FCH ,执行指令 ADD A,R0 结果 : ( A ) =4FH , Cy=1 , Ac=0 , OV=0 , P=1
【例 3-1】 (A)=53H, (R0)=FCH ,执行指令 ADD A,R0
结果 : (A)=4FH, Cy=1, Ac=0,OV=0, P=1
注意:运算中,由于位 6 和位 7 同时有进位,所以标志位OV=0 。
【例 3-2 】 (A)= 85H,(R0)=20H,(20H)=AFH ,执行指令 :
ADD A,@R0
结果 : ( A )=34H, Cy=1, Ac=1,OV=1, P=1
注意:由于位 7 有进位,而位 6 无进位,所以标志位 OV=1
P.38
0 1 0 1 0 0 1 1 + 1 1 1 1 1 1 0 0 1 1 1 0 0 0 0
= 0 1 0 0 1 1 1 1
Cy: 1
1 0 0 0 0 1 0 1 + 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1
= 0 0 1 1 0 1 0 0
Cy: 1
【例 3-3】 ( A )=85H,( 20H)=FFH,Cy=1 ,执行指令: ADDC A,20H结果为 : ( A )=85H,Cy=1,Ac=1,OV=0,P=1
【例 3-4】 ( A )=56H,( R5)=67H ,把它们看作为两个压缩的 BCD 数,进行 BCD 数的加法。执行指令:
ADD A,R5 ;先按二进制加,得 BDH DA A ;紧接着进行 BCD 调整,得 23H 且有向上进位结果为:( A )=23H, Cy=1 ( 维持 ADD后的
Ac=1,OV=1),P=1 。 可见, 56+67=123 ,结果是正确的。
【例 3-5】 (A)=C9H,(R2)=54H,Cy=1, 执行指令 SUBB A,R2 结果:( A ) =74H,Cy=0,Ac=0,OV=1 (位 6 向位 7 借位而位 7 无 向上借位) , P=0
P.38~40
1 0 0 0 0 1 0 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
= 1 0 0 0 0 1 0 1
Cy: 1 ←原 Cy
1 1 0 0 1 0 0 1 - 0 1 0 1 0 1 0 0 - 1 = 0 1 1 1 0 1 0 0
Cy: 0
←原Cy
【例 3-6】 (A)=0FH, (R7)=19H, (30H)=00H,(R1)=40H, (40H)=0FFH ,执行指令
DEC A ;(A)-1→A = 0EHDEC R7 ;(R7)-1→R7 =18HDEC 30H ;(30H)-1→30H = FFHDEC @R1 ;((R1))-1→(R1) = FEH
结果为 (A)=0EH,(R7)=18H,(30H)=0FFH,(40H)=0FEH,P=1 ,
不影响其他标志 【例 3-7】 (A)=FBH, (B)=12H ,执行指令
DIV AB结果为 (A)=0DH, (B)=11H, Cy=0,OV=0 。
P.41
【例 B3-7 】编程序实现 R1、 R2 中的双字节 BCD 数加上 R3、 R4 中的双字节 BCD 数,三字节和值存放于 R5、 R6、 R7 中。
ORG 11A0H11A0 EA MOV A, R2 ;取被加数低字节11A1 2C ADD A, R4 ;加上加数低字节11A2 D4 DA A ;十进制调整11A3 FF MOV R7, A ;存和值的低字节11A4 E9 MOV A, R1 ;取被加数高字节11A5 3B ADDC A, R3 ;加上加数高字节及低字节的进位 11A6 D4 DA A ;十进制调整 11A7 FE MOV R6, A ;存和值的高字节11A8 74 00 MOV A,#00H ;被加数与加数无第三字节,设其为
011AA 34 00 ADDC A,#00H ;加上高字节向第三字节的进位 ;无需进行十进制调整 ( 其结果为 00H或 01H) 11AC FD MOV R5, A ;存和值的第三字节11AD 80 FE SJMP $ ;自循环暂停11AF【练习】如果是双字节数相加结果只需双字节呢? 如果是双字节二进制数相加 ( 不是 BCD数 ) 呢? 如果是双字节二进制数相减结果为双字节二进制数呢? 如果是单字节二进制数相加结果为双字节呢? 如果是 (31H)、 (30H) 的双字节数加上 (41H)、 (40H) 中的双字节数,三字
节结果存放于 (52H)、 (51H)、 (50H) 中,前者为高字节,如何编程。
移位指令操作示意图
D7 D0
D7
D7
D7
D0
D0
D0
【例B3-11 】 8 位二进制码算术左移(无符号数乘 2 ): CLR C ;Cy清0
RLCA ;左移 1 位 , 低位补 0 ,原最高位进到 Cy 中 【例B3-12 】 8 位二进制码逻辑右移(无符号数除 2 ): CLR C ;Cy清0 RRCA ;右移 1 位 , 高位补 0 ,原最低位移到 Cy 中
【思考 】 DPTR(DPH、DPL )中的 16 位二进制码算术左移(乘 2 )【思考 】 DPTR(DPH、DPL )中的 16 位二进制码逻辑右移(除 2 )
请分析下列程序段执行后有关单元的内容。
MOV A, #68HMOV R0, #40HPUSH ACCADD A, #50HMOV @R0, AMOV A, R0INC R0MOV @R0,APOP BORL A, 40H
答: A= , R0= , B= , (40H)= , (41H)=
; 单字节 BCD 码加法运算0000 ORG 0000H
0000 802E SJMP MAIN
0002
0030 ORG 0030H
0030 7456 MAIN:MOV A , #56H
0032 2467 ADD A , #67H
0034 D4 DA A
0035 F530 MOV 30H , A
0037 80FE SJMP $ ;
0039 END
【例】单字节 BCD 码加法运算(BCD.ASM )
目标地址 0030 减下一址 - 0002 获 rel 字节 002E
[+46] 补
PC→
执行相对转移: PC ← PC + rel ;∴ rel=[ 目标地址 - 下一指令址 ] 低8 位 目标地址 下一指令址 + 偏移量
0030H ← 0002H + 0046H
+48
+2
例 4-12( 改 ) 如果 xi 均为单字节数,并按 i 顺序存放在 51 单片机内部RAM从 50H 开始的单元中,数据个数 n 放在 R2 中,求这批数据的和(双字节)放在 R3、R4 中,程序如下 : (求数组和程序)
ORG 0000HADD1: MOV R2,#0AH ; 加法次数 n 送R2,n 为具体的数据个数 ,如
10 MOV R3,#0 ; 部分和高字节单元清 0 MOV R4,#0 ; 部分和低字节单元清 0
MOV R0,#50H;R0 指向第一个数LOOP: MOV A,R4 ; 取部分和低字节原有的值
ADD A,@R0 ; 加上当前数低字节 ( 本例原始数据只有低字节 ) MOV R4,A ; 回存新的部分和低字节结果 MOV A,R3 ; 取部分和高字节原有的值ADDC A, #00H ; 加上当前数高字节 (00H) 及低字节的进位 MOV R3,A ; 回存新的部分和高字节结果INC R0 ;R0 指向下一个数DJNZ R2,LOOP ; 未加完,转回继续进行下一个数的累加SJMP $END
P.68
补充 1 : 请编程序使 40H、 41H 单元所存储的二个数中的大数减去小数,差值存 58H 单元(即求两数差的绝对值)。
补充 2 :有 8 个双字节 BCD 数存放在片内 RAM的40H 开始的单元中,请编程求它们的和(双字节)放在 60H、 61H 单元中。(设双字节数的高字节存放在两字节的高地址单元)
补充 3 :完成下列程序的人工汇编工作: ORG 2036H D2 SETB P1.6 12 LOOP: LCALL DELY B2 CPL P1.6 80 SJMP LOOP 7D DELY:MOV R5, #0F5H 00 DELY2: NOP 00 NOP DD DJNZ R5, DELY2 22 RET
2036 1 ORG 2036H2036 D296 2 SETB P1.62038 12203F 3 LOOP:LCALL DELY203B B296 4 CPL P1.6203D 80F9 5 SJMP LOOP203F 7DF5 6 DELY: MOV R5,#0F5H2041 00 7 DELY2: NOP2042 00 8 NOP2043 DDFC 9 DJNZ R5,DELY2 2045 22 10 RET
【例 B5-2】外部中断 INT0每中断五次令 P1.0求反一次 (INT0-2.ASM )
( 要紧接着DJNZ后重置 )
DJNZ 4AH,LR MOV 4AH,#200DJNZ 49H,LR MOV 49H,#100
MOV 4AH,#200MOV 49H,#100
软件计数改为5×100×200=100000次
【例 B5-2 】 INT0 每中断 1 次令 50H 单元内容加 1 并且输出到 P1 口
(INT0-5.ASM )
MOV A,50HADD A,#1 DA AMOV 50H,A
按 BCD码加 1
【例 B4-3 】将 3AH 单元中的压缩 BCD 码转换为非压缩BCD 码分别存放到 30H、 31H 单元中去,其中高位 ( 十位 ) 存放在 31H 单元。
CZ1:MOV A,3AH ; 取压缩 BCD 码ANL A,#0FH ; 保留低 4 位(个位)MOV 30H,A ; 送非压缩 BCD 码个位单元
MOV A,3AH ; 再取原压缩 BCD 码ANL A,#0F0H ; 保留高 4 位(十位)SWAP A ; 交换到低 4 位MOV 31H,A ; 送非压缩 BCD 码十位单元
•编写非压缩 BCD 码转换为压缩 BCD 码的程序•编写压缩 BCD 码转换为对应的两个 ASCII 码的程序•编写两个 0~9 的 ASCII 码转换为对应的压缩 BCD 码的程序
【拆字拼字典型程序例】
【拼字程序】
【拼字程序】【拆字程序】
【拆字程序】
屏蔽高四位
屏蔽低四位
【例 B4-3 】将 3AH 单元中的压缩 BCD 码转换为非压缩BCD 码分别存放到 30H、 31H 单元中去,其中高位 ( 十位 ) 存放在 31H 单元。
CZ:MOV R0,#3AH ; 拆字程序。 R0 指向压缩 BCD 码单元MOV R1,#30H ; R1 指向非压缩 BCD 码第一单元
CZ1:MOV A,@R0 ; 取压缩 BCD 码ANL A,#0FH ; 保留低 4 位(个位)MOV @R1,A ; 送非压缩 BCD 码个位单元INC R1 ;R1 指向高位单元(十位)MOV A,@R0 ; 再取原压缩 BCD 码ANL A,#0F0H ; 保留高 4 位(十位)SWAP A ; 交换到低 4 位MOV @R1,A ; 送非压缩 BCD 码十位单元
【拆字拼字典型程序例】
【例 B4-1 】请编程序使 48H、 49H 单元所存储的二个数中较大者
在前。 ORG 0000H
BIG:MOV A ,48H ; 取甲CLR C ; 清 CySUBB A ,49H ; 减去乙数JNC LP1 ; 无借位则甲≥乙 ,转 LP1MOV A ,48H ; 乙数大:两数交换MOV 48,49HMOV 49H,A
LP1:SJMP $ ; 自循环
【练习】 请编程序使 48H、 49H 单元所存储的二个数中较小者送
28H 单元。 请编程序判断若 34H、 35H 单元所存储的二个数相等则置
F0 位为 0 ,否则置 1 。
CJNE A,49H,LP SJMP LP1 ; 相等
LP:JNC LP1 ; 甲>乙
例4-14 50ms 延时程序。使用 12MHz 晶振时,一个机器周期为 TM=1µs, 执行一条DJNZ 指令的时间为 2µs 。这时,可用双重循环方法写出延时 50ms 的程序:DEL: MOV R7,#200 ①
DEL1: MOV R6,#125 ②
DEL2: DJNZ R6,DEL2 ③ ;估算: 2*125*200*1µs≈50ms
DJNZ R7,DEL1 ④
RET ⑤
以上计算没有考虑到除“DJNZ R6,DEL2 ” 指令外的其它指令的执行时间,如细致计算,它的延时时间为:
[1+(1+2*125+2 ) *200+2]×1µs=50603µs=50.603ms
多重循环程序:最常见的多重循环是软件延时程序。P.69
① ② ③ ④ ⑤
; 实现 P1 口输出驱动 8 只 LED巡回点亮的控制程序ORG 0000H
MAIN:MOV SP,#6FH ; 设定栈底指针SETB C ;Cy置 '1'MOV P1,#0FEH ; 置控制码初始值并输出 P1口 ,
(P1.0='0', 其他为 '1') LOOP:LCALL D1S ; 延时 1S
MOV A,P1 ; 读入 P1 口原控制码RL A ; 调整控制码(循环左移一位)
MOV P1,A ; 输出新控制码到 P1 口 SJMP LOOP D1S:MOV R7,#8 ① ; 软件延时 1S子程序 D1S2:MOV R6,#200② D1S1:MOV R5,#200③ D1S0:NOP ;④ 估算 3×200×200×8×1.085uS≈1.0416 S
DJNZ R5,D1S0⑤DJNZ R6,D1S1⑥DJNZ R7,D1S2⑦RET⑧END
<2 +1+{ 1+[1+(1+2)×200+2]×200+2 }×8+2>TM
=964829TM=964829×12/11.0592=1,046,897uS
CALL ① ② ③ ④⑤ ⑥ ⑦ ⑧
【计算程序运行时间例】
作业四 : P.83 — 1. 2.补充 5-1 :编写完整的应用程序,运用外部中断功能,实现从
INT1引脚每输入 2 个下降沿信号令 3FH 单元内容按 BCD码加 1 并且输出到 P1 口。
补充 5-2 :请列式准确计算出运行下列软件延时子程序需要花费的机器周期数,设单片机时钟频率为 11.0592MHZ ,该子程序运行时间是多少的?
DELAY:MOV R7, #3CHNOP
DL:MOV R6, #0F8HNOP
DJNZ R6, $ DEC R7
DJNZ R7, DL RET
【例 8-1】 编写程序将片外数据存储器中 5000H~ 50FFH 单元全部清零
方法 1 :用DPTR 作数据地址指针,同时使用字节计数器。 (计数控制循环 )
MOV DPTR,#5000H ;设置数据块指针的初值 MOV R7,#00H ;设置块长度计数器初值
CLR A ; A 置写数据 00H
LOOP : MOVX @DPTR,A ;把当前单元清零 INC DPTR ;地址指针加 1 DJNZ R7, LOOP ;减 1 ,若不为 0 则继续清
零HERE : SJMP HERE ;执行完毕,原地踏步
P.134
如果改为对 4FA0H~ 508AH单元写数据 D6H ,如上更改。
4FA0H
EBH
MOV A,#0D6H
例 8-1 编写程序将片外数据存储器中 5000H~ 50FFH 单元全部清零
方法 2 :
用DPTR 作为数据区地址指针,但不使用字节计数器,而是比较特征地址。 ( 条件控制循环 )
MOV DPTR,#5000H ;设置数据块指针的初值CLR A ; A 置写数据 00H
LOOP:MOVX @DPTR,A ;把当前单元清零INC DPTR ;地址指针加 1MOV R7,DPL ;取新地址值低字节CJNE R7, # 0 , LOOP ;与末地址 +1 的低字节比较,未
完继续
HERE: SJMP HERE
P.134
4FA0H
MOV A,#0D6H
8BH
如果改为对 4FA0H~ 508AH单元写数据 D6H ,如上更改。
【例 B4-2】 有一组数据,存放在 30H 为首地址的内存单元,数据长度为12 个。试将每一个数取出加 1 ,依序存放到以 50H 为首地址的单元中。
ORG 0000H0000 02 00 30 LJMP START00030030 ORG 0030H0030 78 30 START:MOV R0,#30H ; R0 指向源数据区首地址0032 79 50 MOV R1,#50H ; R1 指向目标数据区首地址0034 7F 0C MOV R7,#12 ;置循环计数初值 120036 E6 LOOP:MOV A,@R0 ;取当前源数据0037 04 INC A ;加 10038 F7 MOV @R1,A ;送目标数据区当前单元0039 08 INC R0 ; R0 指向下一个源数据003A 09 INC R1 ; R1 指向下一个目标单元003B DF F9 DJNZ R7,LOOP ;循环计数减 1 ,未完继续003D 80 FE SJMP $
END
【数据块传送程序例】
•若题中说明数据个数 n 存放在 2FH单元中?•若要求的是个数据取出按 BCD码加 1 后传送?•若要求的是数据原样传送?•若要求的是依序传送到 58H之前的内存单元中?•若要求的是与片外数据存储器之间进行数据块传送?
作业五 : P.140 — 4. 6. 7. 8. 11. 13. (对每个答案仔细思考为什么)
补充 4-4 :编写完整的应用程序,将片外数据存储器2A01H 开始的 24 个单字节数据依次传送到片内 32H 开始的单元中。
补充 8-1 :请列出详细的地址分析过程,求出下列存储器片选译码电路各输出端所对应的地址区域。
6.2.2 方式 1——16 位计数方式
图 6-5
溢出中断标志
+1计数溢出
16位可预置加 1 计数器‘1’接通
P.87-88
P.86
计数初值 可计数 可定时 0000H 65536次 65536TM 0001H 65535次 65535TM · · · · · · · · · · · · FFFFH 1次 1TM
TMTOSC
6.4.1 方式 1 应用 【例 6-1】 假设系统时钟频率采用 6MHz ,要在 P1.0 上输
出一个周期为 2ms 的方波,即 500Hz方波,如图 6-13 所示。
图 6-13
(12MHZ)
(1uS)
500×2uS
12MHZ时最长可定时 65536uS 11.0592MHZ时最长可定时约 71111uS
每 1mS 令 P1.0求反一次即可
ORG 0000HRESET: AJMP MAIN ;转主程序 ORG 000BH ; T0 的中断入口
AJMP IT0P ;转 T0 中断处理程序 IT0P
ORG 0100HMAIN: MOV SP,#60H ;设堆栈指针 MOV TMOD,#01H ;设置 T0 为定时方式
1, 00000001B PT0M0: MOV TL0,#0CH ; 置 T0 计 数 初 值
FE0CH,500=01F4H MOV TH0,#0FEH ; 0000H-
FE0CH=500,500×2uS=1mS SETB ET0 ;允许 T0 中断 SETB EA ;CPU 开中断
SETB TR0 ;启动 T0 HERE: AJMP HERE ;自身跳转 ITOP: MOV TL0,#0CH ; T0 中断服务子程序, T0重新置初
值 MOV TH0,#0FEH ;重置初值会导致有若干个 TM误差 CPL P1.0 ;P1.0 的状态取反 RETI ;中断返回
P.91【例 6-1】
•若改 TMOD赋值 05H,则实现:对 T0引脚每计满 500个脉冲令 P1.0求反一次•若改计数初值为 65536-250=65286=FF06H 则实现: P1.0输出 1000HZ方波
[ 题意:Fosc=6MHz]
6.2.3 方式 2 ——8 位计数自动重装工作方式
图 6-6
P.88
计数初值 可计数 可定时 00H 256次 256TM 01H 255次 255TM · · · · · · · · · FFH 1次 1TM
【例 B6-1 】改例 6-1为 T0定时方式 2 实现 P1.0 输出 1000HZ方波
( 1 )选择工作方式 控制字为 TMOD=00000010B=02H。 ( 2 )计算 T0 的计数初值 X=28-250=6=06H 因此, TL1的初值为 06H,重装初值寄存器 TH1=06H ( 3 )程序设计 借上例程序框架改造如下页:
自动重装初值寄存器
8 位可预置加 1 计数器
+1
TMTOSC
(12MHZ)
(1uS)
溢出中断标志计数
溢出
‘1’接通
12MHZ时最长可定时 256uS 11.0592MHZ时最长可定时约 277.7uS
自动
【例 B6-1 】改例 6-1为 T0定时方式 2 实现 P1.0 输出1000HZ方波 ORG 0000H
RESET: AJMP MAIN ;转主程序 ORG 000BH ; T0 的中断入口
AJMP IT0P ;转 T0 中断处理程序 IT0P
ORG 0100HMAIN: MOV SP,#60H ;设堆栈指针 MOV TMOD,#02H ;设置 T0 为定时方式
2 , 00000010B PT0M0: MOV TL0,#06H ;置 T0 计数初值 06H, 定时
250×2=500uS MOV TH0,#06H ;置自动重装初值 06H
SETB ET0 ;允许 T0 中断 SETB EA ; CPU 开中断
SETB TR0 ;启动 T0 HERE: AJMP HERE ;自身跳转 ITOP: ; T0 中断服务子程序。
CPL P1.0 ; P1.0 的状态取反 RETI ;中断返回
[ 题意:Fosc=6MHz]
【例 B6-2 】扩展例 B6-1 的定时时间为 P1.0 输出 1HZ方波 ORG 0000H
RESET: AJMP MAIN ;转主程序 ORG 000BH ; T0 的中断入口
AJMP IT0P ;转 T0 中断处理程序 IT0P ORG 0100HMAIN: MOV SP,#60H ;设堆栈指针 MOV TMOD,#02H ;设置 T0 为定时方式
2 , 00000010B PT0M0: MOV TL0,#06H ;置 T0计数初值 06H , 定时
250×2=500uS MOV TH0,#06H ;置自动重装初值 06H
SETB ET0 ;允许 T0 中断 SETB EA ; CPU 开中断
SETB TR0 ;启动 T0 MOV 58H,#10 MOV 59H,#100
HERE: AJMP HERE ITOP: DJNZ 58H,LR ;递减计数
MOV 58H,#10 DJNZ 59H,LR
MOV 59H,#100 CPL P1.0 ; P1.0 的状态取反 LR:RETI ;中断返回
[Fosc=6MHz]
MOV 58H,#00H
MOV 59H,#00H
INC 58H ; 二进制加 1
MOV A,58HCJNE
A,#0AH,LRMOV
58H,#00HMOV A,59HADD
A,#01H ;BCD加 1
DA AMOV 59H,ACJNE
A,#00H,LRMOV
59H,#00H
以递增计数方式实现中断次数的计数扩展
【例 6-4】 利用 T1 的方式 2 对外部信号计数,要求每计满 100 个数,将 P1.0 取反。(本例是方式 2计数模式的应用)
( 1 )选择工作方式 T1计数方式 2 的控制字为 TMOD=60H。( 2 ) 计 算 T1 的 初 值 X=28-
100=156=9CH ,∴ TH1=TL1=9CH( 3 )程序设计 ORG 0000H
LJMP MAINORG 001BH ; T1 中断服务程序入口
CPL P1.0 ; P1.0 位取反 RETI ORG 0100H MAIN:MOV TMOD,#60H ; 设 T1 为 计 数 方 式
2, 01100000B MOV TL1,#9CH ; T0 置初值 MOV TH1,#9CH SETB ET1 ;允许 T1 中断 SETB EA ; CPU 开中断 SETB TR1 ;启动 T1 HERE:AJMP HERE
P.94
4.3.4 数据极值查找程序设计 在指定的无序数据区中找出最大值(或最小值)。 逐个进行数值大小的比较,记存下暂时较大 ( 小 ) 的数,最终从这批数据中找出最大值(或最小值)并存于某一单元中。
• 不带符号数比较大小根据相减后 Cy标志位判定
• 补码表示的带符号数比较大小根据相减后差的符号位及 OV标志位判定
P.62
A-B, Cy=0( JNC)则 A≥B Cy=1( JC) 则 A < B
A-B→E, Es=0(正)且 OV=0 或 Es=1(负)且 OV=1 则A≥B Es=1(负)且 OV=0 或 Es=0(正)且 OV=1 则 A < B
0100 ORG 0100H0100 90 20 41 MOV DPTR , #2041H 0103 E0 MOVX A , @DPTR 0104 FF MOV R7,A ; 取数据个数为循环次数0105 A3 INC DPTR ;DPTR 指向第一个数据0106 75 30 00 MOV 30H , #00H ; 向暂存单元预置极小值0109 E0 L1: MOVX A , @DPIR ; 取当前数据010A B5 30 02 CJNE A , 30H , L2 ;比较 , 不等则进一步判大小010D 80 04 SJMP L3 ; 相等则跳转 ( 本例可略去 )010F 40 02 L2:JC L3 ;Cy=1说明当前数小则跳转0111 F5 30 MOV 30H,A ;Cy=0: 当前数大则取代原暂存单元值0113 A3 L3:INC DPTR ;DPTR 指向下一个数据0114 DF F3 DJNZ R7 , L1 ; 未完继续比较0116 90 20 40 MOV DPTR,#2040H0119 E5 30 MOV A,30H011B F0 MOVX @DPTR,A ; 存最大值结果011C 80 FE SJMP $010E END P.70—9习题分析( 改求最小数存
6AH单元 )
【例 B4-4 】以 2042H 为首地址的存储单元中,连续存放一组单字节无符号数,数据个数存于 2041H 单元,从中找出最大数并存于 2040H。
循环次数
地址指针→ 数据初值→
循环体
循环控制→
结果处理
为下循环准备→
•找最小值?•对片内单元数据?
【求极值典型程序例】
循环准备
相等的处理
小于→大于→
4.3.3 关键字查找程序设计顺序检索和对分检索1. 顺序检索 从第 1 项开始逐项顺序查找,判断所取数据是否与关键字相等。
找到与关键字相等的数据则进行……处理,继续或结束检索; 全部数据扫描完从未发现与关键字相等的数据则进行……处理。
P.61
【例B4-5 】从30H 开始的 20 个字节的无序表中查找一个关键字如 4AH ,若有则将其所在单元地址存 R3 ,若不存在则 R3置 0 。
ORG 0200HJS: MOV R0,#30H ;R0 指向数据区首地址
MOV R5, #14H ;取数据长度于 R5 作为循环次数 MOV 2FH,#4AH ;关键字 4AH 存至2FH 单元
LOOP: MOV A,@R0 ;取当前数据CJNE A,2FH,LP1 ;与关键字比较 , 不相等转查下一个MOV A, R0 ;找到关键字:取该数据所在地址MOV R3,A ;存到 R3 中SJMP LP2 ;结束查找
LP1: INC R0 ;R0 指向新一个数据DJNZ R5,LOOP ;未找完,继续MOV R3,#00H ;全部查找结束:说明不存在, R3置00H
LP2: SJMP $
P.70—7、 8 习题分析
这是初次找到的关键字数据的地址
•若查找的关键字是字符‘ a’?若是数 50?若是 BCD 数 50 ?•若找到关键字数据则 51H单元存 01H,若不存在则 51H单元存 00H ?•若要求统计关键字数据的个数值存放到 54H单元,若都不存在 54H单元存00H?
【数据检索典型程序例】
作业七 : 编写程序请加详细注释 P.70-8.试编写程序,查找在内部 RAM的 20H~ 40H 单
元中出现“ 00H” 这一数据的次数,并将查找到的结果存入41H 单元。
P.70-9改 在内部 RAM的 21H 单元开始存有一组单字节无符号数,数据长度为 20H ,编写程序,要求找出最小数存入 6AH 单元。
【补充 4-5 】编写程序将 40H、 41H 单元中的两位十进制数的 ASCII 码转换为对应的压缩 BCD 码存放到 4AH 单元中去,其中高位 ( 十位数 ) 的 ASCII 码存放在 40H 单元。
图 11-4
【例 B11-1 】分析如下 8 位D/A驱动程序,请绘出 D/A 输出波形,标明幅度参数,列式精确计算输出波形的周期。设晶体振荡器的频率为 6 MHz 。 机器周期数 START:MOV DPTR,#0DFFFH ( 2 ) LP0:MOV A,#2AH ( 1 ) LP1: ADD A,#01H ( 1 )
MOVX @DPTR, A ( 2 ) CJNE A,#0C8H, LP1 ( 2 ) SJMP LP0 ( 2 ) 计算所产生的锯齿波周期? (6MHz)
T=[1+(1+2+2)× ( C8H-2BH+1 ) +2]×2uS =[5×158+3]×2uS =793×2uS =1586uS
T
C8H
2BH
作业八: 编写程序请加注释【补充 11-1 】分析如下 8 位D/A驱动程序,请绘出 D/A 输出波形,标明幅度参数,列式精确计算输出波形的周期。(设fOSC=6MHZ )
START:MOV DPTR,#7FFFH LP0:MOV A,#0C0H LP1:DEC A
MOVX @DPTR, A CJNE A,#17H, LP1 SJMP LP0
图 11-17MOV A , 00H ; A 值与本次操作无关
MOV DPTR, #07FF8H MOVX @DPTR , A ;写操作实现选择 IN0(~IN7) 且启动转换
•选择通道 0(~通道 7) 且启动转换 :
; 置启动相应输入通道的地址值 7FF8H(~7FFFH)
AT89C51与 ADC0809 的接口
•A/D结束后读取结果数据 : MOVX A , @DPTR
①③
②
0 10~10 1
0
无关!③ ③
(用(用地址总线低地址总线低 33 位位选择通道)选择通道)
③①
P.210
设 fosc=6MHZ ≈1MHZ
≈500kHZ 128uS 一次
地址分析: 0111 1111 1111 1000--7FF8H 选IN0 且启动 · · · · · · · · · · · · · · · · · 0111 1111 1111 1111—7FFFH 选 IN7且启动
MOVX 写:①DPTR送A15~A0② A 送D7~D0③发WR“ ”
【例】对 8 路模拟信号轮流采样一次,采用软件延时的方式,并依次把结果转储到数据存储区 40H起的单元。 MAIN:MOV R1,#40H ; 置数据区首地址 MOV R7,#08H ; 置转换的通道个数
MOV DPTR,#7FF8H ;端口地址初值,指向模拟量输指向模拟量输入通道入通道 IN0IN0 LOOP:MOVX @DPTR, A ;启动当前通道 A/D 转换 (A的值无关 )
MOV R6,#0FH ; 软件延时,等待转换结束(64×2=128uS)DELAY:NOP
NOP NOPDJNZ R6,DELAY ; 延时约 5×15×2uS=150uSMOVX A,@DPTR ; 读取转换结果MOV @R1, A ; 存储转换结果INC DPTR ; 指向下一个模拟量通道 (( 地址低三位决定通道 地址低三位决定通道 ii))INC R1 ; 修改数据区指针DJNZ R7, LOOP ;8 个通道全采样完否?未完则
继续……
P.211
设fosc=6MHZ
•选择通道 0(~通道 7) 且启动转换 :MOV A , 00H MOV DPTR, #07FFFH MOVX @DPTR , A ; 写操作实现选择 IN0(~IN7) 且启动转换
AT89C51与 ADC0809 的接口
•A/D结束后读取结果数据 : MOVX A , @DPTR
①③
②0
③ ③
(用(用数据总线低数据总线低 33 位位选择通道)选择通道)
③
D2D1D0
①
0 10 ~ 10 1
设 fosc=6MHZ ≈1MHZ
≈500kHZ 128uS 一次
; 置选择输入通道 0(~ 7) 的三位码 ,00H(~07H); 置启动 A/D 的地址值
地址分析: 0111 1111 1111 1111--7FFFH 选INi且启动 (i=0~7,由 A 中数据的低三位 000~ 111决定 )
【补充】
MOVX读:①DPTR送A15~A0② A 送D7~D0③发WR“ ”
【例】对 8 路模拟信号轮流采样一次,采用软件延时的方式,并依次把结果转储到数据存储区 40H 开始的单元。 MAIN:MOV R1,#40H ; 置数据区首地址 MOV R7,#08H ; 置转换的通道个数
MOV DPTR,#7FFFFH ; A/DA/D端口地址 端口地址 送DPTR MOV 18H,#00H ;MOV 18H,#00H ; 置初始通道码,指向置初始通道码,指向 IN0IN0 LOOP:MOVMOV A,18H ;A,18H ; 取当前通道码取当前通道码 MOVX @DPTR, A ;启动当前通道 A/D (A(A 的低三位决定的低三位决定通道 通道 ii))
MOV R6,#0FH ; 软件延时 , 等待转换结束(64×2=128uS)DELAY:NOP
NOP NOPDJNZ R6,DELAY ; 延时约 5×15×2uS=150uSMOVX A,@DPTR ; 读取转换结果MOV @R1, A ; 存储转换结果
INC 18H ;INC 18H ; 指向下一个模拟量通道指向下一个模拟量通道INC R1 ; 修改数据区指针DJNZ R7, LOOP ;8 个通道全采样完否?未完
则继续……
设fosc=6MHZ
改用改用数据总线低数据总线低 33 位位选择通道时的程序变更:选择通道时的程序变更: 【补充】
中断方式 将图 11-17 中 EOC脚经一个非门连接到 8031的 INT1*脚即可。转换结束时, EOC发出一个脉冲向单片机提出中断申请,单片机响应中断请求,在中断服务程序读 A/D 结果,并启动 0809 的下一次转换,外中断 1采用下跳沿触发。
P.211
实验板 A/D 接口电路设计实例:
接 P2.2/A10
0 ~5V
+5V
FBF8H→IN0 · · · · · ·FBFFH→IN7
U9 ADC0809
RD
WR
89S51ALE--CLOCK
A0A1A2
地址分析: 1111 1011 1111 1000--FBF8H 选IN0 且启动 · · · · · · · · · · · · · · · · · 1111 1011 1111 1111—FBFFH 选 IN7且启动
0 ~5V
AN0
AN1
fALE≈11.0592MHZ/6≈1.8MHZ >>640KHZ
实验板 A/D驱动子程序:(主流程约每 8mS 调用一次) (灰)
ADSUB:MOV DPTR,#0FBF9H ;A/D子程序 MOVX @DPTR,A ;启动对 IN1的A/D 转换 LCALL D1MS ; 延时等待A/D 转换结束 MOVX A,@DPTR ;读取 A/D 转换结果值 MOV B,A ;A/D 转换结果拆送最左两位的显示缓冲单元 ANL A,#0FH
MOV 36H,A
MOV A,B
ANL A,#0F0H
SWAP A
MOV 37H,A
RET
•如何修改 ADSUB子程序为对 IN0的 A/D转换?•如何修改 ADSUB子程序使得 A/D采集间隔扩展至 0.4S或2S?