目录
一、周期性点亮LED灯
1.1汇编语言分析,延时计算
在汇编语言编程中,延时计算通常用于控制程序执行的速度或者等待外部事件的发生。延时的实现方式可以是通过循环计数、空操作指令、或者定时器等硬件设备。
实现LED灯闪烁的代码:
ORG 10 ;起始地址,设置起始地址为10。这表示程序将从存储器的地址10处开始执行。
START:SETB P1.0 ;端口置1 将P1.0引脚置为高电平(1),这通常用于控制外部设备或指示LED等。
LCALL DELAY ;调用延时函数DELAY,延时一定时间。
CLR P1.0 ;将P1.0引脚清零(低电平)。
LCALL DELAY ;再次调用延时函数DELAY,延时一定时间。
AJMP START ;无条件跳转到START标签处,使程序继续循环执行。
DELAY: MOV R7,#250 ;将立即数250加载到寄存器R7中,用于内部计数以实现延时。
D1: MOV R6,#250 ;1us*250
D2: DJNZ R6,D2 ; 将R6中的值递减1,如果R6不为0,则跳转到D2标签处继续循环。
DJNZ R7,D1 ;将R7中的值递减1,如果R7不为0,则跳转到D1标签处继续循环,用于实现外部循环,延长延时时间。
RET ;返回主函数
END ;指令结束
对于上述代码,我们可以看到汇编程序的代码和相关解释,对于每个指令的时间,通过查阅资料可得到:
延时程序与MCS—51指令执行时间有很大的关系。在使用12MHz晶振时,一个机器周期为1us,执行一条DJNZ指令的时间为2us。MOV运行需要1微秒。
上述代码使用两个寄存器R6和R7来进行计数。R7被初始化为250,而R6在每次R7循环时也被初始化为250。每次R6减到0时,它会被重新加载为250,然后R7减1。当R7也减到0时,循环结束。
计算总的循环次数时需要考虑两个循环的嵌套。R6每减少一次,都会执行一个内部的循环,循环在R6再次减到0之前会执行250次。这个内部循环会重复R7次,即250次。
时长计算:
ORG 10 ;起始地址,设置起始地址为10。
START:SETB P1.0 ;端口置1 1us
LCALL DELAY ;调用延时函数DELAY,延时一定时间。2us
CLR P1.0 ;1us
LCALL DELAY ;2us
AJMP START ;2us
DELAY: MOV R7,#250 ;将立即数250加载到寄存器R7中,用于内部计数以实现延时。1us
D1: MOV R6,#250 ;1us
D2: DJNZ R6,D2 ; 将R6中的值递减1,如果R6不为0,则跳转到D2标签处继续循环。250*2=500us
DJNZ R7,D1 ;将R7中的值递减1 0.5ms*250=12.5ms
RET ;返回主函数
END ;指令结束
计算得到:1+2+1+2+2+(1+1+250*2+500*250+2)*2=251016us=251ms 16us
我们可以计算得到目前延时大概为251ms左右。
1.2循环延时
上述代码是实现了二重循环,想要增加延时时间,我们可以采用三重循环:
DELAY:MOV R5,#10
D1: MOV R6,#200 ;10μs
D2: MOV R7,#250 ;200μs
DJNZ R7,$ ;250 * 2=500μs
DJNZ R6,D2 ;250 * 200 * 2=100000μs
DJNZ R5,D1 ;250 * 200 * 10 * 2 = 1000000μs
RET
1.3NOP指令
NOP(No Operation)指令是一种在大多数计算机体系结构中都存在的基本指令,它不执行任何操作并且不改变处理器状态。在汇编语言中,NOP通常用作占位符或者延迟执行,有时也用于调试目的。其作用是保持程序的结构完整性,或者在需要填充一些指令位置时使用。NOP指令的编码通常是固定的,它只会占用一个时钟周期,并且不会修改任何寄存器或者存储器的内容。
1.4实现约1sLED灯周期变化
结合上述,得到延时1s左右的LED灯闪烁汇编代码为:
ORG 10 ;起始地址,设置起始地址为10。
START:SETB P1.0 ;端口置1 1us
LCALL DELAY ;调用延时函数DELAY,延时一定时间。2us
CLR P1.0 ;1us
LCALL DELAY ;2us
AJMP START ;2us
DELAY:MOV R5,#10
D1: MOV R6,#200 ;10μs
D2: MOV R7,#250 ;200μs
DJNZ R7,$ ;250 * 2=500μs
DJNZ R6,D2 ;250 * 200 * 2=100000μs
DJNZ R5,D1 ;250 * 200 * 10 * 2 = 1000000μs
RET
END ;指令结束
结果如图所示:
结合仿真软件提供的时间计算,刚好实现1s灯光闪烁。
二、普中单片机实验开发板实现LED灯闪烁
2.1普中开发版:
软件准备: STC-ISP软件
使用指南参考:https://blog.csdn.net/qq_28576837/article/details/125712180
2.2Keil中写代码
生成HEX文件,本操过程与之前博客汇编代码点亮LED灯类似,在此不再过多论述。
创建工程>新建文件>编写代码>保存为,c文件>把 编写代码加入到工程中>点击魔法棒>导出>生成HEX文件
LED灯闪烁代码:
#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)
{
P2=0x01;
delay_ms(50);
P2=0x00;
de lay_ms(50);
}
}
流水灯代码;
#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);
}
}
查看高低电平变化图:
2.3连接开发板完成点灯实验:
点亮LED灯:LED闪烁
流水灯烧录:
三、汇编语言求平方代码实现
3.1采用查表法汇编程序
ORG 0000H ;定义下一条的指令放在地址为0000H存储器
LJMP A1 ;长跳转指令至A1
ORG 0080H
A1: NOP
NOP
MOV SP,#60H
MOV DPTR,#2000H
MOV A,#03H ;对应A2的DB中的第3位
MOVC A,@A+DPTR
A2: SJMP A2
ORG 2000H
DB 01h,04h,09h,10h,19h,24h,31h,40h,51h
END
- ORG 0000H:指令的起始地址被设置为 0000H,即指令从存储器的起始地址开始执行。
- LJMP A1:进行长跳转指令,跳转到标签 A1 处执行。
- ORG 0080H:设置下一条指令的地址为 0080H,即代码段的偏移地址。
- A1: NOP:在地址 0080H 处定义了一个标签 A1,并在其下方插入了两个 NOP 指令,用于延迟执行或者占位。
- MOV SP,#60H:将立即数 60H(相当于十进制的 96)移动到堆栈指针 SP 中,这个操作可能是为了初始化堆栈指针。
- MOV DPTR,#2000H:将立即数 2000H 移动到数据指针 DPTR 中,这可能是为了设置数据指针的初始位置。
- MOV A,#03H:将立即数 03H(十进制的 3)移动到累加器 A 中。
- MOVC A,@A+DPTR:执行 MOVC(Move Code Byte)指令,从以 DPTR 寄存器和 A 寄存器指定的地址中取得一个字节的数据并将其移动到累加器 A 中。在这个例子中,A 中的值是 03H,所以它将从 DPTR+03H 的地址中取得一个字节的数据。
- A2: SJMP A2:在地址 0088H 处定义了一个标签 A2,并在其下方插入了一个 SJMP(无条件短跳转)指令,使程序无限循环跳转到 A2 标签处。
- ORG 2000H:设置下一条指令的地址为 2000H,这是数据段的偏移地址。
- DB 01h,04h,09h,10h,19h,24h,31h,40h,51h:在地址 2000H 处定义了一个字节序列,其中包含了多个字节的数据,分别是 01h、04h、09h、10h、19h、24h、31h、40h 和 51h。
END
:表示程序结束。
3.2在Edsim中验证此程序
确定位置,寻找数值。
3.3在Keil中:
创建相关程序,导入代码;
按照如下步骤依次
1.点击红色仿真按钮窗口
2.调出Memory窗口,查看地址
3.点击RUN,运行
可以得到相对应的16进制数目。
四、总结
通过本次的实验学习,本文章中主要呈现了汇编程序实现延时、开发板点灯和汇编语言求平方代码实现三个方面来进行呈现,本人也从中进一步加深了对汇编代码的理解,对仿真51单片机软件的进一步深入了解,对keil软件中的应用也得到了熟练应用,同时通过实现对普中开发板的LED灯点亮和烧录,学会了使用相关软件,理解汇编语言,了解代码。当然,本人所学知识有限,文章中内容存在不严谨语言和错误之处,还望各位积极指出,感谢你的阅读。