51单片机架构与汇编指令
一. 安装Proteus8软件,使用AT89C51单片机的外部引脚,点亮1个LED灯。采用汇编指令完成。
AT89C51单片机
51单片机由一个IP核和片上外设组成,IP核(内核)就是CPU,片上外设就是:时钟电路、SFR和RAM、ROM、定时/计数器、并行I/O口、串行I/O口、中断系统。IP核跟外设之间由系统总线连接,且是8bit的,速度有限。
51内核是上个世纪70年代Intel公司设计的,速度只有12M,外设是IC厂商(STC)在内核的基础上添加的,不同的IC厂商会在内核上添加不同的外设,从而设计出各具特色的单片机。
汇编语言
汇编指令是汇编语言中使用的一些操作符和助记符,还包括一些伪指令(如assume,end),汇编指令同机器指令一一对应。每一种CPU都有自己的汇编指令集。计算机是通过执行指令来处理数据的,为了指出数据的来源、操作结果的去向及所执行的操作,一条指令一般包含操作码和操作数两部分。指令是计算机能够识别和执行的操作命令,由二进制数“0”、“1”组成。每条指令的编码格式由机器指令系统规定。
1、汇编语言
ORG 0100H
SETB P2.0
SJMP $
END
- ORG 0100H:设置程序的起始地址为0100H,表示程序从地址0100H处开始执行。
- SETB P2.0:将P2寄存器的第0位设为1,即设置P2寄存器的第0位为1。
- SJMP $:无条件跳转指令,跳转到当前指令的地址,实现一个无限循环。
- END:指示程序结束。
用51汇编语言和C语言编程,实现流水灯正常工作。
1、51汇编语言
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN:
MOV A,#0FEH
LOOP:
MOV P0,A
LCALL DELAY
RL A
LJMP LOOP
DELAY:
MOV R2,#255
D1:MOV R3,#250
D2:DJNZ R3,D2
DJNZ R2,D1
RET
END
-
ORG 0000H:设置程序的起始地址为0000H,表示程序从地址0000H处开始执行。
-
LJMP MAIN:无条件跳转指令,跳转到标签MAIN处执行。
-
ORG 0100H:设置程序的起始地址为0100H。
-
MAIN::标签,表示程序的入口处。
-
MOV A,#0FEH:将立即数0FEH(带符号的十六进制数)移动到寄存器A中。
-
LOOP::标签,定义一个循环开始处。
-
MOV P0,A:将寄存器A中的值移动到P0端口。
-
LCALL DELAY:调用子程序DELAY。
-
RL A:将A寄存器的值向右循环移位。
-
LJMP LOOP:无条件跳转到LOOP处,实现循环。
-
DELAY::定义了一个子程序DELAY。
-
MOV R2,#255:将立即数255移动到寄存器R2中。
-
D1::标签,用于延时循环开始处。
-
MOV R3,#250:将立即数250移动到寄存器R3中。
-
D2::标签,用于内部延时循环开始处。
-
DJNZ R3,D2:R3不为零时跳转到标签D2处,实现内部延时。
-
DJNZ R2,D1:R2不为零时跳转到标签D1处,实现整体延时。
-
RET:子程序返回。
-
END:指示程序结束。
-
该程序会在P0端口的LED灯上实现流水灯效果。MOV指令用于设置P0的端口值, DELAY指令用于创建延迟,使用三个寄存器(R2、R3、R4)实现一个简单的循环延迟。DJNZ指令用于在寄存器的值不为0的时候进行循环,当寄存器的值减到0时,程序返回调用DELAY的地方,让流水灯效果持续进行。
2、C语言编程
#include <reg51.h>
#include <intrins.h>
void delay_ms(int a)
{
}
int i,j;
for(i=0;i<a;i++)
{
}
for(j=0;j<1000;j++) _nop_();
void main(void)
{
while(1)
{
P0=0xfe;
delay_ms(50);
P0=0xfd;
delay_ms(50);
P0=0xfb;
delay_ms(50);
P0=0xf7;
delay_ms(50);
P0=0xef;
delay_ms(50);
P0=0xdf;
delay_ms(50);
P0=0xbf;
delay_ms(50);
P0=0x7f;
delay_ms(50);
}
}
该程序会在P0端口的LED灯上实现流水灯效果,每次循环都会点亮下一个LED灯。delay_ms函数用于产生延迟,以便可以观察到LED灯的切换。nop()用于生成一个时钟周期的延迟,该指令是一个空操作。main函数中,通过一个无限循环实现流水灯的效果,每次循环中,通过修改P0端口的输出值来控制连接在P0端口上的LED灯的亮灭。
3、原理图
首先选择一个微控制器(AT89C51),有足够的I/O端口来控制多个LED灯。选择一定数量的LED灯,一个LED灯对应一个I/O端口。每个LED灯都需要一个限流电阻来限制流过LED的电流,防止过载。选择一个电源为整个电路供电,将微控制器的I/O端口连接到LED灯和限流电阻