1、电子教案单片机原理与应用技术第 1 页 共 12 页第1章 汇编语言程序设计80C51 汇编,语言语句结构的基本格式伪指令的功能和应用汇编的概念程序设计的步骤和基本方法顺序程序分支程序循环程序查表程序散转程序1-1 汇编语言一. 汇编语言及其语句结标号:操作码 目的操作数,源操作数 ;注释二. 伪指令在汇编时起控制作用,自身并不产生机器码,而仅是为汇编服务的一些指令,称为伪指令。伪指令不属于 80C51 指令系统。常用的伪指令有以下几种: 起始伪指令 ORG(Origin)格式:ORG 16 位地址 结束伪指令 END格式:功能:汇编语言源程序的结束标志。在 END 后面的指令,汇编程序不再处
2、理。 等值伪指令 EQU(Equate)格式:字符名称 EQU 数据或汇编符号 数据地址赋值伪指令 格式:字符名称 DATA 表达式功能:将一个数据或特定的汇编符号赋予规定的字符名称。 定义字节伪指令 DB(Define Byte)格式:DB 8 位二进制数表功能:从指定的地址单元开始,定义若干 个 8 位内存单元的数据。数据与数据之间用“, ”分割。 定义字伪指令 DW(Define Word)格式:DW 16 位二进制数表功能:从指定的地址单元开始,定义 若干个 16 位数据。 定义位地址伪指令格式:字符名称 BIT 位地址功能:将位地址赋予所规定的字符名称。三.汇编将汇编语言源程序转换为
3、计算机所能识别的机器语言代码程序的过程称为汇编。汇编可分为: 手工汇编第 2 页 共 12 页 计算机汇编四. 程序设计的基本方法编写程序要求:不仅要完成规定的功能任务,而且还要求:执行速度快、占用内存少、条理清晰、阅读方便、便于移植、巧妙而实用。一般应按以下几个步骤进行: 分析问题,确定算法或解题思路 画流程图 编写源程序 汇编和调试第 3 页 共 12 页1-2 汇编语言程序设计举例一. 顺序程序顺序程序是指按顺序依次执行的程序,也称为简单程序或直线程序。顺序程序结构虽然比较简单,但也能完成一定的功能任务,是构成复杂程序的基础。根据不同条件转向不同的处理程序,这种结构的程序称为分支程序。8
4、0C51 指令系统中的条件转移指令、比较转移指令和位转移指令,可以实现分支程序。【例】 已知 16 位二进制负数存放在 R1R0 中, 试求其补码,并将结果存在R3R2 中解:二进制负数的求补方法可归结为“求反加 1”,符号位不变。利用 CPL 指令实现求反;加 1 时,则应低 8 位先加 1,高 8 位再加上低位的进位。注意这里不能用 INC 指令,因为INC 指令不影响标志位。程序如下:CONT: MOV A,R0 ;读低 8 位CPL A ;取反ADD A,#1 ;加 1MOV R2,A ;存低 8 位MOV A,R1 ;读高 8 位CPL A ;取反ADDC A,#80H ;加进位及符
5、号位MOV R3,A ;存高 8 位RET ;二.分支程序根据不同条件转向不同的处理程序,这种结构的程序称为分支程序。80C51 指令系统中的条件转移指令、比较转移指令和位转移指令,可以实现分支程序。 S0 单独按下,红灯亮,其余灯灭; S1 单独按下,绿灯亮,其余灯灭; 其余情况,黄灯亮。第 4 页 共 12 页解:程序如下SGNL:ANL P1,#11100011B;红绿黄灯灭ORL P1,#00000011B;置 P1.0、P1.1 输入态, P1.5P1.7 状态不变SL0: JNB P1.0,SL1 ;P1.0=0,S0 未按下,转判 S1JNB P1.1,RED ;P1.0=1,S
6、0 按下; 且 P1.1=0,S1 未按下,转红灯亮YELW:SETB P1.4 ;黄灯亮CLR P1.2 ;红灯灭CLR P1.3 ;绿灯灭SJMP SL0 ;转循环SL1: JNB P1.1,YELW ;P1.0=0,S0 未按下;P1.1=0,S1 未按下,转黄灯亮GREN:SETB P1.3 ;绿灯亮CLR P1.2 ;红灯灭CLR P1.4 ;黄灯灭SJMP SL0 ;转循环RED: SETB P1.2 ;红灯亮CLR P1.3 ;绿灯灭CLR P1.4 ;黄灯灭SJMP SL0 ;转循环 课堂练习题:电路及灯亮灭要求同上述【例】题,其中第 3、4 两条指令 JNB P1.0 和 J
7、NB P1.1按下列要求修改,试重新编程。 JB P1.0,JB P1.1, JB P1.0,JNB P1.1, JNB P1.0,JB P1.1,第 5 页 共 12 页三. 循环程序循环程序一般包括以下几个部分: 循环初值; 循环体; 循环修改; 循环控制;以上四部分可以有两种组织形式,其结构如图 4-6 所示.【例】 编制一个循环闪烁灯的程序。设 80C51 单片机的 P1 口作为输出口,经驱动电路 74LS240(8 反相三态缓冲/ 驱动器) 接 8 只发光二极管,如图 4-8 所示。当输出位为 “1”时,发光二极管点亮,输出位为“0”时为暗。试编程实现:每个灯闪烁点亮 10 次,再转
8、移到下一个灯闪烁点亮 10 次,循环不止。 解:程序如下:FLASH:MOV A,#01H ;置灯亮初值FSH0: MOV R2,#0AH ;置闪烁次数FLOP: MOV P1,A ;点亮LCALL DY1s ;延时 1sMOV P1,#00H ;熄灭LCALL DY1s ;延时 1sDJNZ R2,FLOP ;闪烁 10 次RL A ;左移一位第 6 页 共 12 页SJMP FSH0 ;循环RET ;【例】设 Xi 均为单字节数,并按顺序存放在以 50H 为首地址的内 RAM 存储单元中,数据长度(个数)N 存在 R2 中,试编程求和 S=X1+X2+ +XN,并将 S(双字节)存放在R3
9、R4 中, (设 S65536) 。解:程序如下: SXN: MOV R2,#N ;置数据长度(循环次数)MOV R3,#00H ;和单元( 高 8 位)清 0MOV R4,#00H ;和单元( 低 8 位)清 0MOV R0,#50H ;求和数据区首址LOOP:MOV A,R4 ;读前次低 8 位和ADD A,R0 ;低 8 位累加MOV R4,A ;存低 8 位和CLR A ;ADDC A,R3 ;高 8 位加进位MOV R3,A ;存高 8 位和INC R0 ;指向下一数据 循环修改DJNZ R2,LOOP ;判 N 个数据累加完否? 循环控制 RET ;退出循环 退出循环 【例】编写延
10、时 10ms 子程序 ,fosc=12MHz。 解:fosc=12MHz ,一个机器周期为 1s。DY10ms:MOV R6,#20 ; 置外循环次数DLP1: MOV R7,#250 ; 置内循环次数DLP2: DJNZ R7,DLP2 ; 2 机周250 =500 机周DJNZ R6,DLP1 ; 500 机周20= 10000 机周RET ;说明:MOV Rn 指令为 1 个机器周期;DJNZ 指令为 2 个机器周期;RET 指令为 2 个机器周期;(2 机周250)+1+220+1+21s/ 机周=10063s 10ms【课堂练习题】 按下列要求编写延时子程序: 延时 2ms,fosc
11、=6MHz ; 延时 5ms,fosc=12MHz ; 延时 10s,fosc=12MHz;设 80C51 单片机的 P1 口作为输出口,经驱动电路 74LS240(8 反相三态缓冲/ 驱动器)接 8 只发光二极管,如图 4-8 所示。当输出位为1时,发光二极管点亮,输出位为0时为暗。试编程实现:每个灯闪烁点亮 10 次,再转移到下一个灯闪烁点亮 10 次,循环不止。 FLASH:MOV A,#01H ;置灯亮初值FSH0: MOV R2,#0AH ;置闪烁次数FLOP: MOV P1,A ;点亮LCALL DY1s ;延时 1sMOV P1,#00H ;熄灭LCALL DY1s ;延时 1s
12、第 7 页 共 12 页DJNZ R2,FLOP ;闪烁 10 次RL A ;左移一位SJMP FSH0 ;循环RET ;【课堂练习题】根据图 4-8 电路,设计灯亮移位程序,要求 8 只发光二极管每次点亮一个,点亮时间为 250ms,顺序是从下到上一个一个地循环点亮。设 fosc=6MHz。【例】已知 P1 口数据每隔 10ms 刷新一次,试求其 1s 内的平均值 , 平均值存 30H。解:本题需求 100 个数据的平均值,一般有两种方法:一种是全部累加后再平均;另一种是边平均边累加,现给出两种方法的程序。AVRG1: MOV R2,#0 ;低 8 位累加寄存器清 0MOV R3,#0 ;高
13、 8 位累加寄存器清 0MOV R4,#100 ;置平均次数ALOP: MOV A,P1 ;读 P1 口数据ADD A,R2 ;低 8 位累加MOV R2,A ;回存CLR A ;高 8 位与进位累加ADDC A,R3 ;MOV R3,A ;回存LCALL DY10ms ;延时 10msDJNZ R4,ALOP;判 100 次累加完否?未完继续MOV A,R3 ;100 次累加完,求平均值,被除数A、BMOV B,R2 ;MOV R0,30H ;置商间址MOV R6,#0 ;置除数 100,除数R6R5MOV R5,#100 ;LCALL SUM ;(A、B)(R6、R5)= 商 R0, 余数
14、 A CJNE A,#50,NEXT ;四舍五入NEXT: JC GRET ;C=1,50, 舍INC 30H ;C=0,50, 入GRET: RET ;AVRG2: MOV 30H,#0 ;商累加寄存器清 0MOV 31H,#0 ;余数累加寄存器清 0MOV R4,#100 ;置平均次数ALOP: MOV A,P1 ;读 P1 口数据MOV B,#100 ;置除数(平均次数)DIV AB ;P1 口数据除以 100ADD A,30H ;商累加第 8 页 共 12 页MOV 30H,A ;回存MOV A,B ;ADD A,31H ;余数累加MOV 31H,A ;回存CLRC ;SUBB A,#
15、100 ;JC GON ;余数累加100,余数累加寄存器不变INC 30H ;余数累加 100, 商累加寄存器+1MOV 31H,A ;减去 100 后差余数累加寄存器GON: LCALL DY10ms ;延时 10msDJNZ R4,ALOP ;判 100 次累加完否?未完继续MOV A,31H ;100 次累加完毕,余数累加四舍五入CJNE A,#50,NEXT ;NEXT: JC GRET ;C=1,50, 舍INC 30H ;C=0,50, 入GRET: RET ;【课堂练习题】已知某单片机系统每隔 20ms 测一次温度,8 位温度 A/D 值存在特殊功能寄存器 SBUF 中,试分别求
16、其 1s 和 1 分内的平均值, 分别存 30H 和 31H。当用 PC 作基址寄存器时,其表格首地址与 PC 值间距不能超过 256 字节,且编程要事先计算好偏移量,比较麻烦。因此,一般情况下用 DPTR 作基址寄存器。解:编程如下: CHAG:MOV DPTR,#TABD;置共阴字段码表首址MOV A,30H ;读显示数字MOVC A,A+DPTR ;查表,转换为显示字段码MOV 30H,A ;存显示字段码RET ;TABD:DB 3FH,06H,5BH,4FH,66H;04 共阴字段码表DB 6DH,7DH,07H,7FH,6FH;59 共阴字段码表四. 查表程序用于查表的指令有两条:
17、MOVC A,A+DPTR MOVC A,A+PC当用 DPTR 作基址寄存器时,查表的步骤分三步: 基址值(表格首地址)DPTR; 变址值(表中要查的项与表格首地址之间的间隔字节数)A ; 执行 MOVC A,A+DPTR。当用 PC 作基址寄存器时,其表格首地址与 PC 值间距不能超过 256 字节,且编程要事先计算好偏移量,比较麻烦。因此,一般情况下用 DPTR 作基址寄存器。【例】 在单片机应用系统中,常用 LED 数码管显示数码,但显示数字(9) 与显示数字编码并不相同,需要将显示数字转换为显示字段码,通常是用查表的方法。现要求将 30H 中第 9 页 共 12 页的显示数字转换为显
18、示字段码并存入 30H。已知共阴字段码表首址为 TABD。解:编程如下: CHAG:MOV DPTR,#TABD;置共阴字段码表首址MOV A,30H ;读显示数字MOVC A,A+DPTR ;查表,转换为显示字段码MOV 30H,A ;存显示字段码RET ;TABD:DB 3FH,06H,5BH,4FH,66H;04 共DB 6DH,7DH,07H,7FH,6FH;59 共阴字段码表【例】 用查表程序求 040 之间整数的立方。已知该整数存在内 RAM 30H 中,查得立方数存内 RAM 30H(高 8 位)31H 。已知立方表( 双字节)首地址为 TAB。解:编程如下:CUBE: MOV
19、DPTR,#TAB ;置立方表首址MOV A,30H ;读数据ADD A,30H ;数据2AMOV 30H,A ;暂存立方表数据序号 MOVC A, A+DPTR;读立方数据高 8 位XCH A,30H ;存立方数据高 8 位,立方表数据序号AINC A ;指向立方数据低 8 位MOVC A,A+DPTR ;读立方数据低 8 位 MOV 31H,A ;存立方数据低 8 位RET ;TAB: DW 0,0,0,1,0,8,0,27,0,64 ;040 立方表DW 0,125,0,216,0FAH,00H;说明:数据2A 原因是立方表数据为双字节【课堂练习题】已知 8 位显示数字已存入首址为 30
20、H 的内 RAM 中,试将其转换为共阴显示字段码,存入首址为 40H 的内 RAM 中。五. 散转程序散转程序是一种并行多分支程序。【例】 单片机四则运算系统。在单片机系统中设置四个运算命令键,它们的键号分别为 0、1、2、3。当其中一个键按下时,进行相应的运算。操作数由 P1 口和 P3 口输入,运算结果仍由 P1 口和 P3 口输出。具体如下:P1 口输入被加数、被减数、被乘数和被除数,输出运算结果的低 8 位或商;P3口输入加数、减数、乘数和除数,输出进位(借位) 、运算结果的高 8 位或余数。键盘号已存放在 30H 中。解:程序如下:PRGM: MOV P1,#0FFH ;P1 口置输
21、入态MOV P3,#0FFH ;P3 口置输入态MOV DPTR,#TBJ ;置表首地址MOV A,30H ;读键号RL A ;键号 2AADD A,30H ;键号3A第 10 页 共 12 页JMP A+DPTR ;散转TBJ: LJMP PRGM0 ;转 PRGM0(加法)LJMP PRGM1 ;转 PRGM1(减法)LJMP PRGM3 ;转 PRGM3(除法)LJMP PRGM2 ;转 PRGM2(乘法)PRGM0: MOV A,P1 ;读加数ADD A,P3 ;P1+P3MOV P1,A ;和P1CLR A ;ADDC A,#00H ;进位AMOV P3,A ;进位P3RET ;PRGM1: MOV A,P1 ;读被减数CLR C ;SUBB A,P3 ;P1-P3MOV P1,A ;差P1CLR A ;RLC A ;借位 AMOV P3,A ;借位P3RET ;PRGM2: MOV A,P1 ;读被乘数MOV B,P3 ;置乘数MUL AB ;P1P3MOV P1,A ;积低 8 位P1MOV P3,B ;积高 8 位P3RET ;PRGM3: MOV A,P1 ;读被除数MOV B,P3 ;置除数DIV AB ;P1P3MOV P1,A ;商P1MOV P3,B ;余数P3RET ;说明:由于 LJMP 为 3 字节指令,因此键号需先乘 3,以便转到正确的位置。