汇编程序周期性任务及开发板点灯和汇编语言求平方代码实现

目录

一、周期性点亮LED灯

1.1汇编语言分析,延时计算     

1.2循环延时

1.3NOP指令

1.4实现约1sLED灯周期变化

二、普中单片机实验开发板实现LED灯闪烁

2.1普中开发版:

2.2Keil中写代码

2.3连接开发板完成点灯实验:

三、汇编语言求平方代码实现

3.1采用查表法汇编程序

3.2在Edsim中验证此程序

3.3在Keil中:

四、总结

一、周期性点亮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
10+200+250+100000+1000000=1100451 微秒,换算约 1 秒,大概时间择为1s

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
  1. ORG 0000H:指令的起始地址被设置为 0000H,即指令从存储器的起始地址开始执行。
  2. LJMP A1:进行长跳转指令,跳转到标签 A1 处执行。
  3. ORG 0080H:设置下一条指令的地址为 0080H,即代码段的偏移地址。
  4. A1: NOP:在地址 0080H 处定义了一个标签 A1,并在其下方插入了两个 NOP 指令,用于延迟执行或者占位。
  5. MOV SP,#60H:将立即数 60H(相当于十进制的 96)移动到堆栈指针 SP 中,这个操作可能是为了初始化堆栈指针。
  6. MOV DPTR,#2000H:将立即数 2000H 移动到数据指针 DPTR 中,这可能是为了设置数据指针的初始位置。
  7. MOV A,#03H:将立即数 03H(十进制的 3)移动到累加器 A 中。
  8. MOVC A,@A+DPTR:执行 MOVC(Move Code Byte)指令,从以 DPTR 寄存器和 A 寄存器指定的地址中取得一个字节的数据并将其移动到累加器 A 中。在这个例子中,A 中的值是 03H,所以它将从 DPTR+03H 的地址中取得一个字节的数据。
  9. A2: SJMP A2:在地址 0088H 处定义了一个标签 A2,并在其下方插入了一个 SJMP(无条件短跳转)指令,使程序无限循环跳转到 A2 标签处。
  10. ORG 2000H:设置下一条指令的地址为 2000H,这是数据段的偏移地址。
  11. DB 01h,04h,09h,10h,19h,24h,31h,40h,51h:在地址 2000H 处定义了一个字节序列,其中包含了多个字节的数据,分别是 01h、04h、09h、10h、19h、24h、31h、40h 和 51h。
  12. END:表示程序结束。

3.2在Edsim中验证此程序

确定位置,寻找数值。

3.3在Keil中:

创建相关程序,导入代码;

按照如下步骤依次

1.点击红色仿真按钮窗口

2.调出Memory窗口,查看地址

3.点击RUN,运行

可以得到相对应的16进制数目。

四、总结

通过本次的实验学习,本文章中主要呈现了汇编程序实现延时、开发板点灯和汇编语言求平方代码实现三个方面来进行呈现,本人也从中进一步加深了对汇编代码的理解,对仿真51单片机软件的进一步深入了解,对keil软件中的应用也得到了熟练应用,同时通过实现对普中开发板的LED灯点亮和烧录,学会了使用相关软件,理解汇编语言,了解代码。当然,本人所学知识有限,文章中内容存在不严谨语言和错误之处,还望各位积极指出,感谢你的阅读。

  • 28
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值