资源预览内容
第1页 / 共65页
第2页 / 共65页
第3页 / 共65页
第4页 / 共65页
第5页 / 共65页
第6页 / 共65页
第7页 / 共65页
第8页 / 共65页
第9页 / 共65页
第10页 / 共65页
亲,该文档总共65页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
4.1 单片机程序程序设计(chn x sh j)语言概述4.1.1 4.1.1 机器语言(j q y yn)(j q y yn)和汇编语言4.1.2 4.1.2 单片机使用的高级语言(1 1)BASICBASIC语言(2 2)C C语言(3 3)PL/MPL/M语言 4.1.3 80C514.1.3 80C51单片机汇编语言的语句格式第1页/共64页第一页,共65页。汇编语言程序设计必须注意如下特点:(1 1)设计人员必须详细了解单片机的硬件结构,以便(ybin)(ybin)在程序设计中熟练使用;(2 2)必须熟悉汇编语言指令的功能和用法;(3 3)在程序设计前,必须分析设计任务,确定所用算法,确定程序结构,确定数据的类型、数据的结构,必须对数据的存放、寄存器和工作单元的使用以及所用硬件资源等作出具体安排;(4 4)根据分析,画出程序设计流程图;(5 5)根据程序设计流程图编写程序。第2页/共64页第二页,共65页。4.2 汇编语言程序的基本(jbn)结构形式 单片机汇编语言程序设计的基本结构形式一般分为以下4 4种形式,即顺序结构、分支结构、循环结构和子程序结构。4.2.1 4.2.1 顺序程序结构 顺序程序是最简单的程序结构,在顺序程序中,既无分支,循环,也不调用子程序,程序执行时一条一条地按顺序执行指令 例:假定三字节无符号数相加,其中一个加数在内部RAMRAM的50H50H、51H51H和52H52H单元中,另一个加数在内部RAMRAM的53H53H、54H54H和55H55H单元中,要求把相加之和存放(cnfng)(cnfng)在50H50H、51H51H和52H52H单元中,进位存放(cnfng)(cnfng)在位寻址区的00H00H位中。解:(1 1)分析任务:求两数之和 (2 2)算法:加法运算(ADDADD或ADDCADDC) 第3页/共64页第三页,共65页。 (3 3)程序结构:顺序或循环结构 (4 4)数据类型:三字节、二进制、无符号数 (5 5)数据结构:升序或降序排列 (6 6)RAMRAM单元安排: (内部RAMRAM字节单元、位地址(dzh)(dzh)空间) (7 7)采用寄存器间接寻址方式(R0R0、R1R1)加数(N1N1)高字节(8 8位)中字节(8 8位)低字节(8 8位)加数(N2N2)高字节(8 8位)中字节(8 8位)低字节(8 8位)加数(N1N1)加数(N2N2)和(N3N3)52H52H单元低字节(8 8位)55H55H单元低字节(8 8位)52H52H单元低字节(8 8位)51H51H单元中字节(8 8位)54H54H单元中字节(8 8位)51H51H单元中字节(8 8位)50H50H单元高字节(8 8位)52H52H单元高字节(8 8位)50H50H单元高字节(8 8位)00H00H位进位位第4页/共64页第四页,共65页。 (8 8)程序设计(chn x sh j)(chn x sh j)流程框图;第5页/共64页第五页,共65页。 (9 9)程序清单; ORG 1000H ORG 1000H MOV RO MOV RO, #52H #52H;加数N1N1的低字节地址送地址指针R0R0 MOV R1 MOV R1, #55H #55H;加数N2N2的低字节地址送地址指针R1R1 MOV A MOV A, R0 R0; 取N1N1的低字节 ADD A ADD A, R1 R1; N1 N1、N2N2低字节相加 MOV R0 MOV R0, A A; 保存N1N1、N2N2低字节和 DEC R0 DEC R0; 修改(xigi)(xigi)加数N1N1的地址指针内容 DEC R1 DEC R1; 修改(xigi)(xigi)加数N2N2的地址指针内容 MOV A MOV A, R0 R0; 取N1N1的中间字节 ADDC A ADDC A, R1R1; N1 N1、N2N2中间字节带低字节和进位相加 MOV R0 MOV R0, A A; 保存N1N1、N2N2中间字节和 DEC R0 DEC R0; 修改(xigi)(xigi)加数N1N1的地址指针内容第6页/共64页第六页,共65页。 DEC R1 DEC R1; 修改加数N2N2的地址(dzh)(dzh)指针内容 MOV A MOV A, R0 R0; 取N1N1的高字节 ADDC A ADDC A, R1 R1; N1 N1、N2N2高字节带中间字节和进位相加 MOV R0 MOV R0, A A; 保存N1N1、N2N2高字节和 MOV 00H MOV 00H, C C; 高字节和的进位送00H00H位保存 END END 思考题: 1 1)上述程序中,如果只采用ADDCADDC指令,应如何修改程序? 2 2)如果N1N1、N2N2,N3N3均为十进制数,应如何修改程序? 3 3)如果加数N1N1在内部RAM 50HRAM 50H、51H51H和52H52H单元中,而加数N2N2与和N3N3均在外部RAM0053HRAM0053H、0054H0054H和0055H0055H单元中,其它条件不变,应如何修改程序? 4 4)如果N1N1、N2N2,N3N3均存放在外部RAMRAM单元,应如何修改程序?第7页/共64页第七页,共65页。例:设内部RAM 40HRAM 40H,41H41H单元中分别存放8 8位二进制数,现分别取这两个单元中的半个字节(z ji)(z ji),合并成一个新字节(z ji)(z ji)存放在42H42H单元中。要求如下:42H42H单元新字节(z ji)(z ji)的低半字节(z ji)(z ji)取自40H40H单元的低半字节(z ji)(z ji),而高半字节(z ji)(z ji)取自41H41H单元的低半字节(z ji)(z ji)。解:(1 1)分析任务:拆字、合字第8页/共64页第八页,共65页。 (2 2)算法:逻辑运算 (3 3)程序结构:顺序 (4 4)数据类型:单字节、二进制、无符号数 (5 5)数据结构:升序或降序排列 (6 6)程序设计(chn x sh j)(chn x sh j)流程框图;第9页/共64页第九页,共65页。 (7 7)程序清单; ORG 2000H ORG 2000H START: MOV R1 START: MOV R1, #40H #40H;初始化数据指针R1R1的内容 MOV A MOV A, R1 R1; 取40H40H单元内容送A A ANL A ANL A, #0FH #0FH;保留40H40H单元内容低4 4位 INC R1 INC R1; 修改数据指针R1R1的内容 XCH A XCH A, R1 R1; (A) (A)与R1R1内容互换 ANL A ANL A, #0FH #0FH;保留41H41H单元内容低四位 SWAP A SWAP A; 41H 41H单元内容高低半字节(z ji)(z ji)互换 ORL A ORL A, R1 R1; 合字生成新字节(z ji)(z ji) INC R1 INC R1; 修改数据指针R1R1的内容 MOV R1 MOV R1, A A; 新字节(z ji)(z ji)送42H42H单元保存 END END作业题: 上例中其它条件不变,要求如下:42H42H单元新字节(z ji)(z ji)的低半字节(z ji)(z ji)取自40H40H单元的低半字节(z ji)(z ji),而高半字节(z ji)(z ji)取自41H41H单元的高半字节(z ji)(z ji)。第10页/共64页第十页,共65页。(1 1)单分支程序 单分支程序是通过条件转移指令实现的,即根据条件对程序的执行进行判断,满足条件则进行程序转移,不满足条件程序就顺序执行。 在MCS-51MCS-51指令系统中,可利用JZJZ,JNZJNZ,CJNECJNE,DJNZDJNZ,JCJC,JNCJNC,JBJB,JNBJNB,JBCJBC等指令,完成为0 0、为1 1、为正、为负以及相等、不相等等各种条件判断。 例:两个8 8位无符号二进制数比较大小。假设在外部RAMRAM中有ST1ST1、ST2ST2和ST3ST3共3 3个连续单元(单元地址从小到大),其中ST1ST1、ST2ST2单元中存放着两个8 8位无符号二进制数N1N1,N2N2,要求(yoqi)(yoqi)找出其中的大数并存入ST3ST3单元中。4.2.2 分支(fnzh)程序结构第11页/共64页第十一页,共65页。解:(1 1)分析任务:比较两个数的大小 (2 2)算法:算术运算、控制转移 (3 3)程序结构:单分支 (4 4)数据类型:单字节、二进制、无符号数 (5 5)数据结构:单元地址升序排列(pili) (pili) (6 6)RAMRAM单元安排:外部RAMRAM单元 (7 7)采用寄存器间接寻址方式(R0R0、R1R1或DPTRDPTR) (8 8)程序设计流程框图; (9 9)程序清单;思考题(补充作业题): 上例中,如果采用CJNE ACJNE A, direct direct,relrel指令,应如何修改程序?第12页/共64页第十二页,共65页。返回(fnhu)第13页/共64页第十三页,共65页。 ORG 8000H ORG 8000H START: CLR C START: CLR C;进位清0 0 MOV DPTR MOV DPTR, #ST1 #ST1; 设数据指针 MOVX A MOVX A,DPTRDPTR; A A(ST1ST1),取N1N1 MOV R2 MOV R2, A A; 暂存N1N1 INC DPTR INC DPTR; DPTR ST2 DPTR ST2(指向(zh (zh xin)N2xin)N2单元) MOVX A MOVX A, DPTR DPTR; 取N2N2存于A A中 SUBB A SUBB A, R2 R2;N1N1,N2N2比较(N2-N1N2-N1,差在A A中) JNC BIG1 JNC BIG1;N2N1N2N1,转BIG1BIG1,N2N2N1N1,顺序执行 XCH A XCH A, R2R2;N1N1,N2N2互换,A N1A N1 SJMP BIG0 SJMP BIG0 BIG1: MOVX A BIG1: MOVX A, DPTRDPTR;A N2A N2 BIGO: INC DPTR BIGO: INC DPTR; DPTR ST3 DPTR ST3(指向(zh xin)N3(zh xin)N3单元) MOVX DPTR MOVX DPTR, A A;ST3 ST3 大数 END END返回(fnhu) 第14页/共64页第十四页,共65页。(2 2)多分支程序 假设多分支程序中,分支序号的最大值为n n,则多分支转移结构如图所示: MCS-51 MCS-51指令系统没有多分支转移指令,无法使用单条指令完成多分支转移。要实现多分支转移,可采用(ciyng)(ciyng)以下几种方法: 第15页/共64页第十五页,共65页。 假设(jish)(jish)分支序号值保存在累加器A A中,则可使用CJNE ACJNE A, #data #data, rel rel指令,其分支流程如图所示: (a)使用(shyng)多条CJNE指令,通过逐次比较,实现分支程序转移第16页/共64页第十六页,共65页。例:已知:127X-128127X-128,求Y Y。设X X,Y Y分别存放在外部RAM 1000HRAM 1000H和2000H2000H单元(dnyun)(dnyun)中。解:(1 1)分析任务:解方程 (2 2)算法:控制转移 (3 3)程序结构:多分支 (4 4)数据类型:单字节、二进制、有符号数 (5 5)RAMRAM单元(dnyun)(dnyun)安排:外部RAMRAM单元(dnyun)(dnyun) (6 6)采用寄存器间接寻址方式(R0R0、R1R1或DPTRDPTR) (7 7)程序设计流程框图 (8 8)程序清单;思考题(补充作业题): 上例中,如果采用CJNECJNE指令,应如何修改程序?第17页/共64页第十七页,共65页。返回(fnhu)第18页/共64页第十八页,共65页。 ARE EQU 1000H ARE EQU 1000H; BUF EQU 2000H BUF EQU 2000H; ORG 1000H ORG 1000HSTARTSTART:MOV DPTRMOV DPTR, #ARE #ARE; 数据X X的地址送数据指针DPTRDPTR MOVX A MOVX A, DPTR DPTR; A A取数据X X JZ SUL JZ SUL; X X0 0转SULSUL JB ACC.7 JB ACC.7, NEG NEG; X X0 0转NEGNEG,否则(fuz)(fuz),X X0 0 MOV A MOV A, #01H #01H; SJMP SUL SJMP SUL; NEG: MOV A NEG: MOV A, #0FFH #0FFH; (0FFH (0FFH为-1-1补码) ) SUL: MOV DPTR SUL: MOV DPTR, #BUF #BUF; 数据Y Y的地址送数据指针DPTRDPTR MOVX DPTR MOVX DPTR, A A; 保存Y Y值 END END返回(fnhu)第19页/共64页第十九页,共65页。 首先,在程序中建立一个转移指令表,在表格中存放转移指令,然后,通过查转移指令表的方式实现多分支程序转移。 这种方法主要利用散转指令JMP A+DPTRJMP A+DPTR,此指令采用变址寻址方式,操作过程:(PCPC)(A A)+ +(DPTRDPTR),CPUCPU根据PCPC的内容来实现多分支程序转移。DPTRDPTR中送转移指令表的表首地址(常用转移指令表的名称标号代替),而A A中送转移指令表中存放的转移指令的序号(常常从第0 0条开始)。 例如,有多个分支程序,如要通过AJMPAJMP转移指令进行(jnxng)(jnxng)转移,则应把这些转移指令按序写入转移指令表中,并设置一个序号指针(例如R3R3),序号往往从0 0开始,然后可使用以下查表程序实现程序转移。(b)使用查转移指令表的方法(fngf)实现多分支程序转移第20页/共64页第二十页,共65页。 MOV A MOV A, R3 R3; 分支程序(chngx)(chngx)序号送A A RL A RL A; 分支程序(chngx)(chngx)序号乘2 2 MOV DPTR MOV DPTR,#BRTAB#BRTAB; BRTAB BRTAB为转移指令表名称标号, JMP A+DPTR JMP A+DPTR; 也为转移指令表首地址BRTABBRTAB:AJMP ROUT0AJMP ROUT0; 分支程序(chngx)0(chngx)0的转移指令 AJMP ROUT1 AJMP ROUT1; 分支程序(chngx)1(chngx)1的转移指令 AJMP ROUT2 AJMP ROUT2; AJMP ROUT127 AJMP ROUT127; 分支程序(chngx)127(chngx)127的转移指令ROUT0ROUT0: ; 分支程序(chngx)0(chngx)0ROUT1: ROUT1: ; ROUT127: ROUT127: ; 分支程序(chngx)127(chngx)127第21页/共64页第二十一页,共65页。 由于AJMPAJMP指令是二字节指令,因此,程序中通过RL ARL A指令将分支序号乘2 2。转移指令表中最多只能安排128128条分支转移指令,如需多于128128条,则必须另行修改程序。 由于AJMPAJMP指令转移范围是2KB2KB,因此,分支程序应安排在以JMP JMP A+DPTRA+DPTR指令为中心的2KB2KB范围之内,否则会出错。 如果转移指令表中的转移指令是LJMPLJMP指令,则分支程序可安排在64KB ROM64KB ROM空间(kngjin)(kngjin)的任何地方。但转移指令表中的转移指令的条数最多为8585条(LJMPLJMP指令是三字节指令),上述程序应作相应的修改。 MOV A MOV A, R3 R3; MOV B MOV B, #03H #03H; MUL AB MUL AB;第22页/共64页第二十二页,共65页。 MOV DPTR MOV DPTR,#BRTAB#BRTAB; BRTAB BRTAB为转移指令表名称(mngchng)(mngchng)标号, JMP A+DPTR JMP A+DPTR; 也为转移指令表首地址BRTABBRTAB:LJMP ROUT0LJMP ROUT0; 分支程序0 0的转移指令 LJMP ROUT1 LJMP ROUT1; 分支程序1 1的转移指令 LJMP ROUT2 LJMP ROUT2; LJMP ROUT85 LJMP ROUT85; 分支程序8585的转移指令ROUT0ROUT0: ; 分支程序0 0ROUT1: ROUT1: ; ROUT85ROUT85:; 分支程序8585第23页/共64页第二十三页,共65页。返回(fnhu)第24页/共64页第二十四页,共65页。4.2.3 循环(xnhun)程序结构 MCS-51 MCS-51汇编语言指令系统没有专用的循环指令,但可以使用条件转移指令通过条件判断来控制循环是继续还是结束。 循环程序一般由四个主要部分组成: : (1 1)初始化部分:为循环程序做准备,如规定循环次数、给各变量和地址指针预置初值。 (2 2)处理部分: : 为反复执行的程序段,是循环程序的实体, 也是循环程序的主体。 (3 3)循环控制部分: : 其作用是修改循环变量和控制变量,并判断循环是否结束,直到符合结束条件时,跳出循环为止。 (4 4)结束部分: : 这部分主要是对循环程序的结果进行(jnxng)(jnxng)分析、处理和存放。第25页/共64页第二十五页,共65页。 单循环程序(chngx)(chngx)一般有以下两种典型结构:第26页/共64页第二十六页,共65页。 双重循环程序(chngx)(chngx)的结构:第27页/共64页第二十七页,共65页。 在应用系统程序设计时, ,有时经常需要(xyo)(xyo)将数据存储器中各部分地址单元作为工作单元,以存放程序执行的中间值或执行结果, , 因此,在使用这些工作单元之前,必须将工作单元清零。工作单元清零可用循环程序完成。 例:假设在内部RAMRAM区,开辟9696个工作单元,工作单元首地址为20H20H,则工作单元清零程序子程序如下: : ORG 1000H ORG 1000H CLR0 CLR0:MOV R0MOV R0, #20H #20H;循环初始化部分 MOV R7 MOV R7, #96 #96; CLR A CLR A LOOP LOOP:MOV R0MOV R0, A A; 循环体部分 INC R0 INC R0; 修改变量 DJNZ R7 DJNZ R7, LOOP LOOP;循环控制部分 RET RET END END思考题(补充作业题):如采用CJNECJNE指令,应如何修改程序?第28页/共64页第二十八页,共65页。 例:两个(lin )(lin )三字节二进制无符号数相加,被加数放在内部RAM 20HRAM 20H22H22H单元(低字节存放在低地址单元,高字节存放在高地址单元,即低位在前,高位在后),加数放在2AH2AH2CH2CH单元,和放在20H20H22H22H单元,最高位如有进位,则放在23H23H单元中。解:数据类型(二、十进制数,有、无符号数);数据结构(升、降序排列)被加数(N1N1)高字节(8 8位)中字节(8 8位)低字节(8 8位)加数(N2N2)高字节(8 8位)中字节(8 8位)低字节(8 8位)被加数(N1N1)加数(N2N2)和(N3N3)20H20H单元低字节(8 8位)2AH2AH单元低字节(8 8位)20H20H单元低字节(8 8位)21H21H单元中字节(8 8位)2BH2BH单元中字节(8 8位)21H21H单元中字节(8 8位)22H22H单元高字节(8 8位)2CH2CH单元高字节(8 8位)22H22H单元高字节(8 8位)23H23H单元进位位第29页/共64页第二十九页,共65页。被加数 N1 N1 高字节(8 8位) 中字节(8 8位) 低字节(8 8位) 加数 N2 N2 高字节(8 8位) 中字节(8 8位) 低字节(8 8位) + +)进位位(CYCY) 进位位(CYCY) 进位位(CYCY) 和 N3 N3 进位 高字节(8 8位) 中字节(8 8位) 低字节(8 8位) 程序流程框图(kungt)(kungt) 程序清单思考题:统计正数、负数、零的个数。第30页/共64页第三十页,共65页。 ORG 0030H ORG 0030HADDDUOADDDUO:MOV R0MOV R0, #20H #20H; 循环初始化部分 MOV R1 MOV R1, #2AH #2AH; MOV R7 MOV R7, #03H #03H; 循环次数 CLR C CLR C; LOOP LOOP:MOV AMOV A, R0 R0; 循环体部分 ADDC A ADDC A, R1 R1; MOV R0 MOV R0, A A; INC R0 INC R0; 修改指针变量 INC R1 INC R1; DJNZ R7 DJNZ R7, LOOP LOOP; 循环控制(kngzh)(kngzh)部分 CLR A CLR A; 循环结束处理部分 ADDC A ADDC A, #00H #00H; MOV R0 MOV R0, A A; RET RET; END END 返回(fnhu)第31页/共64页第三十一页,共65页。返回(fnhu)第32页/共64页第三十二页,共65页。 例:把内部RAMRAM中起始地址为DATADATA的数据串传送到外部RAMRAM以BUFFERBUFFER为首地址的区域(qy)(qy),直到发现“$”“$”字符的ASCASC码为止,同时规定数据串最大长度为3232个字节。解:(1 1)分析任务:数据传送;(2 2)算法:比较、控制转移 (3 3)程序结构:分支、循环(4 4)数据类型:多字节字符串 (5 5)RAMRAM单元安排:内部RAMRAM单元、外部RAMRAM单元 (6 6)采用寄存器间接寻址方式(R0R0、R1R1或DPTRDPTR)第33页/共64页第三十三页,共65页。 (7 7)程序流程框图(kungt)(kungt);第34页/共64页第三十四页,共65页。 ORG 0030H ORG 0030H DATACSDATACS:MOV R0MOV R0, #DATA #DATA; DATA DATA数据区首地址 MOV DPTR MOV DPTR, #BUFFER #BUFFER;BUFFERBUFFER数据区首地址 MOV R1 MOV R1, #20H #20H; 最大数据串长 LOOP LOOP:MOV AMOV A, R0 R0; 取数据 SUBB A SUBB A, #24H #24H; 判是否为“$”“$”字符 JZ LOOP1 JZ LOOP1; 是“$”“$”字符,转结束(jish)(jish) MOVX DPTR MOVX DPTR,A A; 数据传送 INC R0 INC R0; INC DPTR INC DPTR; DJNZ R1 DJNZ R1, LOOP LOOP; 循环控制 LOOP1 LOOP1:RETRET; 结束(jish) (jish) END END第35页/共64页第三十五页,共65页。4.3 80C51单片机汇编语言程序设计(chn x sh j)举例 4.3.2 4.3.2 定时(dn sh)(dn sh)程序 在单片机的控制应用中,常有定时(dn sh)(dn sh)的需要,如定时(dn sh)(dn sh)中断、定时(dn sh)(dn sh)检测和定时(dn sh)(dn sh)扫描等。定时(dn sh)(dn sh)功能除可以使用纯硬件电路、可编程定时(dn sh)/(dn sh)/计数器实现外,还可以使用软件程序(定时(dn (dn sh)sh)程序)完成。 定时(dn sh)(dn sh)程序是典型的循环程序,它是通过执行一个具有固定延迟时间的循环体来实现定时(dn sh)(dn sh)的。(1 1)单循环定时(dn sh)(dn sh)程序 MOV R5 MOV R5, #TIME #TIME;LOOP: NOPLOOP: NOP; NOP NOP; DJNZ R5 DJNZ R5, LOOP LOOP;第36页/共64页第三十六页,共65页。 假设单片机晶振频率fosc=6MHzfosc=6MHz,则一个机器周期(zhuq)(zhuq)为2s2s,NOPNOP、DJNZDJNZ指令分别是单、双机器周期(zhuq)(zhuq)指令。定时程序的总延迟时间是循环程序段延时时间的整数倍,由于R5R5是8 8位寄存器,因此,这个定时程序的最长定时时间为: 256 256(2828)8=20488=2048(ss)(2 2)较长时间的定时程序 (多重循环定时子程序) TIME TIME:MOV R5MOV R5, #TTME1 #TTME1; LOOP LOOP:MOV R4MOV R4, #TEME2 #TEME2; LOOP1 LOOP1:NOPNOP; NOP NOP; DJNZ R4 DJNZ R4, LOOP1 LOOP1; DJNZ R5 DJNZ R5, LOOP2 LOOP2; RET RET; 第37页/共64页第三十七页,共65页。 这个定时(dn sh)(dn sh)子程序的最长定时(dn sh)(dn sh)时间为: 256 256(2828)4+2+12564+2+1256(2828)2+4=5258282+4=525828(ss)(3 3)调整定时(dn sh)(dn sh)时间 在定时(dn sh)(dn sh)程序中可通过在循环程序段中增减指令的方法对定时(dn sh)(dn sh)时间进行微调。 例: MOV R0 MOV R0, #TTME #TTME; LOOP LOOP:ADD AADD A, R1 R1; INC DPTR INC DPTR; DJNZ R0 DJNZ R0, LOOP LOOP; 由于ADDADD、INCINC、DJNZDJNZ指令的机器周期分别为1 1、2 2、2 2,所以,该程序定时(dn sh)(dn sh)时间为= =(1+2+21+2+2)2sTime2sTime(ss)。第38页/共64页第三十八页,共65页。假定要求定时时间为24us24us。对于这个定时程序,只须增加一条NOPNOP指令即可实现。 MOV R0 MOV R0, #TIME #TIME; LOOPLOOP: ADD A ADD A, R1 R1; INC DPTR INC DPTR; NOP NOP; DJNZ R0 DJNZ R0, LOOP LOOP; 只须TIMETIME取2 2,即可得到精确的24s24s定时。(4 4)以一个基本的延时程序满足不同(b tn)(b tn)的定时要求 如果一个系统有多个定时需要,我们就可以设计一个基本延时程序,使其延时时间为各定时时间的最大公约数,然后可以以此基本程序作为子程序,通过调用的方法实现所需不同(b (b tn)tn)定时。 第39页/共64页第三十九页,共65页。 例:在单片机应用系统中,假设需要的定时时间(shjin)(shjin)分别为5S5S、10S10S、20S20S,可设计一个1S1S延时子程序DELAYDELAY,则5S5S、10S10S、20S20S的定时时间(shjin)(shjin)可通过调用DELAYDELAY实现。 MOV R0 MOV R0, #05H #05H; 5S 5S定时 LOOP: LCALL DELAY LOOP: LCALL DELAY; DJNZ R0 DJNZ R0, LOOP1 LOOP1; MOV R0 MOV R0, #0AH #0AH; 10S 10S定时 LOOP2: LCALL DELAY LOOP2: LCALL DELAY; DJNZ R0 DJNZ R0, LOOP2 LOOP2; MOV R0 MOV R0, #14H #14H; 20S 20S定时 LOOP3: LCALL DELAY LOOP3: LCALL DELAY; DJNZ R0 DJNZ R0, LOOP3 LOOP3; 第40页/共64页第四十页,共65页。 4.3.3 4.3.3 查表程序 所谓查表程序,就是指预先把数据以表格形式存放在程序存储器中,然后使用程序读出,这种能读出表格数据的程序就称之为查表程序。 查表操作对单片机的控制应用十分重要,查表程序常用于实现非线性修正,非线性函数转换以及(yj)(yj)代码转换等场合。 MCS-51 MCS-51单片机指令系统中有两条专用查表指令:(1 1)MOVC AMOVC A, A+DPTR A+DPTR;AA(A A)+ +(DPTRDPTR) (2 2)MOVC AMOVC A, A+PC A+PC; A A(A A)+ +(PCPC) 这两条查表指令的功能是完全相同的,其共同优点是:能在不改变PCPC和DPTRDPTR的状态下,只根据A A的内容就可以取出表格中的数据。注意:A A的内容均为8 8位无符号数。第41页/共64页第四十一页,共65页。对于第一条指令,适用(shyng)(shyng)于64KB 64KB ROMROM范围内查表(即数据表格的大小和位置可以在64KB64KB程序存储器中任意安排,一个数据表格可以被多个程序块使用),编写查表程序时,首先把表的首地址送入DPTRDPTR中,再要将查表的数据序号(或下标值)送入A A中,然后就可以使用该指令进行查表操作,并把结果送A A中。 对于第二条指令,常用于“本地”范围查表(即数据表格只能放在该指令后面256256个地址单元之内,而且表格只能被本程序使用),编写查表程序时,首先把查表数据的序号送入A A中,再把从查表指令的下一条指令的首地址到表的首地址间的偏移量与A A值相加,然后再使用该指令进行查表操作,并把结果送入A A中。 第42页/共64页第四十二页,共65页。例:设计一个子程序,其功能为根据x x的内容(0 09 9之间)查平方表,求出相应的结果y y(y=x2y=x2)。假设x x的内容已存放在内部RAM RAM 30H30H单元中,求出y y的内容存放在内部RAM 40HRAM 40H单元中。 ORG 1000H ORG 1000H1000H SQR1000H SQR: MOV A MOV A, 30H 30H; Ax Ax1002H PUSH DPH1002H PUSH DPH; 现场保护(boh)(boh)1004H PUSH DPL1004H PUSH DPL; 1006H MOV DPTR1006H MOV DPTR,#TAB1#TAB1; DPTR DPTR表首地址TAB1 TAB1 1009H MOVC A1009H MOVC A, A+DPTR A+DPTR;查表得y y100AH MOV 40H100AH MOV 40H, A A; 40Hy 40Hy100CH POP DPL100CH POP DPL; 现场恢复100EH POP DPH100EH POP DPH; 1010H RET1010H RET1011H TAB1: DB 00H1011H TAB1: DB 00H,01H01H,04H04H,09H09H,10H10H,19H19H DB 24H DB 24H,31H31H,40H40H,51H51H第43页/共64页第四十三页,共65页。上例中,如果使用(shyng)MOVC A(shyng)MOVC A,A+PCA+PC指令,则编程如下: ORG 1000H ORG 1000H1000H SQR1000H SQR: MOV A MOV A, 30H 30H; Ax Ax1002H PUSH DPH1002H PUSH DPH; 现场保护1004H PUSH DPL1004H PUSH DPL;1006H ADD A1006H ADD A, #07H #07H; 加偏移量1008H MOVC A1008H MOVC A, A+PC A+PC; 查表得y y1009H MOV 40H1009H MOV 40H, A A; 40Hy 40Hy100BH POP DPL100BH POP DPL; 现场恢复100DH POP DPH100DH POP DPH; 100FH RET100FH RET1010H TAB1: DB 00H1010H TAB1: DB 00H,01H01H,04H04H,09H09H,10H10H,19H19H DB 24H DB 24H,31H31H,40H40H,51H51H此题中,偏移量=1010H-1009H=07H=1010H-1009H=07H第44页/共64页第四十四页,共65页。4.4 单片机汇编语言(hu bin y yn)源程序的编辑和汇编 4.5 80C51单片机汇编语言(hu bin y yn)伪指令 汇编语言程序必须转换为二进制的机器代码程序,单片机才能够(nnggu)(nnggu)执行。汇编语言程序转换为机器代码程序的过程,称之为汇编。汇编的方法有两种:即机器交叉汇编和手工汇编。 所谓手工汇编,就是指程序设计人员通过查指令编码表,逐个把助记符指令“翻译”成机器码。手工汇编方法通常用于短、小程序的汇编。长程序则必须通过机器交叉汇编的方法进行汇编。 所谓机器交叉汇编,就是指程序设计人员使用一种计算机的汇编程序去汇编另一种计算机的源程序,具体地说就是运行汇编程序进行汇编的是一种计算机,而运行汇编得到的目标程序的则是另一种计算机。 单片机只能采用机器交叉汇编的方法对汇编语言程序进行汇编第45页/共64页第四十五页,共65页。 对汇编语言程序进行(jnxng)(jnxng)机器交叉汇编时,必须告诉计算机的汇编程序应该如何完成汇编工作,这一任务就是通过使用伪指令来实现的。 伪指令是程序设计人员发给汇编程序的指令,也称汇编命令或汇编程序控制指令。它具有控制汇编程序的输入输出、定义数据和符号、条件汇编、分配存储空间等功能。 伪指令没有与之相对应的二进制机器代码,因此,在汇编语言指令系统汇总表中,查不到相对应的二进制机器代码。不同汇编语言的伪指令也有所不同,但一些基本指令是相同的。 手工汇编不需要伪指令,但机器交叉汇编必须使用伪指令。在对汇编语言程序进行(jnxng)(jnxng)机器交叉汇编前,伪指令存在于汇编语言程序中,但汇编后得到的机器代码程序中不存在伪指令相对应的二进制机器代码,这一点请特别注意。第46页/共64页第四十六页,共65页。(1 1)ORGORG(ORiGinORiGin)汇编起始地址命令 本命令总出现在汇编语言源程序的开头位置,用于规定目标程序的起始地址,即此命令后面的程序或数据块的起始地址。 命令格式: 标号:ORGORG地址 其中 标号: 是选择项,根据需要选用,地址项,通常(tngchng)(tngchng)为1616位绝对地址,但也可以使用标号或表达式表示。 在汇编语言程序的开始,通常(tngchng)(tngchng)都用一条ORGORG伪指令来规定程序的起始地址,如果不用ORGORG规定,则汇编得到的目标程序将从0000H0000H开始。 例: ORG 8000H ORG 8000H 即规定标号STARTSTART代表地址8000H8000H, START START:MOV AMOV A, #00H #00H; 目标程序的第一条指令从8000H8000H 开始。第47页/共64页第四十七页,共65页。(2 2)ENDEND(END of assemblyEND of assembly)汇编终止命令 本命令用于终止汇编语言源程序的汇编工作,ENDEND是汇编语言源程序的结束标志,因此,在整个汇编语言源程序中只能有一个ENDEND指令(zhlng)(zhlng),且位于程序的最后。如果ENDEND命令出现在程序中间,则在ENDEND之后的指令(zhlng)(zhlng),汇编程序将不予处理。 命令格式: 标号:ENDEND表达式 (3 3)EQUEQU(EQUateEQUate)赋值命令 本命令用于给字符名称赋予一个特定值,赋值以后,其值在整个程序中有效。 命令格式:字符名称EQUEQU赋值项 其中赋值项可以是常数,地址,标号或表达式,其值为8 8位或1616位二进制数。赋值以后的字符名称既可以作地址使用,也可以作立即数使用。第48页/共64页第四十八页,共65页。 例: HOUR EQU 30H HOUR EQU 30H ORG 1000H ORG 1000H START START:MOV HOURMOV HOUR, #40H #40H; 等同于 START START:MOV 30HMOV 30H, #40H #40H;(4 4)DBDB(Define ByteDefine Byte)定义数据字节命令 本命令用于从指定的地址单元开始,在程序存储器的连续单元中定义字节数据。 命令格式: 标号:DBDB8 8位数表 常使用本命令存放数据表格。 例:存放7 7段数码管(共阳极)显示的十六进制基数(0 0F F)的十六进制数的字形(z xn)(z xn)代码,可使用多条DBDB命令定义。 第49页/共64页第四十九页,共65页。 DB 0C0H DB 0C0H,0F9H0F9H,0A4H0A4H,0B0H0B0H; 0 0,1 1,2 2,3 3 DB 99H DB 99H, 92H 92H, 82H 82H, 0F8H 0F8H; 4 4,5 5,6 6,7 7 DB 80H DB 80H, 90H 90H, 88H 88H, 83H 83H; 8 8,9 9,A A,B B DB 0C6H DB 0C6H,0A1H0A1H,86H86H, 84H 84H; C C,D D,E E,F F 查表时, ,为确定数据区的起始地址, ,可采用两种方法: a a)根据(gnj)DB(gnj)DB命令前一条指令的地址确定。把该地址加上它的字节数就是DBDB的定义的数据字节的起始地址。 例:8100: MOV A, #49H8100: MOV A, #49H;一字节指令 TAB: DB 0COH TAB: DB 0COH,0F9H0F9H,0A4H0A4H,0B0H0B0H; 定义的7 7段数码管(共阳极)显示的十六进制基数(0 0F F)的十六进制数的字形代码从8101H8101H地址单元开始存放。第50页/共64页第五十页,共65页。 b b)使用0RG0RG命令专门规定。 例: ORG 8100H ORG 8100H TAB: DB 0COH TAB: DB 0COH,0F9H0F9H,0A4H0A4H,0B0H0B0H; 定义的7 7段数码管(共阳极)显示的十六进制基数(0 0F F)的十六进制数的字形代码从8101H8101H地址单元开始存放(cnfng)(cnfng)。(5 5)DWDW(Define WordDefine Word)定义数据字命令 本命令用于从指定地址开始,在程序存储器单元中定义1616位的数据字。 命令格式: 标号:DWDW1616位数表 存放(cnfng)(cnfng)时,数据字的高8 8位在前(低地址),低8 8位在后(高地址)。 第51页/共64页第五十一页,共65页。 例:DW “AA”DW “AA”; 存入41H41H,42H42H。 DBDB和DWDW定义的数表,数的个数不得超过8080个。如数据的数目较多时,可使用多个定义命令。 在MCS-51MCS-51程序设计应用中,常以DBDB来定义数据,以DWDW来定义地址。 (6 6)DSDS(Define StonageDefine Stonage)定义存储区命令 本命令用于从指定地址开始,保留(boli)(boli)指定数目的字节单元作为存储器,供程序运行使用,汇编时,对这些单元不赋值。 命令格式: 标号:DS DS 1616位数表 例: ORG 8100H ORG 8100H DS 08H DS 08H 从8100H8100H地址开始,保留(boli)8(boli)8个连续的地址单元。 第52页/共64页第五十二页,共65页。(7 7)BIT BIT 位定义命令 本命令用于给字符名称赋以位地址 命令格式:字符名称BITBIT位地址 其中位地址可以是绝对地址,也可以是符号地址(即位(j (j wi)wi)符号名称) 例: AQ BIT P1.0 AQ BIT P1.0 把P1.0P1.0的位地址赋给变量AQAQ,在其后的编程中,AQAQ就可以作为位地址使用。 第53页/共64页第五十三页,共65页。补充内容(nirng):子程序结构 子程序结构是一种非常重要的程序结构。在一个程序中经常遇到反复多次某程序段的情况,如果重复书写这个程序段,会使程序变得冗长而杂乱。对此,可采用子程序结构,即把重复的程序段编写为一个子程序,通过主程序调用而使用它。这样不但减少(jinsho)(jinsho)了编程工作量,而且也缩短了程序的长度。 调用和返回构成了子程序调用的完整过程。为了实现这一过程,必须有子程序调用指令和返回指令。调用指令在主程序中使用,而返回指令则应该是子程序的最后一条指令。执行完这条指令后,程序返回主程序断点处继续执行。第54页/共64页第五十四页,共65页。(1 1)子程序的编程原则 在实际的单片机应用系统软件设计中,为了程序结构更加清晰,易于设计,易于修改,增强程序可读性,基本上都要使用子程序结构。子程序作为一个具有独立功能的程序段,编程时需遵循以下原则: a a)子程序的第一条指令必须有标号,明确子程序入口地址(dzh)(dzh); b b)以返回指令RETRET结束子程序; c c)子程序说明部分; 子程序名称:提供给主程序调用的名字,通常用符号或子程 序第一条语句的标号来表示。 子程序功能:简要说明子程序能完成的主要功能。 子程序入口参数:主程序需要向子程序提供的参数。第55页/共64页第五十五页,共65页。 子程序出口参数:子程序执行完之后向主程序返回的参数。 子程序占用资源:子程序中使用了哪些存储单元、寄存器等 子程序堆栈深度:子程序占用堆栈区的最大字节数。 子程序嵌套情况:子程序中继续调用子程序的情况。 子程序的字节数:子程序中所有指令字节数的总和。 子程序执行时间:子程序中所有指令的机器周期数总和。 这些说明是写给程序员看的,供以后使用子程序时参考。 d d)较强的通用性和可浮动性,尽可能避免使用具体的内存单元和绝对转移地址(dzh)(dzh)等。 e e)注意保护现场和恢复现场。 子程序在编制过程中经常会用到一些通用单元,如工作寄存器、累加器、数据指针DPTRDPTR以及PSWPSW等。而这些工作单元在调用第56页/共64页第五十六页,共65页。它的主程序中也会用到,为此,需要将子程序用到的这些通用编程资源加以保护,称为保护现场。在子程序执行完后需恢复这些单元的内容(nirng)(nirng),称为恢复现场。通常保护和恢复现场是在子程序中利用堆栈操作实现的,在子程序的开始部分把子程序中要用到的编程资源都保护起来,在执行返回指令之前恢复现场,这是一种比较规范的方法。 另外,保护现场和恢复现场也可以在主程序中实现。在调用子程序前保护现场,子程序返回后恢复现场,这种方式比较灵活,可以根据当时的需要确定要保护的内容(nirng)(nirng)。第57页/共64页第五十七页,共65页。(2 2)参数传递的方法 主程序调用子程序时,主程序和子程序之间存在着参数互相传递的问题。参数传递一般有以下(yxi)(yxi)几种方法: 1) 1) 寄存器传递参数 通过寄存器A A传递入口参数和出口参数。 例:假设a a、b b均小于1010,计算c=a2+b2c=a2+b2,其中a a事先存在内部RAMRAM的31H31H单元,b b事先存在32H32H单元,请把c c存入33H33H单元。 SQR:y=x2 SQR:y=x2子程序 ORG 0000H ORG 0000H; 主程序 MAIN MAIN:MOV SPMOV SP, #3FH #3FH; 设置栈底 MOV MOV A A, 31H 31H; 取数a a存放到A A中作为入口参数 LCALL SQR LCALL SQR;第58页/共64页第五十八页,共65页。 MOV MOV R1R1, A A; 出口参数:a a的平方(pngfng)(pngfng)值存放在A A中 MOV MOV A A, 32H 32H; 取数b b存放到A A中作为入口参数 LCALL SQR LCALL SQR; ADD ADD A A, R1 R1; MOV MOV 33H 33H, A A; SJMP $ SJMP $;子程序名称:SQRSQR 功能:通过查表求出平方(pngfng)(pngfng)值y=x2y=x2 入口参数:x x存放在累加器A A中 出口参数:求得的平方(pngfng)(pngfng)值y y存放在A A中 占用资源:累加器A A,数据指针DPTRDPTR第59页/共64页第五十九页,共65页。 SQR SQR:PUSH DPHPUSH DPH;保护现场,将主程序中DPTRDPTR的高8 8位入栈 PUSH DPL PUSH DPL;保护现场,将主程序中DPTRDPTR的低8 8位入栈 MOV DPTR MOV DPTR, #TABLE #TABLE;在子程序中重新使用DPTRDPTR, DPTR DPTR表首地址 MOVC A MOVC A, A+DPTR A+DPTR;查表 POP DPL POP DPL; 恢复现场,将主程序中DPTRDPTR 的低8 8位从堆栈(duzhn)(duzhn)中弹出 POP DPH POP DPH; 恢复现场,将主程序中DPTRDPTR 的高8 8位从堆栈(duzhn)(duzhn)中弹出 RET RETTABLE: DB 0TABLE: DB 0,1 1,4 4,9 9,1616,2525,3636,4949,6464,8181 END END 第60页/共64页第六十页,共65页。 2) 2) 利用堆栈(duzhn)(duzhn)传递参数* * ORG 0000H ORG 0000H; 主程序 MAIN MAIN:MOV SPMOV SP, #3FH #3FH;设置栈底 PUSH PUSH 31H31H; 将数a a存放到堆栈(duzhn)(duzhn)中,作为入口参数 LCALL SQR LCALL SQR; POP ACC POP ACC; MOV MOV R1 R1, A A;出口参数:a a的平方值存放在A A中 PUSH ACC PUSH ACC; LCALL SQR LCALL SQR; POP ACC POP ACC; ADD A ADD A, R1 R1; MOV MOV 33H 33H, A A; SJMP $ SJMP $;第61页/共64页第六十一页,共65页。子程序名称:SQRSQR 功能:通过查表求出平方值y=x2y=x2 入口参数:x x存放(cnfng)(cnfng)在堆栈中 出口参数:求得的平方值y y存放(cnfng)(cnfng)在堆栈中 占用资源:累加器A A,数据指针DPTRDPTR SQR SQR:MOV R0MOV R0, SP SP; R0 R0作为参数指针 DEC DEC R0 R0; 堆栈指针退回子程序调用前的地址 DEC DEC R0 R0; XCH XCH A A, R0 R0; 保护ACCACC,取出参数 MOV MOV DPTR DPTR, #TABLE #TABLE;DPTRDPTR表首地址 MOVC MOVC A A, A+DPTR A+DPTR; 查表 XCH A XCH A, R0 R0; 查表结果放回堆栈中 RET RETTABLE: DBTABLE: DB 0 0,1 1,4 4,9 9,1616,2525,3636,4949,6464,8181第62页/共64页第六十二页,共65页。(3 3)子程序调用中应注意的问题 由于子程序调用过程中,CPUCPU自动使用了堆栈,因此,容易出现以下几种错误: a a)忘记给堆栈指针SPSP赋栈底初值,堆栈初始化位置与第1 1组工作寄存器重合,如果以不同的方式使用了同一个内存区域,会导致程序乱套。 b b)程序中的PUSHPUSH和POPPOP没有配对使用,使RETRET指令执行时不能弹出正确的断点地址,造成返回错误。 c c)堆栈设置太小,堆栈操作增长(zngzhng)(zngzhng)太大,使栈区与其它内存单元重合。第63页/共64页第六十三页,共65页。感谢您的欣赏(xnshng)!第64页/共64页第六十四页,共65页。内容(nirng)总结4.1 单片机程序程序设计语言概述。此题中,偏移量=1010H-1009H=07H。伪指令是程序设计人员发给汇编程序的指令,也称汇编命令或汇编程序控制指令。查表时,为确定数据区的起始地址,可采用两种方法:。这样(zhyng)不但减少了编程工作量,而且也缩短了程序的长度。调用和返回构成了子程序调用的完整过程。在子程序执行完后需恢复这些单元的内容,称为恢复现场。通过寄存器A传递入口参数和出口参数。感谢您的欣赏第六十五页,共65页。
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号