本门课程硬件平台为ATMEL公司的AT89C52单片机,在Proteus软件进行仿真实验。
51单片机是8位单片机、8k ROM 、256bytes RAM、四个8位并行I/O口
本门课程使用汇编语言编程。
;汇编语言指令格式
[标号:] 操作码 [第一操作数] [,第二操作数] [,第三操作数] [;注释]
操作码 | 操作数 | 字节数 | 周期数 |
---|---|---|---|
数据传递类指令 | |||
MOV | A,Rn | 寄存器传送到累加器 | 1 |
MOV | A,direct | 直接地址传送到累加器 | 2 |
MOV | A,@Ri | 累加器传送到外部RAM(8 地址) | 1 |
MOV | A,#data | 立即数传送到累加器 | 2 |
MOV | Rn,A | 累加器传送到寄存器 | 1 |
MOV | Rn,direct | 直接地址传送到寄存器 | 2 |
MOV | Rn,#data | 累加器传送到直接地址 | 2 |
MOV | direct,Rn | 寄存器传送到直接地址 | 2 |
MOV | direct,direct | 直接地址传送到直接地址 | 3 |
MOV | direct,A | 累加器传送到直接地址 | 2 |
MOV | direct,@Ri | 间接RAM 传送到直接地址 | 2 |
MOV | direct,#data | 立即数传送到直接地址 | 3 |
MOV | @Ri,A | 直接地址传送到直接地址 | 1 |
MOV | @Ri,direct | 直接地址传送到间接RAM | 2 |
MOV | @Ri,#data | 立即数传送到间接RAM | 2 |
MOV | DPTR,#data16 | 16 位常数加载到数据指针 | 3 |
MOVC | A,@A+DPTR | 代码字节传送到累加器 | 1 |
MOVC | A,@A+PC | 代码字节传送到累加器 | 1 |
MOVX | A,@Ri | 外部RAM(8 地址)传送到累加器 | 1 |
MOVX | A,@DPTR | 外部RAM(16 地址)传送到累加器 | 1 |
MOVX | @Ri,A | 累加器传送到外部RAM(8 地址) | 1 |
MOVX | @DPTR,A | 累加器传送到外部RAM(16 地址) | 1 |
PUSH | direct | 直接地址压入堆栈 | 2 |
POP | direct | 直接地址弹出堆栈 | 2 |
XCH | A,Rn | 寄存器和累加器交换 | 1 |
XCH | A, direct | 直接地址和累加器交换 | 2 |
XCH | A, @Ri | 间接RAM 和累加器交换 | 1 |
XCHD | A, @Ri | 间接RAM 和累加器交换低4 位字节 | 1 |
(算术运算类指令) | |||
INC | A | 累加器加1 | 1 |
INC | Rn | 寄存器加1 | 1 |
INC | direct | 直接地址加1 | 2 |
INC | @Ri | 间接RAM 加1 | 1 |
INC | DPTR | 数据指针加1 | 1 |
DEC | A | 累加器减1 | 1 |
DEC | Rn | 寄存器减1 | 1 |
DEC | direct | 直接地址减1 | 2 |
DEC | @Ri | 间接RAM 减1 | 1 |
MUL | AB | 累加器和B 寄存器相乘 | 1 |
DIV | AB | 累加器除以B 寄存器 | 1 |
DA | A | 累加器十进制调整 | 1 |
ADD | A,Rn | 寄存器与累加器求和 | 1 |
ADD | A,direct | 直接地址与累加器求和 | 2 |
ADD | A,@Ri | 间接RAM 与累加器求和 | 1 |
ADD | A,#data | 立即数与累加器求和 | 2 |
ADDC | A,Rn | 寄存器与累加器求和(带进位) | 1 |
ADDC | A,direct | 直接地址与累加器求和(带进位) | 2 |
ADDC | A,@Ri | 间接RAM 与累加器求和(带进位) | 1 |
ADDC | A,#data | 立即数与累加器求和(带进位) | 2 |
SUBB | A,Rn | 累加器减去寄存器(带借位) | 1 |
SUBB | A,direct | 累加器减去直接地址(带借位) | 2 |
SUBB | A,@Ri | 累加器减去间接RAM(带借位) | 1 |
SUBB | A,#data | 累加器减去立即数(带借位) | 2 |
(逻辑运算类指令) | |||
ANL | A,Rn | 寄存器“与”到累加器 | 1 |
ANL | A,direct | 直接地址“与”到累加器 | 2 |
ANL | A,@Ri | 间接RAM“与”到累加器 | 1 |
ANL | A,#data | 立即数“与”到累加器 | 2 |
ANL | direct,A | 累加器“与”到直接地址 | 2 |
ANL | direct, #data | 立即数“与”到直接地址 | 3 |
ORL | A,Rn | 寄存器“或”到累加器 | 1 |
ORL | A,direct | 直接地址“或”到累加器 | 2 |
ORL | A,@Ri | 间接RAM“或”到累加器 | 1 |
ORL | A,#data | 立即数“或”到累加器 | 2 |
ORL | direct,A | 累加器“或”到直接地址 | 2 |
ORL | direct, #data | 立即数“或”到直接地址 | 3 |
XRL | A,Rn | 寄存器“异或”到累加器 | 1 |
XRL | A,direct | 直接地址“异或”到累加器 | 2 |
XRL | A,@Ri | 间接RAM“异或”到累加器 | 1 |
XRL | A,#data | 立即数“异或”到累加器 | 2 |
XRL | direct,A | 累加器“异或”到直接地址 | 2 |
XRL | direct, #data | 立即数“异或”到直接地址 | 3 |
CLR | A | 累加器清零 | 1 |
CPL | A | 累加器求反 | 1 |
RL | A | 累加器循环左移 | 1 |
RLC | A | 带进位累加器循环左移 | 1 |
RR | A | 累加器循环右移 | 1 |
RRC | A | 带进位累加器循环右移 | 1 |
SWAP | A | 累加器高、低4 位交换 | 1 |
(控制转移类指令) | |||
JMP | @A+DPTR | 相对DPTR 的无条件间接转移 | 1 |
JZ | rel | 累加器为0 则转移 | 2 |
JNZ | rel | 累加器为1 则转移 | 2 |
CJNE | A,direct,rel | 比较直接地址和累加器,不相等转移 | 3 |
CJNE | A,#data,rel | 比较立即数和累加器,不相等转移 | 3 |
CJNE | Rn,#data,rel | 比较寄存器和立即数,不相等转移 | 2 |
CJNE | @Ri,#data,rel | 比较立即数和间接RAM,不相等转移 | 3 |
DJNZ | Rn,rel | 寄存器减1,不为0 则转移 | 3 |
DJNZ | direct,rel | 直接地址减1,不为0 则转移 | 3 |
NOP | 空操作,用于短暂延时 | 1 | |
ACALL | add11 | 绝对调用子程序 | 2 |
LCALL | add16 | 长调用子程序 | 3 |
RET | 从子程序返回 | 1 | |
RETI | 从中断服务子程序返回 | 1 | |
AJMP | add11 | 无条件绝对转移 | 2 |
LJMP | add16 | 无条件长转移 | 3 |
SJMP | rel | 无条件相对转移 | 2 |
(布尔指令) | |||
CLR | C | 清进位位 | 1 |
CLR | bit | 清直接寻址位 | 2 |
SETB | C | 置位进位位 | 1 |
SETB | bit | 置位直接寻址位 | 2 |
CPL | C | 取反进位位 | 1 |
CPL | bit | 取反直接寻址位 | 2 |
ANL | C,bit | 直接寻址位“与”到进位位 | 2 |
ANL | C,/bit | 直接寻址位的反码“与”到进位位 | 2 |
ORL | C,bit | 直接寻址位“或”到进位位 | 2 |
ORL | C,/bit | 直接寻址位的反码“或”到进位位 | 2 |
MOV | C,bit | 直接寻址位传送到进位位 | 2 |
MOV | bit, C | 进位位位传送到直接寻址 | 2 |
JC | rel | 如果进位位为1 则转移 | 2 |
JNC | rel | 如果进位位为0 则转移 | 2 |
JB | bit,rel | 如果直接寻址位为1 则转移 | 3 |
JNB | bit,rel | 如果直接寻址位为0 则转移 | 3 |
JBC | bit,rel | 直接寻址位为1 则转移并清除该位 | 2 |
伪指令 | 格式 | ||
DS | 〔标号:〕 DS 表达式值 | 预留存储区命令 | |
BIT | 字符名称 BIT 位地址 | 定义位命令 | |
USING | 再定位段名 SEGMENT 段类型〔再定位类型〕 | 用来声明一个再定位段和一个可选的再定位类型。 | |
RSEG | RSEG 段名 | 再定位段选择指令 | |
CSEG | CSEG [AT 绝对地址表达式] | 绝对代码段 | |
DSEG | DSEG [AT 绝对地址表达式] | 内部绝对数据段 | |
XSEG | XSEG [AT 绝对地址表达式] | 外部绝对数据段 | |
ISEG | ISEG [AT 绝对地址表达式] | 内部间接寻址数据段 | |
BSEG | BSEG [AT 绝对地址表达式] | 绝对位寻址数据段 | |
ORG | ORG 表达式 | 设定一个新的程序起始地址 | |
END | |||
EQU | 符号名 EQU 表达式 | 将一个数值或寄存器名赋给一个指定的符号名 | |
DATA | 符号名 DATA 表达式 | 将一个内部 RAM 的地址赋给指定的符号名 | |
DB | 标号:] DB 表达式表 | 以表达式的值的字节形式初始化代码空间 |
这里进行说明,提示是否添加.s文件,这个是51单片机的启动文件。在用c语言进行编程的时候,是要电机“是”来添加一个启动文件的。在实验课上用汇编语言编写程序并不需要这个启动文件。
这样之后就可以在右侧的编辑页面进行编程了
因为手上没有开发板,实验课都是用的proteus仿真软件进行51单片机的仿真。
老师给的软件版本是8.7SP3但是因为我这里破解出了问题总是闪退还没解决,就用了8.6版本。在这里附上一个Proteus8.7闪退解决办法,可以作为参考。可能是因为盗版系统的原因,这个办法似乎在我的电脑上面并不适用。
下面开始使用
然后一路点击下一步直到出现原理图界面,中间的选项全部保持默认即不创建pcb,不创建pcb布板设计,没有固件项目
在原理图界面鼠标中键单击一下可以移动界面,再次单击退出移动。
鼠标左键单击元件可以选中元件,再次单击可更改元件属性,右键可进行元件的旋转等操作。
单击元件可选中,再次单击编辑元件
第一节课内容为安装和认识keil4集成开发环境。上文已经详细记录。
万物始于LED。
第二节课的内容是学会使用Proteus进行仿真和点亮一个LED。
Proteus软件的简单使用在上文已经记录。
汇编程序如下:
ORG 0100H
SETB P2.0
SJMP $ ;无条件相对转移 $就是本句语言的指针地址
;SJMP $,就是硬件部分
END
点亮一个灯之后就是点亮流水灯了。
汇编程序:
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN:
MOV A,#80H
LOOP:
MOV P2,A
LCALL DELAY
RR A
LJMP LOOP
DELAY:
MOV R2,#255
D1:MOV R3,#250
D2:DJNZ R3,D2 ;寄存器减1,不为0 则转移
DJNZ R2,D1
RET
END
要实现流水灯效果,只需要让累加器A中的1000 0000循环右移,中间加 以延时即可。延时要足够长,否则会看到所有的灯都是亮的。
延时程序分为两层的循环,D1和D2,分别用到R2、R3两个寄存器。两个八位寄存器,那对应的数字就是0~255注意给寄存器传送立即数时不要超过255。
硬件连接如图。
在用Proteus进行仿真时,不需要搭建完整的实验电路,只需要搭建本次实验所需的部分的功能电路即可进行仿真。所以可以不搭建晶振和复位等电路。
第四节课是用单片机驱动数码管。
数码管实质上就是LED灯的并联。abcdefg七段显示数字,八段数码管比七段数码管多了一个小数点段h。分为共阴数码管和共阳数码管,在Proteus软件中有这么多数码管可供选择
带有anode描述的即为共阳数码管,其com端接地,输入高电平使对应的段发光。
带有cathode描述的即为共阴数码管,其com端接vcc,输入低电平使对应的段发光。
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN:
MOV DPTR,#TAB
MOV R2,#0
MOV R3,#17
LOOP:
MOV A,R2
MOVC A,@A+DPTR
MOV P2,A
CPL A ;累加器求反
MOV P3,A
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
INC R2
DJNZ R3,LOOP
LJMP MAIN
DELAY:
MOV R4,#250
D1:MOV R5,#250
D2:DJNZ R5,D2
DJNZ R4,D1
RET
TAB:
DB 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0X08,0X03,0X46,0X21,0X06,0x0e
END
前四节课的内容大概就是这些,欢迎指正其中的错误,欢迎各路大佬给些学习意见
后面的几节课笔记也发出来咯单片机实验笔记(汇编、Proteus仿真)(下)