了解汇编指令及其关于LED的运用

1. 深入了解汇编指令和常用程序结构,以周期性点亮LED灯的延时函数为例,掌握:

(1)通过多重循环计数的定时方法 ;

我们首先要了解什么是汇编语言:
汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。

了解完后我们再看到如下汇编语言:

TIMER_LED:
    MOV R7, #10        ; 外层循环计数器,控制点亮和熄灭LED的周期
OUTER_LOOP:
    MOV R6, #1000      ; 内层循环计数器,控制LED点亮时间
INNER_LOOP_ON:
    ; 点亮LED的操作,例如将LED端口的相应位设置为1

    DJNZ R6, INNER_LOOP_ON   ; 内层循环,LED点亮时间
    MOV R6, #1000      ; 重置内层循环计数器
INNER_LOOP_OFF:
    ; 熄灭LED的操作,例如将LED端口的相应位设置为0

    DJNZ R6, INNER_LOOP_OFF   ; 内层循环,LED熄灭时间
    DJNZ R7, OUTER_LOOP       ; 外层循环,控制整个周期
    RET

在这个代码中,外层循环控制整个周期的间隔,内层循环控制LED点亮和熄灭的时间。你可以根据需要调整R7和R6的值来改变LED点亮和熄灭的周期和持续时间。

(2)通过 循环+ nop 指令的方法;

NOP指令(No Operation)是一个空操作指令,也是汇编语言中的一种指令,它不执行任何操作,仅占用一个CPU周期。在汇编语言中,NOP指令通常用于延时或者填充代码的空闲区域。在一些情况下,NOP指令也可以用于调试或者占位符。

CYCLIC_LED_DELAY:
    MOV R5, #10     ; 外层循环计数器,可以根据需要调整
OUTER_LOOP:
    MOV R6, #250    ; 内层循环计数器,可以根据需要调整
INNER_LOOP:
    NOP             ; 空操作,用于延时
    NOP
    NOP
    NOP
    DJNZ R6, INNER_LOOP   ; 内层循环
    DJNZ R5, OUTER_LOOP   ; 外层循环
    RET

这段代码会循环执行内层NOP指令,以产生一个延时,然后通过外层循环控制延时的周期。你可以根据需要调整R5和R6的值来调整延时的时间。在延时期间,你可以在LED控制寄存器中设置相应的位来点亮LED灯。

2. 掌握汇编语言用查表法完成求平方数的程序;

; 寄存器定义
R0  EQU 0
R1  EQU 1
R2  EQU 2

    ORG 0x00   ; 程序起始地址

START:
    MOV R0, #5    ; 设置要求平方的数值,例如5
    MOV R1, R0    ; 将要求平方的数值存储到寄存器R1中
    MOV R2, #0    ; 将平方结果初始化为0

SQUARE_LOOP:
    ADD R2, R1    ; 将平方结果加上要求平方的数值
    SUB R0, #1    ; 将要求平方的数值减1
    JZ  SQUARE_DONE  ; 如果要求平方的数值为0,则跳转到结束标签
    JMP SQUARE_LOOP  ; 否则继续循环求平方

SQUARE_DONE:
    ; 在这里可以使用平方结果R2
    ; 比如将结果输出到某个输出端口或者存储到内存中

    ; 你的其他操作...

    ; 退出程序
    HALT

    END START     ; 程序结束标签

这段代码首先将要求平方的数值存储到寄存器R1中,然后将平方结果初始化为0。接着通过循环将平方结果不断累加,直到要求平方的数值减为0。最后,在SQUARE_DONE标签处,你可以对平方结果进行后续操作,比如将结果输出到某个输出端口或者存储到内存中。

3. 掌握普中单片机实验开发板的开发使用方法,在板子上完成LED周期性点灯的C程序实验;

在这里插入图片描述

4.一个LED周期性闪烁的汇编程序例子。

在这里插入图片描述

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

首先,我们需要了解这些指令的执行周期。在常见的8051系列单片机中,MOV指令和DJNZ指令通常执行需要1个机器周期。然后,我们可以使用单片机的时钟频率来计算时钟周期的时间。假设单片机的时钟频率为1 MHz(1微秒一个时钟周期)。

MOV R6,#250 指令的执行周期数为1,对应的时钟周期为1微秒。

DJNZ R6,D2 指令的执行周期数为2,对应的时钟周期为2微秒。

接下来,我们计算 Delay 函数的循环次数和对应的时钟周期总数:

Delay 函数中,R7 循环 250 次(MOV R7, #250),每次循环 R6 循环 250 次(D1:MOV R6,#250 和 D2:DJNZ R6,D2),所以总共循环次数为 250 * 250 = 62500。

每次 R6 循环需要 250 * 2 = 500 个时钟周期(MOV R6, #250 和 DJNZ R6, D2),所以总的时钟周期数为 62500 * 500 = 31250000 微秒。

最后,我们计算 LED 灯每隔多少毫秒或秒变化一次亮灭状态:

假设每次循环 LED 灯亮灭一次,那么 LED 灯变化一次状态需要的时间为 31250000 微秒,换算成毫秒为 31250 毫秒,或者换算成秒为 31.25 秒。

(2)如果要求你实现准确的LED 每隔1s亮灭的周期性变化,上面程序如何修改?请给出完整代码。

为了实现 LED 每隔 1 秒亮灭的周期性变化,我们需要修改内部循环的计数值,以及增加适当的延时来保证准确的周期性变化。下面是修改后的完整代码:

DOUBLE_LOOP:
    MOV R7, #100     ; 设置外层循环次数,以实现每隔1秒变化一次状态
OUTER_LOOP:
    MOV R6, #250     ; 设置内层循环次数,以增加适当的延时
INNER_LOOP:
    ; 在这里放置内层循环的操作
    DJNZ R6, INNER_LOOP   ; 内层循环
    DJNZ R7, OUTER_LOOP  ; 外层循环
    RET                   ; 返回

在这个修改后的程序中,我们将外层循环的计数值设置为 100,这相当于每隔 1 秒变化一次 LED 的亮灭状态。同时,内层循环的计数值设置为 250,以增加适当的延时,确保 LED 的亮灭状态变化平滑和准确。

对于本次博客的编写,我也是参考了其他大佬的博客,并且也在网上查了一些资料;如果你发现有什么不对的地方,我很希望大佬能够指出。

参考资料: https://blog.csdn.net/fuhanghang/article/details/84260199

  • 15
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值