470 likes | 667 Views
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
E N D
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 结果: (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
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: 0 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 P.38~40 ←原Cy 【例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.41 【例3-6】(A)=0FH,(R7)=19H,(30H)=00H,(R1)=40H,(40H)=0FFH,执行指令 DEC A ;(A)-1→A = 0EH DEC R7 ;(R7)-1→R7 =18H DEC 30H ;(30H)-1→30H = FFH DEC @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。
【例B3-7】编程序实现R1、R2中的双字节BCD数加上R3、R4中的双字节BCD数,三字节和值存放于R5、R6、R7中。【例B3-7】编程序实现R1、R2中的双字节BCD数加上R3、R4中的双字节BCD数,三字节和值存放于R5、R6、R7中。 ORG 11A0H 11A0 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 ;被加数与加数无第三字节,设其为0 11AA 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)中,前者为高字节,如何编程。
D0 D0 D7 D7 D7 D0 D0 D7 移位指令操作示意图 【例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,#68H MOV R0,#40H PUSH ACC ADD A,#50H MOV @R0,A MOV A,R0 INC R0 MOV @R0,A POP B ORL A,40H 答:A= , R0= , B= , (40H)= , (41H)=
【例】单字节BCD码加法运算 (BCD.ASM) [+46]补 ;单字节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 +2 目标地址 0030 减下一址- 0002 获rel字节002E PC→ +48 执行相对转移:PC ← PC + rel ;∴rel=[目标地址-下一指令址]低8位 目标地址 下一指令址 + 偏移量 0030H ← 0002H + 0046H
P.68 例4-12(改)如果xi均为单字节数,并按i顺序存放在51单片机内部RAM从50H开始的单元中,数据个数n放在R2中,求这批数据的和(双字节)放在R3、R4中,程序如下:(求数组和程序) ORG 0000H ADD1: 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
补充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 2036H 2036 D296 2 SETB P1.6 2038 12203F 3 LOOP:LCALL DELY 203B B296 4 CPL P1.6 203D 80F9 5 SJMP LOOP 203F 7DF5 6 DELY: MOV R5,#0F5H 2041 00 7 DELY2: NOP 2042 00 8 NOP 2043 DDFC 9 DJNZ R5,DELY2 2045 22 10 RET
(INT0-1.ASM) 外部中断应用例: 【例B5-1】外部中断INT0每中断一次令P1.0求反。 实验板INT0按键电路
(INT0-2.ASM) 软件计数改为 5×100×200=100000次 DJNZ 4AH,LR MOV 4AH,#200 DJNZ 49H,LR MOV 49H,#100 【例B5-2】外部中断INT0每中断五次令P1.0求反一次 (要紧接着 DJNZ后重置) MOV 4AH,#200 MOV 49H,#100
(INT0-3.ASM) 【例B5-3】主程序运用软件延时控制P1.7秒闪的同时实现外部中断INT0每中断五次令P1.0求反一次
(INT0-4.ASM) 【例B5-4】上例基础上中断服务子程序具体代码后移的方法
【例B5-2】 INT0每中断1次令50H单元内容加1并且输出到P1口 (INT0-5.ASM) MOV A,50H ADD A,#1 DA A MOV 50H,A 按BCD码加1
【例B4-3】将3AH单元中的压缩BCD码转换为非压缩BCD码分别存放到30H、31H单元中去,其中高位(十位)存放在31H单元。【例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单元。【例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码十位单元 【拆字拼字典型程序例】
CJNE A,49H,LP SJMP LP1 ;相等 LP:JNC LP1 ;甲>乙 【例B4-1】请编程序使48H、49H单元所存储的二个数中较大者 在前。 ORG 0000H BIG:MOV A ,48H ;取甲 CLR C ;清Cy SUBB A ,49H ;减去乙数 JNC LP1 ;无借位则甲≥乙,转LP1 MOV A ,48H ;乙数大:两数交换 MOV 48,49H MOV 49H,A LP1:SJMP $;自循环 【练习】 • 请编程序使48H、49H单元所存储的二个数中较小者送28H单元。 • 请编程序判断若34H、35H单元所存储的二个数相等则置F0位为0,否则置1。
P.69 多重循环程序:最常见的多重循环是软件延时程序。 例4-1450ms延时程序。 使用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 ① ② ③ ④ ⑤
【计算程序运行时间例】 ;实现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,#3CH NOP DL:MOV R6,#0F8H NOP DJNZ R6,$ DEC R7 DJNZ R7,DL RET
P.134 【例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 ;执行完毕,原地踏步 4FA0H EBH MOV A,#0D6H 如果改为对4FA0H~508AH单元写数据D6H ,如上更改。
P.134 例8-1编写程序将片外数据存储器中5000H~50FFH单元全部清零 方法2: 用DPTR作为数据区地址指针,但不使用字节计数器,而是比较特征地址。 (条件控制循环) MOV DPTR,#5000H;设置数据块指针的初值 CLR A;A置写数据00H LOOP:MOVX @DPTR,A;把当前单元清零 INC DPTR;地址指针加1 MOV R7,DPL;取新地址值低字节 CJNE R7,# 0 ,LOOP;与末地址+1的低字节比较,未完继续 HERE:SJMP HERE 4FA0H MOV A,#0D6H 8BH 如果改为对4FA0H~508AH单元写数据D6H ,如上更改。
ORG 0000H 0000 02 0030 LJMP START 0003 0030 ORG 0030H 0030 78 30 START:MOV R0,#30H ;R0指向源数据区首地址 0032 79 50 MOV R1,#50H ;R1指向目标数据区首地址 0034 7F 0C MOV R7,#12 ;置循环计数初值12 0036 E6 LOOP:MOV A,@R0 ;取当前源数据 0037 04 INC A ;加1 0038 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 【数据块传送程序例】 【例B4-2】有一组数据,存放在30H为首地址的内存单元,数据长度为12个。试将每一个数取出加1,依序存放到以50H为首地址的单元中。 • 若题中说明数据个数n存放在2FH单元中? • 若要求的是个数据取出按BCD码加1后传送? • 若要求的是数据原样传送? • 若要求的是依序传送到58H之前的内存单元中? • 若要求的是与片外数据存储器之间进行数据块传送?
作业五 : P.140 — 4. 6. 7. 8. 11. 13. (对每个答案仔细思考为什么) 补充4-4:编写完整的应用程序,将片外数据存储器2A01H开始的24个单字节数据依次传送到片内32H开始的单元中。 补充8-1:请列出详细的地址分析过程,求出下列存储器片选译码电路各输出端所对应的地址区域。
P.87-88 TM TOSC 溢出中断 标志 (12MHZ) (1uS) 计数溢出 +1 6.2.2 方式1——16位计数方式 16位可预置加1计数器 ‘1’接通 计数初值 可计数 可定时 0000H 65536次 65536TM 0001H 65535次 65535TM ············ FFFFH 1次 1TM 图6-5 • 12MHZ时最长可定时 65536uS • 11.0592MHZ时最长可定时约71111uS 6.4.1 方式1应用 【例6-1】假设系统时钟频率采用6MHz,要在P1.0上输出一个周期为2ms的方波,即500Hz方波,如图6-13所示。 P.86 500×2uS 每1mS令P1.0求反一次即可 图6-13
【例6-1】 [题意:Fosc=6MHz] P.91 ORG 0000H RESET: AJMP MAIN ;转主程序 ORG 000BH ;T0的中断入口 AJMP IT0P ;转T0中断处理程序IT0P ORG 0100H MAIN: 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 ;中断返回 • 若改TMOD赋值05H,则实现:对T0引脚每计满500个脉冲令P1.0求反一次 • 若改计数初值为65536-250=65286=FF06H 则实现:P1.0输出1000HZ方波
P.88 TM TOSC 溢出中断 标志 8位可预置加1计数器 (12MHZ) (1uS) 计数溢出 +1 6.2.3 方式2 ——8位计数自动重装工作方式 自动 ‘1’接通 计数初值 可计数 可定时 00H 256次 256TM 01H 255次 255TM ········· FFH 1次 1TM 自动重装初值寄存器 图6-6 • 12MHZ时最长可定时256uS • 11.0592MHZ时最长可定时约277.7uS 【例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)程序设计 借上例程序框架改造如下页:
【例B6-1】改例6-1为T0定时方式2实现P1.0输出1000HZ方波【例B6-1】改例6-1为T0定时方式2实现P1.0输出1000HZ方波 [题意:Fosc=6MHz] ORG 0000H RESET: AJMP MAIN ;转主程序 ORG 000BH ;T0的中断入口 AJMP IT0P ;转T0中断处理程序IT0P ORG 0100H MAIN: 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 ;中断返回
【例B6-2】扩展例B6-1的定时时间为P1.0输出1HZ方波【例B6-2】扩展例B6-1的定时时间为P1.0输出1HZ方波 ORG 0000H RESET: AJMP MAIN ;转主程序 ORG 000BH ;T0的中断入口 AJMP IT0P ;转T0中断处理程序IT0P ORG 0100H MAIN: 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,58H CJNE A,#0AH,LR MOV 58H,#00H MOV A,59H ADD A,#01H ;BCD加1 DA A MOV 59H,A CJNE A,#00H,LR MOV 59H,#00H
P.94 【例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 MAIN ORG 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.62 4.3.4 数据极值查找程序设计 在指定的无序数据区中找出最大值(或最小值)。 逐个进行数值大小的比较,记存下暂时较大(小)的数,最终从这批数据中找出最大值(或最小值)并存于某一单元中。 • 不带符号数比较大小根据相减后Cy标志位判定 • 补码表示的带符号数比较大小根据相减后差的符号位及OV标志位判定 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
【例B4-4】以2042H为首地址的存储单元中,连续存放一组单字节无符号数,数据个数存于2041H单元,从中找出最大数并存于2040H。【例B4-4】以2042H为首地址的存储单元中,连续存放一组单字节无符号数,数据个数存于2041H单元,从中找出最大数并存于2040H。 【求极值典型程序例】 循环 次数 循环 准备 0100 ORG 0100H 0100 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,#2040H 0119 E5 30 MOVA,30H 011B F0 MOVX @DPTR,A;存最大值结果 011C 80 FE SJMP $ 010E END P.70—9习题分析(改求最小数存6AH单元) 地址指针→ 数据初值→ 循环体 相等的处理 小于→ 大于→ 为下循环准备→ 循环控制→ 结果处理 • 找最小值? • 对片内单元数据?
P.61 4.3.3 关键字查找程序设计 顺序检索和对分检索 1. 顺序检索 从第1项开始逐项顺序查找,判断所取数据是否与关键字相等。 • 找到与关键字相等的数据则进行……处理,继续或结束检索; • 全部数据扫描完从未发现与关键字相等的数据则进行……处理。
【例B4-5】从30H开始的20个字节的无序表中查找一个关键字如4AH,若有则将其所在单元地址存R3,若不存在则R3置0。【例B4-5】从30H开始的20个字节的无序表中查找一个关键字如4AH,若有则将其所在单元地址存R3,若不存在则R3置0。 ORG 0200H JS: 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?
【数据表可在64K内任一处】 (x+ TAB) 【省用DPTR,数据表应随后】 (x+TAB-NEXTPC + PC)=(x+TAB) 相等
作业七:编写程序请加详细注释 P.70-8.试编写程序,查找在内部RAM的20H~40H单元中出现“00H”这一数据的次数,并将查找到的结果存入41H单元。 P.70-9改 在内部RAM的21H单元开始存有一组单字节无符号数,数据长度为20H,编写程序,要求找出最小数存入6AH单元。 【补充4-5】编写程序将40H、41H单元中的两位十进制数的ASCII码转换为对应的压缩BCD码存放到4AH单元中去,其中高位(十位数)的ASCII码存放在40H单元。
【例B11-1】分析如下8位D/A驱动程序,请绘出D/A输出波形,【例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 C8H 2BH T 图11-4
作业八:编写程序请加注释 【补充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
P.210 AT89C51与ADC0809的接口 (用地址总线低3位选择通道) ≈500kHZ 128uS一次 设fosc=6MHZ ≈1MHZ 01 0~1 01 MOVX写: ①DPTR送A15~A0②A送D7~D0 ③发WR“” ② 无关! ③ ③ ① 0 ③ ③ ① • 选择通道0(~通道7)且启动转换: 图11-17 MOV A , 00H ;A值与本次操作无关 MOV DPTR, #07FF8H MOVX @DPTR , A ;写操作实现选择IN0(~IN7)且启动转换 ;置启动相应输入通道的地址值7FF8H(~7FFFH) • A/D结束后读取结果数据: • MOVX A , @DPTR 地址分析:0111 1111 1111 1000--7FF8H 选IN0且启动 ················· 0111 1111 1111 1111—7FFFH 选IN7且启动
P.211 【例】对8路模拟信号轮流采样一次,采用软件延时的方式,并依次把结果转储到数据存储区40H起的单元。 设fosc=6MHZ MAIN:MOV R1,#40H ;置数据区首地址 MOV R7,#08H ;置转换的通道个数 MOV DPTR,#7FF8H ;端口地址初值,指向模拟量输入通道IN0 LOOP:MOVX @DPTR,A ;启动当前通道A/D转换(A的值无关) MOV R6,#0FH ;软件延时,等待转换结束(64×2=128uS) DELAY:NOP NOP NOP DJNZ R6,DELAY ;延时约5×15×2uS=150uS MOVX A,@DPTR ;读取转换结果 MOV @R1,A ;存储转换结果 INC DPTR ;指向下一个模拟量通道(地址低三位决定通道 i) INC R1 ;修改数据区指针 DJNZ R7,LOOP ;8个通道全采样完否?未完则继续 ……
【补充】 AT89C51与ADC0809的接口 (用数据总线低3位选择通道) ≈500kHZ 128uS一次 设fosc=6MHZ ≈1MHZ 01 0~ 1 01 D2 D1 D0 MOVX读: ①DPTR送A15~A0②A送D7~D0 ③发WR“” ② ③ ③ ① 0 ③ ③ ① • 选择通道0(~通道7)且启动转换: MOV A , 00H MOV DPTR, #07FFFH MOVX @DPTR , A;写操作实现选择IN0(~IN7)且启动转换 ;置选择输入通道0(~7)的三位码,00H(~07H) ;置启动A/D的地址值 • A/D结束后读取结果数据: • MOVX A , @DPTR 地址分析:0111 1111 1111 1111--7FFFH 选INi且启动 (i=0~7,由A中数据的低三位000~111决定)
改用数据总线低3位选择通道时的程序变更: 【补充】 【例】对8路模拟信号轮流采样一次,采用软件延时的方式,并依次把结果转储到数据存储区40H开始的单元。 设fosc=6MHZ MAIN:MOV R1,#40H ;置数据区首地址 MOV R7,#08H ;置转换的通道个数 MOV DPTR,#7FFFH ; A/D端口地址 送DPTR MOV 18H,#00H ;置初始通道码,指向IN0 LOOP:MOVA,18H ;取当前通道码 MOVX @DPTR,A ;启动当前通道A/D(A的低三位决定通道 i) MOV R6,#0FH ;软件延时,等待转换结束(64×2=128uS) DELAY:NOP NOP NOP DJNZ R6,DELAY ;延时约5×15×2uS=150uS MOVX A,@DPTR ;读取转换结果 MOV @R1,A ;存储转换结果 INC 18H ;指向下一个模拟量通道 INC R1 ;修改数据区指针 DJNZ R7,LOOP ;8个通道全采样完否?未完则继续 ……
P.211 中断方式 将图11-17中EOC脚经一个非门连接到8031的INT1*脚即可。转换结束时,EOC发出一个脉冲向单片机提出中断申请,单片机响应中断请求,在中断服务程序读A/D结果,并启动0809的下一次转换,外中断1采用下跳沿触发。
实验板A/D接口电路设计实例: U9 ADC0809 AN0 0~5V AN1 FBF8H→IN0 · · ·· ·· FBFFH→IN7 0~5V RD A0 A1 A2 接P2.2/A10 WR 89S51ALE--CLOCK +5V fALE≈11.0592MHZ/6≈1.8MHZ>>640KHZ 地址分析:1111 1011 1111 1000--FBF8H 选IN0且启动 ················· 1111 1011 1111 1111—FBFFH 选IN7且启动
实验板A/D驱动子程序:(主流程约每8mS调用一次) (灰) ADSUB:MOVDPTR,#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 D2 A1 D1 A0 D0