例3-1:(Keil演示OK)c:2000h ORG2000HTAB1:DB30H,8A H,7FH,73DB''5'',''A'',''BCD''DW伪 指令与DB的功能类似,所不同的是DB用于定义一个字节(8位二进制数),而DW则用于定义一个字(即两个字节,16位二进制数 ).在执行汇编程序时,机器会自动按高8位先存入,低8位后存入(记忆!)的格式排列,这和MCS-51指令中16 位数据存放的方式一致.例3-2:(Keil演示OK) ORG1500HTA B2:DW1234H,80H解答:(1500H)=12H,(1501H)=34H,(1502H) =00H,(1503H)=80H.预留存储空间伪指令DS(Storage) 格式:[标号:]DS表达式 该伪指令的功能是从标号指定的单元开始,保留若干字节的内存空间以备源程序使用.存储空间内预留的存储单元数 由表达式的值决定.例3-3:ORG1000H(Keil通过) DS20HDB30H, 8FH汇编后:从1000H开始,预留32(20H)个字节的内存单元,然后从1020H开始,按照 下一条DB指令赋值,即(1020H)=30H,(1021H)=8FH.保留的存储空间将由程序的其它部分决定它们的用处. 例3-4:EQU和DATA的以用法(KEIL演示OK)ORG0000H A10EQU10H A20DATA20H MOVR0,A10 ;直接用A10,10H单元中的内容→R0 MOVR1,A10+1 ;A10+1,11H中的内容→R1 MOVR2,#A10 ;注意使用了#,#10 H立即数→R2注意体会这些细微的用法 MOVR3,A20 MOVR4,A20+1 MOVR5,#A20 SJ MP $ END3.4汇编语言程序的结构1.程序设计的基本步骤,一般步骤为: (1)分析题意,明确要求; (2)建 立思路,确定算法; (3)编制框图,绘出流程; (4)编写程序,上机调试; 显然,算法和流程是至关重要的.程序结构有 简单顺序、分支、循环和子程序等几种基本形式. 2.画流程图(VISIO,亿图) 画流程图是指用各种图形、符号、指向线等来说明 程序设计的过程.国际通用的图形和符号说明如下:椭圆框:起止框,在程序的开始和结束时使用.矩形框:处理框,表示要进行的各种操作. 菱形框:判断框,表示条件判断,以决定程序的流向.指向线:流程线,表示程序执行的流向.圆圈:连接符,表示不同页之间的流程连 接. 各种几何图形符号如下图所示:3.5.1顺序程序例3-5:两个无符号双字节数相加.(KEIL演示)设被加数存放 于内部RAM的40H(高位字节),41H(低位字节),加数存放于50H(高位字节),51H(低位字节),和数存入40H和 41H单元中. ORG0000HSTART:CLRC ;将Cy清零 M OVR0,#41H ;将被加数地址指针送R0 MOVR1,#51H ;将加数地址指针送R 1AD1:MOVA,@R0 ;被加数低字节的内容送入A ADDA,@ R1 ;两个低字节相加 MOV@R0,A ;低字节的和存入被加数低字节中 DECR0 ;指向被加数高位字节 DECR1 ;指向 加数高位字节 MOVA,@R0 ;被加数高位字节送入A ADDCA ,@R1 ;两个高位字节带Cy相加 MOV@R0,A ;高位字节的和送被加数高位字节 SJMP $ END3.5.2分支程序设计1.单分支程序 单分支结构程序使用转移指令实现,根据 条件对程序的执行进行判断,满足条件转移执行,否则顺序执行.在MCS-51指令系统中条件转移指令有: (1)判A转移指令JZ、JN Z; (2)判位转移指令JB、JNB、JBC、JC、JNC; (3)比较转移指令CJNE; (4)减1不为0转移指令DJNZ ;例3-9:假定在外部RAM中有ST1、ST2和ST3共3个连续单元,其中ST1、ST2单元中分别存放着两个8位无符号数 ,要求找出其中的大数并存入ST3单元. (keil演示) 分析:两个无符号数的大小比较可利用两数相减是 否有借位来判断,流程图和程序如下所示: ST1EQU4000h ORG0000hSTART:C LR C MOV DPTR,#ST1 MOVX A,@DPTR ;取第一个数 MO V R7, A ;暂存于R7 INC DPTR MOVX A,@DPTR ;取第二个数 SUBB A,R7 ;ST2-ST1 JC BIG1 ;C=1,跳到BIG1,ST2 MOVX A,@DPTR ;C=0顺序执行,ST2大,重新取到ST2 SJMP BIG2 BIG 1:XCH A,R7 ;C=1,有借位,ST1大,把R7中的大数交 ;换到A中BIG2:I NC DPTR ;指向ST3MOVX @DPTR,A SJMP $ END2、多分支程序 ;解2(keil演示) ORG0000H VAREQU30H ;X FUNCEQU31H ;YBR1: MOVR0,VAR ;取出变量“X”START:CJNER0,#00H,SUL1 ;R0中的数与00比较不等转移 MOVR1,#00H ;相等,R1←0 SJMPSUL2SUL1:CJN ER0,#80H,$+3 JNCNEG ;两数不等,若(R0)<0,转向NEG MOVR1,#01H ;(R0)>0,则R1←01 SJMPSUL 2NEG:MOVR1,#0FFH ;(R0)<0,则R1←0FFHSUL2: MOVFUNC,R 1 SJMP$ END3.5.3循环程序设计 循环程序一般由四个主要部分组成:(1)初始化部分:为 循环程序做准备,如循环次数设定、给各变量和地址指针预置初值,辅助计数单元清0.(2)处理部分:为反复执行的程序段,是循环 程序的实体,也是循环程序的主体.(3)循环控制部分:这部分的作用是修改循环变量和控制变量,并判断循环是否结束,直到符合 结束条件时,跳出循环为止.(4)结束部分:这部分主要是对循环程序的结果进行分析、处理和存放.3.5.4散转程序设 计(了解)散转程序是分支程序的一种,它可根据运算结果或输入数据将程序转入不同的分支.MCS-51指令 系统中有一条跳转指令JMP@A+DPTR,用它可以很容易地实现散转功能.该指令把累加器的8位无符号数与16位数据指针的内容相加, 并把相加的结果装入程序计数器PC,控制程序转向目标地址去执行.此指令的特点在于,转移的目标地址不是在编程或汇编时预先确定的,而是在 程序运行过程中动态确定的.目标地址是以数据指针DPTR的内容为起始的256字节范围内的指定地址,即由DPTR的内容决 定分支转移程序的首地址,由累加器A的内容来动态选择其中的某一个分支转移程序.例3-13:根据工作寄存器R0内容的不同,使程序转入 相应的分支.(R0)=0对应的分支程序标号为PR0;(R0)=1对应的分支 程序标号为PR1; ……(R0)=N对应的分支程序标号为PRN.程序如下:LP 0:MOVDPTR,#TAB ;取表头地址MOVA,R0A DDA,R0 ;R0内容乘以2JNCLP1 ;无进位转移INCDPH ;加 进位位LP1:JMP@A+DPTR ;跳至散转表中相应位置TAB: AJMPPR0 AJMPPR1…. AJMPPRN 本例程序仅适用于散转表首地址TAB和 处理程序入口地址PR0,PR1,…,PRN在同一个2KB范围的存储区内的情形.若超出2KB范围可在分支程序入口处安 排一条长跳转指令,可采用如下程序: MOVDPTR,#TAB MOVA,R0 MOVB,#0 3H;长跳转指令占3个字节 MULAB XCHA,B ADDA,DPH MOVDPH,A XCHA,B JMP@A+DPTR;跳至 散转表中相应的位置…… ……TAB: LJMPPR0;跳至不同的分支 LJ MPPR1…. LJMPPRN3.5.5查表程序设计 1.查表程序是一种常用程序 ,它广泛使用于LED显示控制、打印机打印控制、数据补偿、数值计算、转换等功能程序中,这类程序具有简单、执行速度快等特点. 2 .所谓查表法,就是预先将满足一定精度要求的表示变量与函数值之间关系的一张表求出,然后把这张表存于ROM中,这时自变量值为单元地址, 相应的函数值为该地址单元中的内容. 查表,就是根据变量X在表格中查找对应的函数值Y,使Y=f(X) 3.MCS-51指令系统 中,有两条查表指令:MOVCA,@A+PC ;A?((A)+(PC)当前值)MOVCA,@A +DPTR ;A?((A)+(DPTR)) 当使用DPTR作为基址寄存器时查表比较简单,查表的步骤分三步: 1 )基址(表格首地址)送DPTR数据指针; 2)变址值(在表中的位置是第几项)送累加器A; 3)执行查表指令M OVCA,@A+DPTR,进行读数,查表结果送回累加器A. 当使用PC作为基址寄存器时,由于PC本身是一个程序计数器 ,与指令的存放地址有关,查表时其操作有所不同.查表的步骤也分三步: 1)变址值(在表中的位置是第几项)送累加器A; 2)偏移量(查表指令的下一条指令的首地址到表格首地址之间的字节数)+A→A;(修正)? 3)执行查表指令MOVCA,@A+PC例3-14:一个字节的十六进制数与ASCII码的转换程序.设数值在R2中,结果低位 存在R2中,高位存在R3中. 分析:对于2位16进制数必须进行2次查表,因此,取数后通过屏蔽的方法来实现高低位分开.(KE IL通过)(1)利用DPTR作基址的参考程序如下(R2=2FH>>>R3=32HR2=46H)HEX2ASC: MOV DPTR,#TABLE ;更容易理解 MOVA,R2 ANL A,#0FH ;取低4位 MOVCA,@A+DPTR ;查表 XCHA,R2 ;R2和A中数据交换 ANL A,#0F0H ;取高4位 SWAPA ;把高4位的数换到低4位来 MOVCA,@A+DPTR ;查表 MOVR3,A SJMP$TABLE: DB 30H,31H,32H,33H,34H ;ASCII表 DB35H,36H,37H,38H,39H DB41H,42H,43H,44H,45H,46H(2)利用PC作基址的参考程序如下:(R2=2FH> >>R3=32HR2=46H)HEX2ASC: MOVA,R2 ;keilOK ANLA,#0F H;取低4位 ADDA,#10 ;调整,不容易理解! MOVCA,@A+PC ;查表 XCHA,R2 ANL A,#0F0H SWAPA ADD A,#3 ;调整 MOVCA,@A+PC ;查表 MOVR3,A SJMP$TABLE: DB30H,31H,32H,33H,34H ;ASCII表 DB35H,36H,37H,38H,39H DB41H,42H,43H,44H,45H,4 6H三、子程序的基本结构MAIN:…… ;MAIN为主程序或调用程序标号LCALLSUB ;调 用子程序SUBSUB:PUSHPSW ;现场保护PUSHACC ;子程序处理程序段 ….. POPACC ;现场恢复 POPPSW ; RET ;最后一条指令必须为R ET3.5.7关键字查找程序设计两种方法,即顺序检索和对分检索一、顺序检索:从第1项开始逐项顺序查找,判断所取数据是 否与关键字相等.例3-17:从50个字节的无序表中查找一个关键字××H. ORG0000H MOV30H ,#××H ;关键字××H送30H单元 MOVR1,#50 ;查找次数送R1 MOVA,#14 ; 修正值送A MOVDPTR,#TAB4 ;表首地址送DPTRLOOP:PUSHACC MOVC A,@A+PC ;查表结果送A CJNEA,40H,LOOP1 ;(40H)不等于关键字则转LOOP1 MOVR2,DPH ;已查到关键字,把该字的地址送R2,R3 MOVR3,DPLDONE:RETLO OP1: POPACC ;修正值弹出 INCA ;A+1→A INCDPTR ;修改数据指针DPTR DJNZR1,LOOP ;R1≠0,未查完,继续查找 MOVR2,#00H ;R1=0,清“0”R2和`R3 MOVR3,#00H ;表中50个数已查完 AJMP DONE ;从子程序返回TAB4: DB…,…,… ;50个无序数据表3.5.8数据极值查找程序设计 进行数值大小的比较,在指定的数据区中找 出最大值(或最小值),并存于某一单元中.例3-18:片内RAM中存放一批数据,查找出最大值并存放于以R0为首地址,R2中存放字节 数,程序框图如右图所示. MOVR2,#4 ;R2要比较的数据字节数 MOVA,R0 ;存首地址指针 MOVR1,A DECR2 MOVA,@R1LOOP: MOVR3,A DECR1 CLRC SUBBA,@R1 ; 两个数比较 JNCLOOP1 ;C=0,A中的数大,跳LOOP1 MOVA,@R1 ;C=1,则大数 送A SJMPLOOP2LOOP1:MOVA,R3LOOP2:DJNZR2,LOOP ;是否比较 结束? MOV@R0,A ;存最大数 RET3.5.9数据排序程序设计升序排,降序排.仅介 绍无符号数据升序排.冒泡法:相邻数互换的排序方法,类似水中气泡上浮.排序时从前向后进行相邻两个数的比较,次序与要求的顺序不符时 ,就将两个数互换;顺序符合要求不互换.假设有7个原始数据的排列顺序为:6、4、1、2、5、7、3.第一次冒泡的过程是: 6、4、1、2、5、7、3;原始数据的排列4、6、1、2、5、7、3;逆序,互换4、1、6、2、5、7、3 ;逆序,互换4、1、2、6、5、7、3;逆序,互换4、1、2、5、6、7、3;逆序,互换4、1、2、5、6、7 、3;正序,不互换 4、1、2、5、6、3、7;逆序,互换,第一次冒 泡结束如此进行,各次冒泡的结果如下:第 1次冒泡结果:4、1、2、5、6、3、7第2次冒泡结果:1、2、4、5、3、6、7第3次冒泡结果:1、2、4、3、5、6、7 第4次冒泡结果:1、2、3、4、5、6、7;已完成排序第5次冒泡结果:1、2、3、4、5、6、7第6次冒泡结果:1、2、3、 4、5、6、7对于n个数,理论上应进行(n-1)次冒泡,有时不到(n-1)次就已完成排序.如何判定排序是否已 完成,看各次冒泡中是否有互换发生,如果有数据互换,则排序还没完成.在程序设计中,常使用设置互换标志的方法,该标志的状 态表示在一次冒泡中是否有互换进行.例3-19一批单字节无符号数,以R0为首地址指针,R2中为字节数,将这批数进行升序排列.程序 框图如图4-2所示.SORT:MOVA,R0 MOVR1,A MOVA,R2 ;字节数送入R5 M OVR5,A CLRF0;互换标志位F0清零 DECR5 MOVA,@R1LOOP: M OVR3, A ; INCR1 ; CLRC ; MOVA,@R1 ;比较大小 SUBBA,R3 ; JNCLOOP1 ; SETBF0 ;互换标志位F0置1 MOVA ,R3; ; XCHA,@R1 ;两个数互换 DECR1 ; XCHA,@R1 ; I NCR1LOOP1: MOVA,@R1 DJNZR5,LOOP JBF0,SORT RET3.5.10码制转换程序设计在单片机应用程序的设计中,经常涉及到各种码制的转换问题.在单片机系 统内部进行数据计算和存储时,经常采用二进制码,具有运算方便、存储量小的特点.在输入/输出中,按照人的习惯均采用代表十进制数的BCD 码(用4位二进制数表示的十进制数)表示.此外,打印机要打印某数字字符,则需要将该数字的二进制码转换为该字符的ASCII码,才能送到 打印机去打印.一、二进制码到BCD码的转换BCD码有两种形式:一种是1个字节放1位BCD码,它适用 于显示或输出;一种是压缩的BCD码,即1个字节放两位BCD码,可以节省存储单元.二、BCD码到二进制码的转换三 、二进制码与ASCII码之间的转换TABLE:DW050FH,0E89H,0A695H,1EAAH,0D9BH,7F93H DW0373H,26D7H,2710H,9E3FH,1A66H,22E3H DW1174H,16EFH,33E4H,6CA0H例3-15:根据16个双字节数的序号查表找出对应数据0FH ……01H00H序号XY15低Y15高……Y1低Y1高Y0低Y0高数据Y#TABL+31#TABL+3 0……#TABL+3#TABL+2#TABL+1#TABL表地址编程思路:以表格首地址(TABL)为基址,以序号(的 2倍)为偏移量,查找对应的数据ORG0000HSTA1:MOVA,R2 ;取待查数据的序号X (入口) RLA ;每数占2个单元,序号要乘2 MOVR4,A ; R4←序号x2(即偏移量) MOVDPTR,#TABLE ;DPTR←表格首地址 MOVCA,@A+DPTR ;(A)←查到数据高8位 XCHA,R4 ;数据高8位存进R 4(出口) ;同时取出偏移量到A INCDPTR ;DPTR指向下一个单元 MOVCA,@A+DPTR ;再查到数据低8位 MOVR3,A ;将数据低8位存进R3(出口) RETTABLE:DW…………… ;表格数据见前页 END3.5.6子程序(Subroutine)和参数传递一、子程序的概念通 常把这些基本操作功能编制为程序段作为独立的子程序,以供不同程序或同一程序反复调用.在程序中需要执行这种操作的地方放置一条调用指令, 当程序执行到调用指令,就转到子程序中完成规定的操作,并返回到原来的程序继续执行下去.二、子程序的调用和参数传递调用 子程序的指令有“ACALL”和“LCALL”,执行调用指令时,先将程序地址指针PC改变(“ACALL”加2,“LCALL”加3) ,然后PC值压入堆栈,用新的地址值代替.执行返回指令RET时,再将PC值弹出.子程序调用中,主程序应先把有关的参数 存入约定的位置(入口参数),子程序在执行时,可以从约定的位置取得参数,当子程序执行完,将得到的结果再存入约定的位置(出口参数),返 回主程序后,主程序可以从这些约定的位置上取得需要的结果,这就是参数的传递.NOTE:标号选择一般是英文的缩写或者汉语拼音的缩写 ,具有一定的含义例3-16:把内部RAM某一单元中一个字节的十六进制数转换成两位ASCII码,结果存放在内部R AM的连续两个单元中.假设一个字节的十六进制数在内部RAM40H单元,而结果存入50H,51H单元,可以利用堆栈进行参数 传递,程序如下:MAIN:MOVR1,#50H ;R1为存结果的指针 MOVA,40H ;A为需转换的十六进制数SWAPA ;先转换高位半字 PUSHACC ;压栈LCALLHEX2ASC;调用 将低半字节的内容转换成ASCII码子程序HEASCPOPACCM OV@R1,A ;存高半字节转换结果INCR1PU SH40H LCALLHEX2ASC POPACC MOV@R1,A ;存低半 字节转换结果HEX2ASC: MOVR0,SP DECR0 DECR0 ;R0指向十六进 制数参数地址 XCHA,@R0 ;取被转换参数 ANLA,#0FH ;保留低半字节 ADDA,#2 ;修改A值 MOVCA,@A+PC;查表 XCHA,@R0 ;结果送 回堆栈 RETTABLE: DB30H,31H,32H,33H,34H,35H,36H,37H,38H,39H DB41H,42H,43H,44H,45H,46H;ASCII表例(补充):阅读下列程序,对汇编程序逐句加上简明注释, 并分析其功能,说明R2、R3、DPTR、A的内容。 ORG0000H MOV4 0H,#41H MOVR7,#20 MOVR2,#00H MOVR3,#00H MOVDPTR,#TAB LOOP:CLRA MOVCA,@A+DPTR CJNEA,40H,LOOP1 MOV R2,DPH MOV R3,DPLDONE:RET LOOP1:IN C DPTR DJNZ R7,LOOP SJMP$ ;系统从0000H单元开始 ;关键字‘A’送30H单元;查找次数送R1;R2附初值;R3附初值;表首地址送DPTR ;A中清0;查表;与关键字‘A’比较;找到把关键字的DPTR值R2、R3;程序返回;找不到,找下一 个;减一循环;循环等待 ORG2000H TAB: DB75,8AH,0AFH,73,''5'','' E'',''A'',12H,34H,48H DB41H,24H,36H,18,''5'',''F'',''B'',63,65,73 END ;表存放与2000H开始的单元;表地址;数据表 ;程序结束程序实现的功能是:从第1项开始逐项顺序查找,判断所取数据是否与关键字相等,已查到关键字,把该字的地址送R2,R3 。(R2)=20H(R3)=06HDPTR=2006HA=41H第三章(2)汇编语言程序设计教学要求:1 .进一步熟悉指令系统,自己可以看懂书上的程序;2.自己可以编写20行以内的程序,并在计算机上调试通过,考试编程必考3.1汇编 语言程序设计中的数3.2汇编语言编程基本规则3.3汇编程序的伪指令3.4汇编语言程序的结构3.5几种常见程序 3.5.1简单程序 3.5.2分支程序设计3.5.3循环程序设计 3.5.4散转程序设计3.5 .5查表程序设计 3.5.6子程序和参数传递3.5.7关键字查找程序设计3.5.8数据极值查找程序设计 3.5.9数据排序程序设计 3.5.10码制转换程序设计3.1汇编语言程序设计中的数计算机只能识别二进 制数——机器指令,它原本是不认识常用的十六进制数和十进制数的.1.机器指令/目标代码:由0/1代码组成的操作码与操作数.2 .二进制数:由0/1组成、“逢2进1”的数制.如:01011110B(0~1后缀:B/bBinar y)3.十六进制数:便于读写记忆的二进制数的简写形式.(0~9,A~F后缀:H/hHexadecimal) 4.BCD码:用二进制数表达的十进制数.(0~9表示为:0000~1001B)3.2汇编语言编 程基本规则1.汇编语言:用助记符描述的指令的集合.2.汇编程序:汇编语言编写的程序借助编译工具编译成为目标代码,计算机才能 识别.这个编译工具称为汇编程序.3.[标号:]操作码[目的操作数][,源操作数][;注释]√指令中以A—F开头的十六进 制数前必须添一个“0”.√二进制数必须带后缀“B”或“b”;十六进制数必须带后缀“H”或“h”;十进制数的后缀是“ D”或“d”或无.3.3汇编程序的伪指令1.汇编程序→软件→工具→工具软件:将程序员用汇编语言编写的程序翻译成机器码2.用 汇编语言编写的程序在此被称为应用程序3.指令:告诉计算机如何操作以及做何种操作(有机器码)4.伪指令:告诉汇编程序在翻译应用程 序时有何具体约定.伪指令不进行具体的操作,那是一般指令的事.比如:从何处开始,何处结束,某些编程者自己规定的表述代表什么意思…… (没有机器码)1.ORGaddr16——汇编程序中一定要写!(ORIGINE)规定编译后的机器代码存放的起始位置.可 以多次使用ORG命令2.END——ASM51程序中一定要写!表示翻译到此结束,其后的任何内容不予理睬.每段程序只 能有一条END指令3.$——“当前PC值”也叫位置计数器,代表正在执行的指令所在位置.如:HERE:SJMPHERE 可写为:SJMP$4.符号名称EQU表达式(EQUATE)将表达式的值赋予符号名称,程序中凡出 现该符号名称就等同于该表达式.5.符号名称BIT位地址将位地址的值赋予符号名称,程序中凡出现该符号名称就代 表该位地址.如:AIBITP1.06.DB8位数据[或8位数据组](DefineByte)将8位数据[或8位 数据组]顺序存放在此后的存储单元中,占相应数量的存储空间.7.DW双字节数据[或双字节数据组](DefineWord) 将双字节数据[或双字节数据组]顺序存放在此后的存储单元中,占据相应存储空间.8.DATA数据地址赋值命令格式:字符名称 DATA表达式功能:将数据地址或代码地址赋予规定的字符名称解答:(2000H)=30H,(2001H)=8 AH,(2002H)=7FH (2003H)=49H;十进制数73以十六进制数存 放 (2004H)=35H;数字5的ASCII码 (2005H)=4 1H;字母A的ASCII码 (2006H)=42H;‘BCD’中B 的ASCII码 (2007H)=43H;‘BCD’中C的ASCII码 (2008H)=44H;‘BCD’中D的ASCII码等值指令EQU(Equate) 指令格式:字符名称EQU数字或汇编符号功能:使指令中的字符名称等价于给定的数字 或汇编符号.使用等值指令可给程序的编制、调试、修改带来方便,如果在程序中要多次使用到某一地址,由EQU 指令将其赋值给一个字符名称,一旦需要对其进行变动,只要改变EQU命令后面的数字即可,而不需要对程序中涉及到该地址的所有指令逐 句进行修改.但要注意,由EQU等值的字符名称必须先赋值后使用,且在同一个源程序中,同一个标号只能赋值一次.例: PA8155EQU8001H即给标号PA8155赋值为8001H.3.5几种常见程序 ORG0000HBCD2B: MOVA,R2 ;取入口数据(23BCD) ANLA,#0F0 H ;取出十位SWAPA ;高4位低4位MOVB,#10 MULAB ;十位乘10MOVR3,A ;积暂存进R3MOV A,R2 ;再取入口数据ANLA,#0FH ;取出个位ADDA,R3 ;加上个位 MOVR2,A ;结果R2(17h) SJMP$ END 例3-6:将R2中 BCD码数转为十六进制数存进R2(0X23=17h)(此子程序在下一例中还要用到)keil演示编程要点:1.两字节BC D码数范围为:0000H—9999H2.相应2进制/16进制数为:0000H—270FH3.调用BCD2B子程序实 现“千位,百位”转为二进制,并乘100;4.再调用BCD2B子程序实现“十位,个位”转为二进制;最后,对位相加.例3-7: 将R5R4中的双字节BCD码数转为十六进制数存于R5R4中.(KEIL演示OK)MAIN:MOV A,R4 MOV R2,ALCALLBCD2BMOV A,R2 MOV R4,A ;R4暂存MOV A,R5MOV R2,ALCALLBCD2B MOV A,R2MOV B,#100 MUL ABADD A,R4 MOV R4,A MOV A,B ADD C A,#00H MOV R5,A RETX100千百十个二进制+Cy+(R5)(R4)( R5)(R4)(A)(A)(B)(A)二进制二进制二进制二进制二进制调BCD2B调BCD2BR4( R5,R4)=2345(BCD)=0929(H)=916^2+216+9例3-8:16进制数(00H—0FH)转 ASCII码子程序(keil演示)0~9→30H~39H,A~F→41H~46H(记忆)算法:凡<10的十 六进制数加30H 凡≥10的十六进制数加37H(参见课件的ASCII码表)解1: ORG0000H ; 入口参数出口参数均在R2中H2ASC:MOVA,R2 ;取待转换的数据(入口) ADDA,#0F6H ;判此数是否≥10?F6+A=100(H) ;若≥10,则C=1;<10,则C=0 MOVA,R2 ; 重取待转换的数据 JNCAD30H ;C=0,小于10就跳去加30H ADDA,#07H ;≥10就先加7再去加30HAD30H:ADDA,#30H MOVR2,A ;存结果(出口)SJMP$ END解2: ORG0000H ;入口参数出口参数均在R2中H2ASC:MOVA,R2 ;取待转换的数据(入口) SUBBA,#0AH MOVA,R2 ;重取待转换的数据 JCSMALL ;C=1,小于10就跳去加30H ADDA,#07H ;≥10就先加7再去加30HSMALL:ADDA,#30H MOVR2,A ;存结果(出口)SJMP$ END;解1(keil演示) O RG0000H VAREQU30H ;X FUNCEQU31H ;YBR 1: MOVA,VAR ;取出变量“X” JZCOMP ;若=0,就赋0 JNBACC.7,POS1 ;判断=正?MOVA,#0FFH ;(-1=+1取反加 1)SJMPCOMP ;输出-1POS1:MOVA,#01H ;输出+1COM P:MOVFUNC,A ;赋给函数“Y”SJMP$END例3-10:1(X>0) 0(X=0)-1(X<0)Y= 例3-补1不同存储区域之间的数据传输: 编写并调试一个数据传送程 序,将内部RAM40--43H的4个数据送到外部RAM3000H—3003H,再将外部RAM3000H—3003H中的数 据送到单片机内部RAM53H-50H(倒序)。 ORG0000H LJMPMAIN ORG0050HMAIN:MOVR0,#40H MOVDPTR,#3000H MOVR7,#4;4个数LOOP:MOVA,@R0 MOVX@DPTR,A INCR0 INCDPTR DJNZR7,LOOP MOVR0,#53H MOVDPTR,#3000H MOVR6,#4 LOOP1:MOVXA,@DPTR MOV@R0,A DECR0 INCDPTR DJNZR6,LOOP1 SJMP$ END ORG0000Hdelay100ms: MOVR6,#200 ;1TmLOOP1: MOVR7,#248 ;1Tm NOP ;1TmLOOP2: DJNZR7,LOOP2;2Tm DJNZR6,LOOP1;2Tm RET ;1Tm END例3-11(常用)软件延时100ms(晶振12MHz,修改)keil演示注意观察sec☆1Tm=1us100ms=100,000us☆MOVRn#data和NOP是单机器周期指令☆DJNZRn,rel是双机器周期指令☆200=0C8H;248=0F8H1+1+248x2=498(498+2)x200ORG0000Hdelay1s:MOVR7,#10DL1:MOVR6,#200DL2:MOVR5,#250DL3:DJNZR5,DL3DJNZR6,DL2DJNZR7,DL1RET END例3-12:(常用)软件延时1s(晶振12MHz)keil演示注意观察sec☆1Tm=1us1s=1,000,000us☆MOVRn#data是单机器周期指令☆DJNZRn,rel是双机器周期指令1+250x21+[(1+250x2)+2)]x2001+[(1+250x2+2)x200+2]x10 |
|