实验一:51单片机架构与汇编指令

文章目录

    • 一、汇编程序点亮一个LED灯
      • (一)电路原理图
      • (二)汇编程序思路
    • 二、LED流水灯电路
      • (一)电路原理图
      • (二)汇编程序思路
        • 1.51汇编程序
        • 2.C语言程序

一、汇编程序点亮一个LED灯

(一)电路原理图

实验一:51单片机架构与汇编指令_第1张图片

(二)汇编程序思路

ORG 0H             ; 程序起始地址
MOV P1, #0FEH      ; 将端口1设置为输出模式,P1.0引脚设为低电平,点亮LED

END                ; 程序结束

这段汇编代码是用来控制 51 单片机上的端口,让其输出一个特定的电平来点亮 LED 灯。解释:

  1. ORG 0H: 这条指令告诉汇编器程序将从地址 0 开始存放代码。在 51 单片机中,地址 0 通常是程序的起始地址。

  2. MOV P1, #0FEH: 这条指令将一个常数值 0FEH(二进制形式为 11111110B)移动到端口 1(P1)的寄存器中。在这个寄存器中,每个位对应一个端口引脚,其中 P1.0 是最低位,P1.7 是最高位。由于 0FEH 的二进制表示只有最低位为 0,其他位都为 1,这意味着它将使得 P1.0 端口引脚输出低电平(即连接 LED 的引脚为低电平),从而点亮 LED 灯。

  3. END: 这个指令表示程序的结束。在汇编程序中,它通常用于告诉汇编器程序到此为止,没有更多的代码需要编译。

这段代码的主要思想是利用单片机的端口控制功能,通过将适当的值加载到端口的寄存器中,以控制特定的端口引脚输出相应的电平,从而点亮 LED 灯。

二、LED流水灯电路

(一)电路原理图

实验一:51单片机架构与汇编指令_第2张图片

(二)汇编程序思路

1.51汇编程序
ORG 0000H         ; 程序起始地址设置为0000H
AJMP MAIN        ; 跳转到主程序入口

ORG 0030H         ; 设置程序入口地址为0030H
MAIN:
    MOV SP, #60H   ; 设置栈指针的初始值为60H,栈用于存储程序中的临时数据

    MOV A, #0FEH   ; 设置A寄存器的初始值为11111110,用于控制灯的状态

LOOP:
    INC R1         ; R1值增加,开始计数
    RR A           ; 右循环移位A寄存器,实现逆向流水灯效果,从下至上依次亮灯

    MOV P0, A      ; 将A寄存器的值输出到P0口,控制灯的亮灭状态

    ACALL DELAY    ; 调用延时函数,实现1秒的延时效果

    SJMP LOOP      ; 无条件跳转到LOOP标签,实现循环

DELAY:
    MOV R2, #0FFH  ; 初始化R2寄存器为255
    MOV R3, #0FFH  ; 初始化R3寄存器为255

DELAY_LOOP:
    DJNZ R2, $     ; R2递减,如果不为零,跳回DELAY_LOOP
    DJNZ R3, DELAY_LOOP ; R3递减,如果不为零,跳回DELAY_LOOP

    RET            ; 延时结束,返回调用处

END              ; 程序结束

这段汇编代码的主要思想是实现一个循环流水灯效果,通过控制单片机上的端口,让LED灯按照一定的顺序亮起和熄灭。解释:

  1. ORG 0000H: 这条指令将程序的起始地址设置为 0000H,即程序从这里开始执行。

  2. AJMP MAIN: 这条指令是跳转指令,将程序跳转到 MAIN 标签处,即主程序入口。

  3. ORG 0030H: 这里设置程序入口地址为 0030H,即 MAIN 标签所在的地址。

  4. MOV SP, #60H: 这条指令将栈指针(Stack Pointer)的初始值设置为 60H。栈用于存储程序中的临时数据。

  5. MOV A, #0FEH: 这条指令将寄存器 A 的初始值设置为 0FEH,即二进制 11111110。这个值将用于控制 LED 灯的亮灭状态。

  6. LOOP:: 这是一个标签,用于实现循环结构。

  7. INC R1: 这条指令将寄存器 R1 的值加 1,开始计数。

  8. RR A: 这是右循环移位指令,将 A 寄存器中的位向右移动,实现 LED 灯的逆向流水灯效果,即从下至上依次点亮 LED。

  9. MOV P0, A: 这条指令将 A 寄存器的值输出到 P0 端口,控制 LED 灯的亮灭状态。

  10. ACALL DELAY: 这是调用延时函数的指令,实现每个 LED 灯的显示时间。

  11. SJMP LOOP: 这是无条件跳转指令,使程序回到 LOOP 标签处,实现循环效果。

  12. DELAY:: 这是一个延时函数的标签。

  13. MOV R2, #0FFHMOV R3, #0FFH: 这两条指令初始化了两个寄存器 R2 和 R3 的值为 0FFH,即 255,用于延时计数。

  14. DELAY_LOOP:: 这是延时函数的循环标签。

  15. DJNZ R2, $DJNZ R3, DELAY_LOOP: 这两条指令分别对 R2 和 R3 寄存器进行递减操作,并检查是否为零。如果不为零,则跳回 DELAY_LOOP 标签处继续延时。

  16. RET: 这是延时函数的返回指令,表示延时结束,将返回到调用延时函数的地方。

  17. END: 这是程序结束的标记。

这段汇编代码的思想是利用循环结构和延时函数实现一个流水灯效果,通过控制单片机的端口以及延时,依次点亮 LED 灯并延时显示,最终实现 LED 灯的循环流水效果。

2.C语言程序
// 51单片机编程常用的头文件
#include    // 包含 8051 单片机的寄存器定义文件
#include  // 包含 _nop_ 函数的头文件

// 延迟函数
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;       // 控制 P0 口输出二进制 1111 1110,点亮最低位的 LED 灯
        delay_ms(50);    // 延时 50 毫秒
        P0 = 0xfd;       // 控制 P0 口输出二进制 1111 1101,点亮下一个 LED 灯
        delay_ms(50);    // 延时 50 毫秒
        // 以此类推,依次点亮 LED 灯,每个灯的亮灭时间为 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);
    }
}

这段程序实现了一个简单的循环流水灯效果,通过控制 51 单片机的端口 P0 的输出来控制 LED 灯的亮灭状态,并通过延时函数来控制每个 LED 灯的亮灭时间。解释:

  1. #include #include :这两行是包含 8051 单片机的寄存器定义文件和延时函数 _nop_() 的头文件。

  2. void delay_ms(int a): 这是一个延时函数,用于实现毫秒级的延时。它接受一个参数 a,表示延时的毫秒数。

  3. void main(void): 这是程序的入口函数。

  4. while (1): 这是一个无限循环,程序将一直在此处执行。

  5. P0 = 0xfe;P0 = 0xfd; 等:这些语句分别将二进制值赋给端口 P0,控制 LED 灯的亮灭状态。例如,P0 = 0xfe; 表示将 P0 端口的值设为二进制 1111 1110,即点亮最低位的 LED 灯。

  6. delay_ms(50);:这是调用延时函数,延时 50 毫秒,控制每个 LED 灯的亮灭时间。

  7. 以此类推,每个 LED 灯的亮灭状态和亮灭时间都在循环中控制,实现了一个简单的循环流水灯效果。

这段程序的思想是通过循环结构和延时函数控制单片机的输出端口,从而实现LED灯的循环流水效果。

你可能感兴趣的:(51单片机,架构,汇编)