汇编程序与周期性任务设计

本文介绍了如何通过汇编语言设计周期性任务,如延时函数,实现LED灯的定时点亮。详细讲解了软件多重循环和使用循环+nop指令的方法,并给出了精确控制LED灯每隔1秒亮灭的修改示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汇编程序与周期性任务设计

一.实验任务

1.深入了解汇编指令和常用程序结构,以周期性点亮LED灯的延时函数为例,掌握 1)通过软件多重循环软件计数的定时方法 ;2)通过 循环+ nop 指令的方法;
二重循环
DELAY: MOV R7,#150 
D1: MOV R6,#250 
D2: DJNZ R6,D2 		;150 * 2=300μs
	 DJNZ R7,D1		;150 * 250 * 2μs=0.075S
	 RET
循环+ nop 指令

一个周期只能用于一次CPU寻址或处理,在汇编标准里一个NOP是会和CPU架构对齐的,达到内存对齐,而一个时钟周期只能完成一次寻址或处理指令,所以NOP也就占用一个时钟周期!也就是1us(1us=0.000001s)

MOV R1,#0FEH
LOOP:			;LOOP英文为循环的意思
MOV P1,#0FEH 
DJNZ R1,LOOP 
NOP
NOP
MOV P1,#0FDH    
2.掌握汇编语言用查表法完成 求平方数的程序;

查表就是根据自变量x,在表格中寻找y,使y=f(x).

查找1-9的平方代码如下:

ORG 0000H
LJMP A1
ORG 0080H
A1: NOP
    NOP
    MOV SP,#60H
	MOV DPTR,#2000H
	MOV A,#03H
	MOVC A,@A+DPTR
A2: SJMP A2
	ORG 2000H
	DB 00h,01h,04h,09h,10h,19h,24h,31h,40h,51h
END
3.掌握普中单片机实验开发板的开发使用方法,在板子上完成LED周期性点灯的C程序实验。

二.具体过程

以LED闪烁为例:

LOOP:SETB 90H ;led0置1
	  LCALL DELAY ;调用延时函数
	  CLR 90H    ;led0置0
	  LCALL DELAY 
	  AJMP LOOP  ;跳转到LOOP
	
DELAY: MOV R7,#250 ;延时函数
D1:	   MOV R6,#250
D2:    DJNZ R6,D2
	   DJNZ R7,D1
	   RET  ;返回主函数
	   END ;指令结束

1)请查阅汇编指令 “MOV R6,#250”和“DJNZ R6,D2”的指令周期数,计算其对应的时钟周期 us值;然后计算 Delay函数的总的循环次数和对应的时钟周期总数us, 说明这个LED灯大约每隔多少毫秒(ms)或秒(s)才变化一次亮灭状态;

“MOV R6,#250”和“DJNZ R6,D2”的指令其对应的时钟周期为500us

在8051微控制器中,如果使用一个12MHz的晶振,每个机器周期(即时钟周期)为1/(12MHz) = 约83.33ns。

对于主循环中的每条指令:

  • SETB 90H:1个机器周期
  • LCALL DELAY:2个机器周期
  • CLR 90H:1个机器周期
  • LCALL DELAY:2个机器周期
  • AJMP LOOP:2个机器周期

因此,主循环一次的总机器周期数为1 + 2 + 1 + 2 + 2 = 8个机器周期。

对于DELAY函数中的指令:

  • MOV R7,#250:1个机器周期
  • MOV R6,#250:1个机器周期
  • DJNZ R6,D2:2个机器周期(每次循环)
  • DJNZ R7,D1:2个机器周期(每次外层循环)
  • RET:2个机器周期

DELAY函数的总机器周期数为1 + 1 + (2 * 250) + (4 * 250) + 2 = 1506个机器周期。

现在我们可以计算总的机器周期数。由于DELAY函数在主循环中被调用了两次,所以总的机器周期数为:

总机器周期数 = 主循环的机器周期数 * 亮灭变化次数 + DELAY函数的机器周期数 * 亮灭变化次数
= 8 * 亮灭变化次数 + 1506 * 亮灭变化次数
= (8 + 1506) * 亮灭变化次数
= 1514 * 亮灭变化次数

如果我们假设LED灯闪烁一次代表一次亮灭变化,则总时间为:

总时间(us)= 总机器周期数 * 每个机器周期的时间(us)
= 1514 * 亮灭变化次数 * 83.33ns
= 126.161us * 亮灭变化次数

将时间转换为毫秒(ms),我们得到:

总时间(ms)= 总时间(us)/ 1000
= (126.161us * 亮灭变化次数) / 1000
= 0.126161ms * 亮灭变化次数

因此,如果LED灯闪烁一次代表一次亮灭变化,那么这个LED灯大约每隔0.126161ms才变化一次亮灭状态。

2)如果要求你实现准确的LED 每隔1s亮灭的周期性变化,上面程序如何修改?请给出完整代码。请在edsim51中进行实践练习。
ORG 10 
START:SETB P1.0 
	  LCALL DELAY 
	  CLR P1.0    
	  LCALL DELAY 
	  AJMP START  
	
DELAY:	MOV R5,#25
DELAY1: MOV R6,#100
DELAY2: MOV R7,#100
		DJNZ R7,$
		DJNZ R6,DELAY2
		DJNZ R5,DELAY1
		RET	  
 END 

在这里插入图片描述

*文章多有不足,欢迎指正

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值