1 / 41

2-4 汇编语言程序设计方法(二)

2-4 汇编语言程序设计方法(二). 单片机常见汇编语言程序设计举例: 数制转换程序 算术和逻辑运算类程序设计 查表程序设计 子程序设计 定时程序. ·. ·. ·. ·. ·. ·. ·. ·. ·. B. A. 22H. 21H. 20H. 1 、数制转换. 例 1 : 将 20H 单元的两个压缩 BCD 码拆开变成 ASCII 码,存入 21H 、 22H 单元。 ( 假设 20H 中的 BCD 码为 00110100). 什么是 BCD 码? 什么是 ASII 码?. 高四位 ASII 码. 0011. 低四位 ASII 码.

afya
Download Presentation

2-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. 2-4 汇编语言程序设计方法(二) • 单片机常见汇编语言程序设计举例: • 数制转换程序 • 算术和逻辑运算类程序设计 • 查表程序设计 • 子程序设计 • 定时程序

  2. · · · · · · · · · B A 22H 21H 20H 1、数制转换 • 例1:将20H单元的两个压缩BCD码拆开变成ASCII码,存入21H、22H单元。(假设20H中的BCD码为00110100) 什么是BCD码? 什么是ASII码? 高四位ASII码 0011 低四位ASII码 0011 压缩BCD码 0011 0100

  3. 方法1:将BCD码除以10H,恰好是将BCD码分别移到了A、B的低4位。然后再各自与30H相或,即成为ASCII码。方法1:将BCD码除以10H,恰好是将BCD码分别移到了A、B的低4位。然后再各自与30H相或,即成为ASCII码。 方法2:利用半字节交换指令来实现。

  4. 开始 · · · (20H)A · · · · · · 10HB A/B (A中为高4位BCD码,B中为低4位BCD码) PC PC PC PC PC PC PC PC B B+30HB A B(22H) 22H A+30HA 21H A(21H) 20H 结束 数制转换程序1---方法1 ORG 0000H MOV A,20H MOV B,#10H DIV AB ORL B,#30H MOV 21H,B ORL A,#30H MOV 22H,A SJMP $ END 源程序如下: 0001 0000 0000 0100 0011 0100 0011 0000 0011 0011 0011 0100 0100

  5. 开始 #20HR0 · · · · · · #30HA · · · A的低4位(20H)的低4位 A PC PC PC PC PC PC PC PC PC PC A(21H) (20H)A 22H 21H A的低4位A的高4位 20H A+30HA R0 A(22H) 结束 简单程序例1---方法2 ORG 0000H MOV R0,#20H MOV A,#30H XCHD A,@R0 MOV 21H,A MOV A,@R0 SWAP A ANL A, #0FH ORL A , #30H MOV 22H, A SJMP $ END 源程序如下: 0011 0011 0011 0011 0000 0100 0100 0000 0011 0011 0011 0100 0000 0010 0000

  6. 解题思路: (40H) 16 商为二进制的高四位 余为二进制的低四位 余数 将高四位乘以0AH,再加上低四位即可。 • BCD码十进制转换成二进制 • 例:假如在内部RAM40H单元中存储有一个压缩BCD编码的两位十进制数,设计一段程序把这个数转换成二进制数并存入41H单元中。

  7. 程序清单 • ORG 0000H • MOV A,40H • MOV B,#16 • DIV AB • MOV 20H,B • MOV B,#0AH • MUL AB • ADD A,20H • MOV 41H,A • SJMP $ • END 取出30H数据除以16,商A,余B 将十位数乘以0AH,其结果不会超过一个字节,在A中 将十位数的二进制数加上个位数,结果41H

  8. 算术和逻辑运算类程序设计 • 多字节BCD码十进制数相加例:假如在MCS-51单片机内部RAM中30H~37H单元、 38H~3FH单元分别存放有两个8字节BCD码十进制数,设计一段程序将这两个数相加,并把结果存于2FH~37H单元中,小地址存数据的高字节。 • 解题思路:先清Cy位,把(37H)和(3FH)进行带Cy相加,在进行十进制调整,结果存于37H单元中;把(36H)和(3EH)进行带Cy相加,在进行十进制调整……循环至结束,结果把最高字节的Cy存入2FH单元。

  9. 开始 R037H(被加数首地址) R13FH(加数首地址) R208H(循环次数) 清Cy位 加数和被加数 相加,十进制 调整,并回存 调整数据指针 R0(R0)-1 R1(R1)-1 N (R2)-1=0? Y Cy存入2FH单元 结束 流程与程序清单 设定循环次数,R0和R1分别指向加数和被加数的首地址 • ORG 0000H • MOV R2,#08H • MOV R0,#37H • MOV R1,#3FH • CLR C • LOP:MOV A,@R0 • ADDC A,@R1 • DA A • MOV @R0,A • DEC R0 • DEC R1 • DJNZ R2,LOP • CLR A • RLC A • MOV 2FH,A • SJMP $ • END 相加,并回存结果 R0和R1分别指向加数和被加数的下一地址,判断循环次数 存进位标志

  10. 极值查找程序 • 例:在MCS-51单片机内部RAM的40H-47H单元中存有8个无符号数,设计一段程序找出其中的最大值,并存放到48H单元中。 • 这是一个求最大值的问题。 • 解题思路:先把(A)(40H),然后将(41H)和(A)进行比较,如果(41H)>(A),则(A)(41H),然后和下一个字节进行比较,依次类推,最后(A)必定是最大值。

  11. 开始 R040H(数据区首地址) R207H(循环次数) A((R0))(取第一个数) R0(R0)+1(指向下一个数) B ((R0)) Y A≥B? N A (B) N (R2)-1=0? Y 48H(A) 结束 • ORG 0000H • MOV R2,#07H • MOV R0,#40H • MOV A,@R0 • LOOP:INC R0 • MOV B,@R0 • CJNE A,B,NEX • NEX: JNC NET • MOV A,B • NET: DJNZ R2,LOOP • MOV 48H,A • SJMP $ • END 设定循环次数R1,R0作为数据指针,指向数据区第一个字节 取出下一个字节,存入B 如果(A)<(B), 则(A)(B) 次数到否,到则取出(A)48H

  12. 排序程序 程序名 :BUBBLE 功能 :将片内RAM数据块由大到小排序 入口参数:R0指向数据块首地址,R2存放数据块长度 出口参数:仍存放原来位置 占用资源:R0,R1,R2,R3,R5,A,PSW;00H位

  13. BUB2:DEC R1 MOV @R1,A INC R1 MOV A,@R1 DJNZ R5,BUB1 MOV A,R0 MOV R1,A MOV A,R2 MOV R5,A JB 00H,BUBB1 RET • BUBBLLE:MOV A,R0 • MOV R1,A • MOV A,R2 • MOV R5,A • BUBB1: CLR 00H • DEC R5 • MOV A,@R1 • BUB1: INC R1 • MOV B,@R1 • CJNE A,B,BUB0 • BUB0: JNC BUB2 • SETB 00H • XCH A,@R1

  14. 键控移位例:有一电路如图所示,设计一个程序实现以下功能:SW按下第1次,VD1发光;SW按下第2次,VD1、VD2发光; SW按下第3次,VD1、VD2、VD3发光…… SW按下第7次,VD1—VD7发光; SW按下第8次,VD1发光; SW按下第9次,VD1、VD2发光……依次轮回。 • 解题思路:本例涉及到查询按键按下的过程,SW没有按下时P2.0为高电平,按下为低电平。实际应该查询的是P2.0的下降沿, P2.0有一个下降沿,表明有一个按键按下,LED的状态应该改变一次。

  15. 初态 次态 程序清单 • SW BIT P2.0 • ORG 0000H • LOOP0: SETB SW • MOV A,#01H • MOV R7,#07H • LOOP1: MOV C,SW • MOV R6,#255 • DELAY: NOP • NOP • DJNZ R6,DELAY • ANL C,/SW • JNC LOOP1 • RLC A • ORL A,#01H • MOV P2,A • DJNZ R7,LOOP1 • SJMP LOOP0 • END 置P2.0为输入方式,确定循环次数为7 延时消抖 判断是否有下降沿,有则移位,否则继续查询 显示输出,如果循环次数到则重新开始

  16. 数据排序程序 • 例:将片内RAM中20H-27H中的数据按照从小到大的顺序重新排列。 • 解题思路:见下图

  17. R1←20H , R0 ←(R1)+1 R3 ←08H B←((R1)) ,R2 ←(R3)-1 查找最小值并和(R1)单元互换 R1 ←(R1)+1 N R3-1=0? Y END 程序流程:

  18. 程序清单:ORG 0000H • MOV R1, #20H • MOV R3, #08H LOOP1: MOV A, R1 ;R0←(R1)+1 INC A MOV R0, A MOV A, R3 ; R2←(R3)-1 DEC A MOV R2, A MOV B, @R1 LOOP: MOV A, @R0 CJNE A, B, MM MM: JNC SS ;如果A≥B跳转 MOV B, A MOV 28H, R0 ;28h纪录最小值所在单元的编号 SS: INC R0 DJNZ R2, LOOP MOV R0, 28H ;最小值单元和20H单元内容互换 MOV A, @R1 ;数据 MOV @R0, A MOV @R1, B INC R1 DJNZ R3, LOOP1 END

  19. 查表程序设计 • 程序使用的专用指令:MOVC A, @A+PC MOVC A, @A+DPTR • 一般情况下, 常使用后者 • 程序设计一般规则: • 先确定表格存放的位置 • 在表格中填入相应的数据 • 查表时先将表格的首地址给DPTR,再将要查表的数据送给A,最后用MOVC A, @A+DPTR

  20. 例1:假如在MCS-51单片机内部RAM中40H单元内存放的是一个角度(范围0- 90),设计一段程序,计算出200sin(),把结果存入41H单元中(结果只取整数)。 • 解题思路:先建立一个相应的数值表格,定义在程序存储器中,利用输入的值进行查表。 • 例程:ORG 0000HMOV DPTR,#TABLE MOV A,40H MOVC A,@A+DPTR MOV 41H,A SJMP $TABLE:DB 0,3,7,10,14,17,21,24,28,31,35,38 DB 41,45,48…199,200,200END 表格的数据是怎么计算出来的? 查表 表格内容

  21. 例2:假如在MCS-51单片机内部RAM中40H单元内存放的是一个参数x(范围0-10),设计一段程序,计算出5x3+4x2+3x+1,把结果存入41H和42H单元中(高位在前)。例2:假如在MCS-51单片机内部RAM中40H单元内存放的是一个参数x(范围0-10),设计一段程序,计算出5x3+4x2+3x+1,把结果存入41H和42H单元中(高位在前)。 • 解题思路:先建立一个相应的数值表格(每个为2个字节),定义在程序存储器中,利用输入的值进行查表。 • 例程: ORG 0000H MOV DPTR,#TABLE MOV A,40H CLR C • RLC A;A*2-->A • PUSH ACC MOVC A,@A+DPTR MOV 41H,A POP ACC INC A MOVC A,@A+DPTR MOV 42H,A SJMP $TABLE: DW 0001H,000DH,003FH,00B5H,018DH DW 02D1H,04DBH,078DH,0B19H,0F9DH,1537H END 查表,得到高两位数 查表,得到低两位数 表格内容

  22. 4.子程序设计 • 在实际问题中,常常会遇到在一个程序中多次用到相同的运算或操作,若每遇到这些运算或操作,都从头编起,将使程序繁琐、浪费内存。因此在实际中,经常把这种多次使用的程序段,按一定结构编好,存放在存储器中,当需要时,可以调用这些独立的程序段。通常将这种可以被调用的程序段称为子程序。 主要内容: 1. 主程序与子程序的关系 2. 子程序嵌套 3. 子程序的调用与返回

  23. 子程序SUB  主程序与子程序的关系 子程序入口地址 主程序MAIN 调用子程序 LCALL SUB  RET 返回

  24. 开始 送显示初值 设闪烁次数 点亮相应的LED 延时 熄灭相应的LED 延时 N 次数-1=0 Y 初值左移1位 指向下一个LED 实例:LED灯的闪烁点亮(一) ORG 0000H MAIN: MOV A,#0FEH ;送显示初值 LP: MOV R0,#10 ;送闪烁次数 LP0: MOV P1,A ;点亮LED LCALL DELAY ;延时 MOV P1,#0FFH;熄灭灯 LCALL DELAY ;延时 DJNZ R0,LP0 RL A SJMP LP END

  25. 子程序嵌套 子程序嵌套(或称多重转子)是指在子程序执行过程中,还可以调用另一个子程序。 主程序MAIN 子程序SUB1 子程序SUB2   LCALL SUB1 LCALL SUB2    RET RET

  26. ORG 0000H MAIN: MOV A,#0FEH ;送显示初值 COUN: ACALL FLASH ;调闪烁子程序 RL A ;A左移,下一个灯闪烁 SJMP COUN ;循环不止 FLASH: MOV R0,#10 ;送闪烁次数 FLASH1: MOV P1,A ;点亮LED LCALL DELAY ;延时 MOV P1,#0FFH ;熄灭灯 LCALL DELAY ;延时 DJNZ R0,FLASH1 ;闪烁次数不够10次,继续 RET DELAY: MOV R3,#0FFH ;延时子程序 DEL2: MOV R4,#0FFH DEL1: NOP DJNZ R4,DEL1 DJNZ R3,DEL2 RET END 子程序嵌套范例:LED灯闪烁(二)

  27. 子程序的调用与返回 问题:子程序调用、返回到主程序中的正确位置,并接著执行主程序中的后续指令呢? 为了解决这个问题,我们采用了堆栈技术。 PC 20 13 21 13 20 13 21 13 主程序MAIN 子程序SUB1 子程序SUB2  2100 2200   21 2010 2110 LCALL SUB1 13 LCALL SUB2  2013 2113 20 13   RET RET 堆栈指针SP 堆栈

  28. 子程序设计注意事项 (1)要给每个子程序起一个名字,也就是入口地址的代号。 (2)要能正确地传递参数。即首先要有入口条件,说明进入子程序时,它所要处理的数据放在何处(如:是放在A中还是放在某个工作寄存器中等)。另外,要有出口条件,即处理的结果存放在何处。 (3)注意保护现场和恢复现场。在子程序使用累加器、工作寄存器等资源时,要先将其原来的内容保存起来,即保护现场。当子程序执行完毕,在返回主程序之前,要将这些内容再取出,送还到累加器、工作寄存器等原单元中,这一过程称为恢复现场。 例4.11 查表子程序。 注意:1.入口参数和出口参数的位置 2.现场的保护与恢复。 

  29. 子程序的参数传递 范例:计算平方和c=a2+b2 ORG 0000H ;主程序 MOV SP,#3FH ;设置栈底 MOV A,31H ;取数a存放到累加器A中作为入口参数 LCALL SQR ;计算a2 MOV R1,A ;出口参数——平方值存放在A中 MOV A,32H ;取数b存放到累加器A中作为出口参数 LCALL SQR ;计算b2 ADD A,R1 ;求和 MOV 33H,A ;存放结果 SJMP $

  30. ;子程序:SQR ;功能:通过查表求出平方值y=x2 ;入口参数:x存放在累加器A中 ;出口参数:求得的平方值y存放在A中 ;占用资源:累加器A,数据指针DPTR SQR:USH DPH ;保护现场,将主程序中DPTR的高八位放入堆栈 PUSH DPL ;保护现场,将主程序中DPTR的低八位放入堆栈 MOV DPTR,#TABLE ;在子程序中重新使用DPTR,表首地址→DPTR MOVC A, @A+DPTR ;查表 POP DPL ;恢复现场,将主程序中DPTR的低八位从堆栈中弹出 POP DPH ;恢复现场,将主程序中DPTR的高八位从堆栈中弹出 RET TABLE: DB 0,1,4,9,16,25,36,49,64,81

  31. 例:假如在MCS-51单片机外部RAM中00H—07H单元中依次存放有8个无符号数Xi(i为0-7),设计一段程序计算出Yi=Xi2,并把结果存于外部RAM 10H开始的16个单元中( Yi占用两个字节,高位在前);再计算Zi=Xi÷2,并把Zi依次存放在Xi所在的单元。 • 解题思路:在本例中,Yi=Xi2和Zi=Xi÷2都比较复杂,我们可以分别使用子程序。 • 程序清单: ORG 0000H • MOV R0,#00H • MOV R1,#10H • MOV R2,#08H • LOOP: MOVX A,@R0 • LCALL DIVIDE • LCALL SQUARE • MOVX @R1,B • INC R1 • MOVX @R1,A • DJNZ R2,LOOP • SJMP $ • END R0和R1作为数据指针,R2为循环次数。 传递参数,调用运算子程序 存放结果

  32. Zi=Xi÷2运算子程序 • DIVIDE:PUSH ACC • CLR C • RRC A • MOVX @R0,A • POP ACC • RET • SQUARE:MOV B,A • MUL AB • RET • END Yi=Xi2运算子程序

  33. 定时程序 • 单重循环延时 • 例1:假设单片机的fosc=12MHz,计算单片机执行下面程序消耗的时间。 • DELAY: MOV R5,#TIME ;1机器周期 • MM: NOP ;1机器周期 • DJNZ R5,MM ;2机器周期 • RET ;2机器周期 • 执行完以上4条语句,所花时间: • T=(1+(1+2)×TIME)+2 ×1s • 推广计算式: • T(机器周期数)=(循环体机器周期数) ×循环次数+初始化机器周期数

  34. 多重循环延时 • 例1:假设单片机的fosc=12MHz,计算单片机执行下面程序消耗的时间。 • DELAY2: MOV R3,#TIME1 ;1机器周期 • LOOP1: MOV R2,#TIME2 ;1机器周期 • LOOP2: NOP ;1机器周期 • DJNZ R2,LOOP2 ;2机器周期 • DJNZ R3,LOOP1 ;2机器周期 • RET ;2机器周期 • 执行完以上6条语句,所花时间: • T=(1+(1+(1+2)×TIME2+2)×TIME1 +2) ×1s

  35. ORG 000H LJMP MAIN ORG 100H MAIN: ;;给片内RAM30H单元开始的16个单元赋值。 MOV R0,#30H MOV R1,#(table1-table) MOV DPTR,#TABLE LOP: CLR A MOVC A,@A+DPTR MOV @R0,A INC R0 INC DPTR DJNZ R1,LOP ;;查找片内RAM30H单元开始的16个单元的最小值,并存于B寄存器。 MOV R0,#30H MOV R1,#(table1-table) MOV B,#0FFH LOP0: MOV A,@R0 CJNE A,B,$+3 JNC LOP1 MOV B,@R0 LOP1: INC R0 DJNZ R1,LOP0 ;;读出片内RAM30H单元开始的16个单元的内容,并和最小值比较,相等则把该单元的值替换成0ffh. MOV R0,#30H MOV R1,#(table1-table) LOP2: MOV A,@R0 CJNE A,B,LOP3 MOV @R0,#0FFH LOP3: INC R0 DJNZ R1,LOP2 SJMP $ TABLE: DB 10H,25H,2H,00H,12H,33H,45H,00H,78H DB 80H,0AAH,0BBH,12H,23H,34H,00H TABLE1: END 习题选讲 例1. 设计一段程序实现如下功能:找出从片内RAM30h开始的16个单元中最小值所在的单元,并将该单元的值替换成0ffh。(最小单元可能不止一个)

  36. 习题选讲 例2. 设计一段程序实现逻辑运算:P1.7=P1.6(P1.5⊙P1.4) 分析:在位逻辑运算指令中只有 ANL 、ORL、CPL 指令,没有XRL(异或)和同或指令,所以对上述表达式进行等效转换后为: P1.7=P1.6*(P1.5*P1.4+/P1.5*/P1.4) ORG 0000h LJMP START ORG 50h START: MOV C,P1.4 CPL C ANL C,/P1.5 ;C=/P1.4*/P1.5 MOV F0,C ;F0=C=/P1.4*/P1.5 MOV C,P1.4 ANL C,P1.5 ;C=P1.4*P1.5 ORL C,F0 ;C=C+F0=P1.4*P1.5+/P1.4*/P1.5= P1.5⊙P1.4 ANL C,P1.6 ;C=P1.6*(P1.5⊙P1.4) MOV P1.7,C ;P1.7=C=P1.6*(P1.5⊙P1.4) SJMP $ END

  37. 习题选讲 例3. 参照下图设计一个彩灯控制程序,让8个led按照自己的设想发光,显示的样式尽可能的丰富。

  38. 工作原理 当P1。0~P1。7中的某端口为高电平时,对应的发光二极管亮,为低电平灭。我们只要控制P1口各位的电平状态,就可以控制8只LED的亮与灭。 例如使(P1)=01010101B=55H,D7、D5、D3、D14只LED灭,D6、D4、D2、D04只LED亮,从效果上看亮与灭是相间隔的;反之,使(P1)=10101010B=AAH,则另外4只LED亮,若反复以一定时间间隔不断从P1口轮流输出55H和AAH,则P1口上8只LED会呈现流水彩灯的效果。

  39. 开始 55H送P1口 延时0.3秒 AAH送P1口 流水式彩灯程序流程图 延时0.3秒 ORG 0000H LOOP: MOV P1,#55H ;将立即数55H送P1端口 LCALL TIME ;调延时子程序TIME MOV P1,#0AAH ;将立即数AAH送P1端口 LCALL TIME ;调延时子程序TIME SJMP LOOP ;转移到LOOP TIME: MOV R6,#200 ;延时子程序TIME TIME1:MOV R7,#200 TIME2:NOP NOP NOP DJNZ R7,TIME2 DJNZ R6,TIME1 RET END

  40. 4)开幕式与闭幕式彩灯程序 ORG 0000H LJMP MAIN ;跳转到主程序 ORG 0030H MAIN:MOV R0,#8 ;R0送循环次数8 MOV DPTR,#TAB ;给数据指针赋值 LOOP:MOV A,#00H ; MOVC A,@ A + DPTR MOV P1,A LCALL TIME INC DPL DJNZ R0,LOOP SJMP MAIN TIME:MOV R6,#200 TIME1:MOV R7,#200 TIME2:NOP NOP NOP DJNZ R7,TIME2 DJNZ R6,TIME1 RET TAB:DB 81H,0C3H,0E7H,0FFH,18H,3CH,7EH,0FFH END 你发现数据的特点了吗?

  41. 本章小结 修改上例中Tab中的数据,使显示方式尽可能的丰富。 • 本章要求: • 了解MCS-51单片机的7种寻址方式; • 掌握数据传送与交换、算术运算、逻辑运算、控制转移、位操作5类共111条指令的功能,特别是每一类指令中比较常用的指令; • 掌握MCS-51单片机汇编语言程序的基本格式及伪指令; • 了解程序的基本结构(顺序结构、分支结构、循环结构)和程序设计的基本方法; • 掌握数制转换、算术运算、极值查找等典型程序的设计; • 掌握子程序的设计方法及其参数传递方法。

More Related