16x16点阵跑马灯加三个led按下启动按键从下往上依次点亮点阵,led也依次点亮跟着亮,按下暂停复位按键停止点阵并记录,led全灭51实现
时间: 2024-03-03 18:53:39 浏览: 60
基于Protues的16×32点阵LED汉字显示屏的设计
以下是一种可能的51单片机实现方式,仅供参考:
```C
#include <reg51.h>
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit LED3 = P1^2;
sbit SCLK = P3^6; // 移位寄存器时钟线
sbit RCLK = P3^5; // 输出寄存器时钟线
sbit SER = P3^4; // 移位数据线
sbit START = P2^0; // 启动/暂停按键
sbit RESET = P2^1; // 复位按键
unsigned char display[16] = {0}; // 点阵显示数据
unsigned char position = 0; // 当前点阵显示的位置
unsigned char pause = 0; // 暂停标志位
// 向移位寄存器中写入一个字节的数据
void shiftOut(unsigned char data) {
unsigned char i;
for (i = 0; i < 8; i++) {
SER = data & 0x80;
data <<= 1;
SCLK = 0;
SCLK = 1;
}
}
// 将点阵数据输出到显示器上
void displayData() {
unsigned char i;
for (i = 0; i < 16; i++) {
shiftOut(display[i]);
}
RCLK = 0;
RCLK = 1;
}
// 更新点阵显示数据
void updateDisplay() {
unsigned char i;
for (i = 0; i < 16; i++) {
display[i] = 0x01 << position;
}
}
// 按键检测函数
unsigned char checkKey() {
if (START == 0) {
while (START == 0);
return 1;
} else if (RESET == 0) {
while (RESET == 0);
return 2;
} else {
return 0;
}
}
// 主函数
void main() {
unsigned char i;
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xFC; // 定时器0初值
TL0 = 0x67;
TR0 = 1; // 启动定时器0
ET0 = 1; // 允许定时器0中断
EA = 1; // 开启总中断
while (1) {
if (pause == 0) {
position++;
if (position >= 16) {
position = 0;
}
updateDisplay();
displayData();
}
i = checkKey();
if (i == 1) { // 启动/暂停
pause = !pause;
} else if (i == 2) { // 复位
position = 0;
pause = 0;
updateDisplay();
displayData();
LED1 = 0;
LED2 = 0;
LED3 = 0;
}
}
}
// 定时器0中断处理函数
void timer0() interrupt 1 {
static unsigned char cnt = 0;
cnt++;
if (cnt >= 20) { // 大约每200ms更新一次LED显示
cnt = 0;
if (position >= 0 && position < 5) {
LED1 = 1;
LED2 = 0;
LED3 = 0;
} else if (position >= 5 && position < 10) {
LED1 = 0;
LED2 = 1;
LED3 = 0;
} else if (position >= 10 && position < 16) {
LED1 = 0;
LED2 = 0;
LED3 = 1;
}
}
}
```
这个程序使用了定时器中断来控制点阵显示的移位速度,并使用按键来控制启动/暂停和复位功能。LED显示当前点阵移位的位置。在每次定时器中断中更新LED显示,大约每200ms更新一次。需要注意的是,本程序没有使用移位寄存器和输出寄存器的清零功能,因此在复位时需要手动将点阵数据清零。
阅读全文