1 / 28

4.4 实用程序举例

4.4 实用程序举例. 4.4.1 延时 在程序设计过程中,有时需要程序 “ 等待 ” 一会儿再去处理某些事情,称之为延时。计算机延时实际就是让计算机反复执行一些空操作,这样就能起到拖延时间的作用。需要执行空操作次数的多少,取决于延时时间的长短。. [ 例 4.15 ] 编写一段延时程序。 ORG 2000H ;周期数 × 执行次数 MOV R0 , #MT ; 1×1 DL : NOP ; 1×MT NOP ; 1×MT

kyrie
Download Presentation

4.4 实用程序举例

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 4.4 实用程序举例 • 4.4.1 延时 • 在程序设计过程中,有时需要程序“等待”一会儿再去处理某些事情,称之为延时。计算机延时实际就是让计算机反复执行一些空操作,这样就能起到拖延时间的作用。需要执行空操作次数的多少,取决于延时时间的长短。

  2. [例4.15] 编写一段延时程序。 • ORG 2000H ;周期数×执行次数 • MOV R0,#MT ;1×1 • DL:NOP ;1×MT • NOP ;1×MT • DJNZ R0,DL ;2×MT

  3. 该程序的延时时间与系统所用的晶振和程序中每条指令的机器周期及其执行次数MT有关。设系统晶振为12 MHz,则可知一个机器周期为: • T=1s/(12×106 )×12=1 μs • 延时时间=T×(1×1+1×MT+1×MT+2×MT) • =1 μs×(1+MT+MT+2MT) (4-1)

  4. 图4-6 双重循环延时程序流程图

  5. [例4.16] 用双重循环完成延时程序。 • 程序如下: • MOV R0,#MT1 ;1×1 • DL1:MOV R1,#MT2 ;1×MT1 • DL2:NOP ;1×MT2×MT1 • NOP ;1×MT2×MT1 • DJNZ R1,DL2 ;2×MT2×MT1 • DJNZ R0,DL1 ;2×MT1

  6. 设晶振仍为12 MHz,则上面程序的执行时间T为: • T=1μs×(1+1×MT1+1×MT2×MT1+1×MT2×MT1+2× MT2×MT1+2×MT1) (4-2) • 4.4.2 代码转换 • 1.十六进制到ASCII码的转换 • [例4.17] 将20H单元中的两个十六进制数转换成ASCII码,低4位的ASCII码保存在21H单元,高4位的ASCII码保存在22H单元。 • 由ASCII编码表可知,转换方法为:若十六进制数小于 10,则此数加30H,否则加上37H就可以将十六进制数转换成ASCII码。

  7. MOV A,20H ;(20H)→A • ANL A,0FH ;屏蔽高4位 • ACALL CHANGE ;求低位十六进制数的ASCII码 • MOV 21H,A ;保存低位十六进制数的ASCII码 • MOV A,20H ;(20H)→A • ANL A,#0F0H ;屏蔽低4位 • SWAP A ;高位十六进制数送低4位 • ACALL CHANGE ;求高位十六进制数的ASCII码 • MOV 22H,A ;保存高位十六进制数的ASCII码 • RET

  8. CHANGE: PUSH A ;操作数进栈保护 • CLR C ;进位标志清零 • SUBB A,#0AH ;与10比较 • POP A ;取出操作数 • JC NUM ;比10小转NUM • ADD A,#07H ;大于等于10加37H • NUM: ADD A,#30H ;加30H • RET

  9. 2.单字节二进制数转换为BCD数 • [例4.18] 已知20H单元存放一个二进制数,编程将它转换为BCD数,百位送入FIRST单元的低4位,十位和个位分别送入SECOND单元的高4位和低4位。 • 本题只需将20H单元中的内容除以100,得到的商就是百位BCD数,然后用余数除以10,其结果中,商为十位BCD数,余数为个位BCD数。

  10. ORG 0100H • FIRST DATA 30H • SECOND DATA 31H • MOV A,20H ;被除数送A • MOV B,#64H ;除数100送B • DIV AB ;A除以B • MOV FIRST,A ;百位BCD数送FIRST • MOV A,B ;余数送A

  11. MOV B,#0AH ;除数10送B • DIV AB ;A除以B • SWAP A ;十位BCD数送高4位 • ORL A,B ;十位和个位BCD数组合成一个字节 • MOV SECOND,A ;送入SECOND单元 • SJMP $ ;结束 • END

  12. 4.4.3 数据处理 • 1.查询 • [例4.19] 在外部RAM 1000H开始的地址单元中存放30个数据,找出其中的奇数存入内部RAM 20H开始的存储单元中,并统计奇数的个数,存入3FH单元。 • 用位操作指令对操作数最低位进行判断,若为1即为奇数。本题中,DPTR是片外数据缓冲区地址指针,R0是片内数据缓冲区地址指针。

  13. ORG 0030H • MOV DPTR,#1000H ;指向片外缓冲区首地址 • MOV R0,#20H ;指向片内缓冲区首地址 • MOV R7,#30H ;循环次数送入R7 • MOV 3FH,#00H ;清零 • LP: MOVX A,@DPTR ;取数 • JNB ACC.0,EVEN ;偶数转EVEN • MOV @R0,A ;奇数保存 • INC R0 ;修改片内地址 • INC 3FH ;修改统计个数 • EVEN: INC DPTR ;修改片外地址 • DJNZ R7,LP ;控制循环 • RET

  14. 2.排序 • [例4.20] 将片内RAM 30H开始的连续16个单元的数据按从小到大的顺序排序。 • 此题采用的是冒泡排序法,即对这16个数据组成的数据串,依次将相邻两数分别进行比较,若后面的数小于前面的数,则比较的相邻两数互换,且置位地址单元7FH为1。若这组数据比较完后,相邻两数有交换(即交换标志位7FH为1),则再重新进行两两比较,直到16个数已从小到大排序,相邻两数比较后不再交换为止。交换标志位7FH用来控制是否再需要重新两两比较。程序流程如图4-7所示。

  15. 图4-7 排序程序流程图

  16. 程序如下: • ORG 2000H • SORT: MOV R1,#30H ;指向数据块首地址 • MOV R7,#10H ;数据块长度送R7 • CLR 7FH ;交换标志位清零 • DEC R7 ;块长减1为比较次数

  17. LOOP1:MOV A,@R1;取相邻两数中的前一个数 • MOV 20H,A • INC R1 • MOV A,@R1 ;取相邻两数中的后一个数 • CJNE A,20H,LOOP ;相邻两数比较 • LOOP: JNC NEXT ;前者小于后者转至NEXT • XCH A,20H ;前者大于后者,相邻两数互换 • MOV @R1,A

  18. DEC R1 • MOV @R1,20H • INC R1 ;恢复数据块指针 • SETB 7FH ;置1标志位 • NEXT: DJNZ R7,LOOP1 • ;所有相邻两数未比较完,转至LOOP1 • JB 7FH,SORT ;交换标志位为1,转至SORT • RET

  19. 4.4.4 算术运算 • 1.多字节BCD码加法 • [例4.21] 已知在BLOCK1和BLOCK2为始址的存储区中分别有长度为N字节压缩的BCD码,请编写程序使它们相加并将和送入BLOCK1为始址的存储单元。 • 使用加法指令从低字节相加,因为是BCD码相加,还需用DA指令调整。

  20. ORG 0100H • MOV R7,#N ;数据块长度送R7 • MOV R0,#BLOCK1 ;被加数始址送R0 • MOV R1,#BLOCK2 ;加数始址送R1 • CLR C ;CY清零 • LOOP: MOV A,@R0 ;被加数送A • ADDC A,@R1 ;相加 • DA A ;BCD码调整

  21. MOV @R0。A ;存和 • INC R0 ;修改被加数地址指针 • INC R1 ;修改加数地址指针 • DJNZ R7,LOOP ;未加完,则转至LOOP • JNC RTN ;最高位无进位转至RTN • MOV @R0,#01H ;有进位则保存 • RTN: RET

  22. 2.双字节无符号数乘法运算程序 • [例4.22] 已知在寄存器R4R5和R2R3中分别存放有双字节的被乘数和乘数(R5、R3存放低8位,R4、R2存放高8位),试编程求积并存入BLOCK开始的连续四个存储单元(低字节在前,高字节在后)。 • AT89C51乘法指令只能完成两个8位无符号数相乘,因此16位无符号数求积必须将它们分解成四个8位数相乘来实现,其方法是边乘边加。原理和过程如图4-8所示。

  23. 图4-8 双字节无符号数乘法原理图

  24. 图中ab为16位被乘数,cd为16位乘数(a、c代表高8位,b、d代表低8位),而其后跟H表示乘积后的高8位,跟L表示乘积后的低8位。图中ab为16位被乘数,cd为16位乘数(a、c代表高8位,b、d代表低8位),而其后跟H表示乘积后的高8位,跟L表示乘积后的低8位。 • ORG 1000H • BLOCK EQU 30H • MOV R0,#BLOCK ;指向积单元首址 • MOV A,R5 • MOV B,R3 • MUL AB ;b×d • MOV @R0,A ;保存bdL

  25. MOV A,B • INC R0 • MOV @R0,A ;保存bdH • MOV A,R4 • MOV B,R3 • MUL AB ;a×d • ADD A,@R0 ;bdH+adL • MOV @R0,A • INC R0 • MOV A,B • ADDC A,#00H ;adH+进位

  26. MOV @R0,A • DEC R0 • MOV A,R5 • MOV B,R2 • MUL AB ;b×c • ADD A,@R0 ;bcL与bdh、adL、进位累加 • MOV @R0,A • MOV A,B

  27. INC R0 • ADDC A,@R0 ;bcH与adH、进位累加 • MOV @R0,A • INC R0 • CLR A • ADDC A,#00H • MOV @R0,A ;保存进位 • MOV A,R4

  28. MOV B,R2 • MUL AB ;a×c • DEC R0 • ADD A,@R0 ;acL与adH、bcH、进位累加 • MOV @R0,A • MOV A,B • INC R0 • ADDC A,@R0 ;ac与进位累加 • MOV @R0,A • RET

More Related