【 例 3-1】 ( a ) =53h , ( r0 ) =fch ,执行指令 add a,r0 结果 : ( a ) =4fh , cy=1...

47
例 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.3 8 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

Upload: ashtyn

Post on 11-Jan-2016

348 views

Category:

Documents


5 download

DESCRIPTION

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. 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. Cy: 1. P.38. 【 例 3-1】 ( A ) =53H , ( R0 ) =FCH ,执行指令 ADD A,R0 - PowerPoint PPT Presentation

TRANSCRIPT

【例 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-1】外部中断 INT0每中断一次令 P1.0求反。

(INT0-1.ASM )

实验板 INT0 按键电路

【例 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-3 】主程序运用软件延时控制 P1.7 秒闪的同时实现外部中断 INT0每中断五次令 P1.0求反一次

(INT0-3.ASM )

【例 B5-4 】上例基础上中断服务子程序具体代码后移的方法

(INT0-4.ASM )

【例 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?

【数据检索典型程序例】

相等

(x+ TAB)

(x+TAB-NEXTPC + PC)=(x+TAB)

【数据表可在 64K内任一处】

【省用 DPTR,数据表应随后】

作业七 : 编写程序请加详细注释 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?

【补充 11-2 】设 AT89C51 单片机与 ADC0809 的连接如下图,其中 ADC0809的 C 、 B 、 A 有接到 A2、 A1、 A0与接到 D2、D1、D0 两种方案,请测算该电路一次 A/D 转换的时间,针对两种方案分别编写程序段实现:启动对 IN6 输入的模拟量的 A/D 转换,待 A/D 转换结束后读取 A/D 转换结果数据并存入 6AH 单元。 ( 调用的软件延时子程序可略,但须在注释说明延时时间,设 fOSC=6MHZ)

A2 D2A1 D1A0 D0

作业八(续)