当前位置: 首页 > article >正文

汇编语言与接口技术--跑马灯

一、 实验要求

  1. 在单片机开发板的LED灯D1~D8上实现跑马灯。LED与单片机引脚连线电路如下图:

  1. 单片机芯片选择AT89C51,晶振频率设为12MHz,操作参考单片机开发板使用说明。
  2. 跑马灯点亮的时间间隔约为1秒。
  3. 分别用定时器的模式1和模式2实现。(用P83的延时子程序实现)

二、 实验设计

 1.整体思路

(1)初始化阶段(MAIN 程序段)

设置堆栈指针 SP 为 #60H,为程序运行时的堆栈操作预留空间,确保函数调用和局部变量存储等操作有足够的内存空间。

将寄存器 B 赋值为 #14H,用于后续控制跑马灯移动的速度和周期,作为中断次数计数器或其他与时间相关的控制参数。

配置定时器 / 计数器 0 的工作模式为模式 1(MOV TMOD,#01H)。

将初始的 LED 状态值 #0FEH(假设低电平点亮 LED,此值对应点亮除最低位外的其他 LED 灯)赋值给累加器 A,并将 A 的值输出到 P2 端口,从而设置 LED 灯的初始点亮状态。

使能定时器 0 中断(SETB ET0)、总中断(SETB EA),并启动定时器 0 开始计时(SETB TR0),为后续的定时器中断触发跑马灯状态更新做准备。

最后进入一个无限循环 SJMP HERE,等待定时器中断的发生。

(2)中断服务阶段(MAIN2 程序段)

每次进入中断服务程序时,首先判断寄存器 B 的值是否为 0。如果 B 不为 0,则将 B 减 1 并跳转到 RETURN 处,暂时不进行 LED 灯状态的更新操作;如果 B 为 0,则说明满足了一定的时间条件或计数条件,开始进行跑马灯状态更新操作。

对累加器 A 中的值进行循环左移操作(RL A),使得 LED 灯的点亮状态向左移动一位,实现跑马灯向左移动的效果。然后将更新后的 A 值输出到 P2 端口,更新 LED 灯的显示状态。

将寄存器 B 重新赋值为 #14H,重置控制参数,为下一次的判断和操作做准备。

调用延迟子程序 ACALL DELAY,用于控制跑马灯移动的速度,通过延迟一定时间来调整 LED 灯状态更新的频率,使其以合适的速度显示,便于观察。

(3)延迟子程序(DELAY 程序段)

通过简单的循环结构实现延迟功能。在这个延迟子程序中,通过将寄存器R5设置为一个初始值(这里是#20),然后在循环中不断对R5进行减 1 操作,直到R5的值变为0,以此来消耗一定的时间,从而达到延迟的目的。

2.流程图

程序从RESET处开始,跳转到MAIN;

在MAIN中,设置堆栈指针、初始化变量、配置定时器和中断,然后等待T0定时器中断;

当T0定时器中断发生时,跳转到MAIN2进行中断服务处理;

在MAIN2中,根据条件判断B值是否为零,如果不为零则更新LED灯状态,并调用DELAY进行延时;

DELAY过程进行简单延时操作;

返回到MAIN2处理下一个循环;

循环执行上述步骤,直到程序结束。

  

 

3.主要模块设计思路及分析

(1)主程序模块(MAIN)
1-1堆栈指针设置

MOV B,#14H:寄存器 B 被用作一个控制参数,其具体用途是与定时器中断相关的计数或时间控制。初始化为 #14H,这个值会影响跑马灯的速度、周期等特性。

MOV TMOD,#01H:设置定时器 / 计数器 0 的工作模式为模式 1。

1-2 LED 初始状态设置

MOV A,#0FEH 和 MOV P2,A:这两条指令用于设置 LED 灯的初始状态。#0FEH 对应的二进制值为 11111110,假设连接到 P2 端口的 LED 灯是低电平点亮,那么初始状态就是除了最低位的 LED 灯熄灭外,其他 LED 灯点亮。

1-3中断设置与启动

SETB ET0、SETB EA 和 SETB TR0:这三条指令分别用于使能定时器 0 中断、总中断以及启动定时器 0 开始计时。使能定时器 0 中断允许单片机在定时器 0 计数溢出时自动跳转到中断服务程序MAIN2执行相应的操作。使能总中断则确保了整个系统能够响应定时器 0 中断以及其他可能的中断请求。启动定时器 0 开始计时后,定时器 0 将按照设定的工作模式和初值开始计数,当计数达到设定值时触发中断,从而实现定时控制跑马灯状态更新的功能。

(2)中断服务程序模块(MAIN2)   
 2-1中断次数判断与控制

DJNZ B,RETURN:该指令用于判断寄存器 B 的值是否为 0。如果 B 不为 0,则将 B 减 1 并跳转到 RETURN 处,是为了控制跑马灯状态更新的频率或时间间隔。

2-2跑马灯状态更新

RL A、MOV P2,A:RL A 指令对累加器 A 中的值进行循环左移操作,实现了 LED 灯点亮状态的向左移动,模拟跑马灯的效果。然后将更新后的 A 值输出到 P2 端口,从而更新了连接到 P2 端口的 LED 灯的显示状态。

MOV B,#14H:在完成一次跑马灯状态更新后,将 B 寄存器重新赋值为 #14H,重置了控制参数,为下一次的判断和操作做好准备。这样可以确保每次跑马灯状态更新的间隔或条件是一致的,保证了跑马灯效果的稳定性和可重复性。

(3)延迟子程序模块(DELAY)

MOV R5, #20:这里设置了外层循环的次数为 #20,可以根据实际需要调整这个值来改变延迟的总时间。如果需要更长的延迟时间,可以增大 R5 的值;反之,如果需要缩短延迟时间,可以减小 R5 的值。       

三、 实现效果

 

四、总结

1. 通过对 B 寄存器的计数操作,可以在定时器中断多次发生后才进行一次跑马灯状态更新,从而实现对跑马灯速度和节奏的更精细控制。例如,如果 B 的初始值为 #14H,每次中断时 B 减 1,当 B 减到 0 时,才进行真正的跑马灯状态更新操作,这样就可以实现每隔一定次数的定时器中断更新一次 LED 灯状态,而不是每次中断都更新。

2. 在 8051 单片机中,定时器 / 计数器 0 的工作模式 1 是 16 位定时器 / 计数器模式,具有较大的计数范围和较高的定时精度,适用于需要较长时间定时或对定时精度有一定要求的应用场景。这里选择模式 1 是为了满足跑马灯效果中对定时中断间隔的要求,通过合适的初值设置,可以实现精确的时间控制,从而控制跑马灯的速度和节奏。


http://www.kler.cn/a/470919.html

相关文章:

  • 精选2款.NET开源的博客系统
  • 二维数组:求最大元素及其所在的行坐标及列坐标(PTA)C语言
  • Jmeter进阶篇(31)解决java.net.BindException: Address already in use: connect报错
  • CS·GO搬砖流程详细版
  • Element-plus表单总结
  • 【JAVA】java中将一个list进行拆解重新组装
  • OpenGL材质系统和贴图纹理
  • 【2024华为OD-E卷-100分-火星文计算】(题目+思路+JavaC++Python解析)
  • 网络物理互连
  • 固定资产管理系统|Java|SSM|VUE| 前后端分离
  • qemu-kvm使用简介
  • js逆向实战(1)-- 某☁️音乐下载
  • Docker 中启动 Nacos
  • Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
  • 普及组集训数据结构--并查集
  • 学习threejs,导入AWD格式的模型
  • iOS实现在collectionView顶部插入数据效果
  • 分布式IO模块:激光切割机产线高效控制的创新引擎
  • c# 中Parallel.ForEach 对其中一个变量进行赋值 引发报错
  • 计算机网络•自顶向下方法:多址接入协议
  • 【AI数学基础】线性代数:向量空间
  • reactor的Hooks.enableAutomaticContextPropagation();不生效解决方案
  • 基于32单片机的智能语音家居
  • pytest日志显示
  • gesp(C++一级)(18)洛谷:B4063:[GESP202412 一级] 奇数和偶数
  • 某制造集团灯塔工厂解决方案(36页PPT)