一、 实验要求
- 在单片机开发板的LED灯D1~D8上实现跑马灯。LED与单片机引脚连线电路如下图:
- 单片机芯片选择AT89C51,晶振频率设为12MHz,操作参考单片机开发板使用说明。
- 跑马灯点亮的时间间隔约为1秒。
- 分别用定时器的模式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 是为了满足跑马灯效果中对定时中断间隔的要求,通过合适的初值设置,可以实现精确的时间控制,从而控制跑马灯的速度和节奏。