基于51单片机的十六个led灯的心型流水灯程序代码 要求:1.定义p0口和p2口为led口 2.定义五个开关s1、s2、s3、s4、s5,功能分别为复位、开灯、下一个、上一个、关灯
时间: 2024-09-10 07:03:04 浏览: 67
在这个版本的代码中,我们将P0口和P2口都用于LED,同时添加了五个开关S1-S5,功能如你所描述。注意这只是一个基本的设计,实际硬件连接可能需要适配。
```c
#include <reg52.h>
#define LED_PORT P0 | P2 // 使用P0和P2口作为LED
#define LED_LENGTH 16 // LED的数量
#define SWITCH_PORT P3 // 定义开关输入端口
#define SW_RESET 0 // S1位置
#define SW_ONOFF 1 // S2位置
#define SW_NEXT 2
#define SW_PREV 3
#define SW_OFF 4
char led_state[16] = {0}; // LED状态数组,初始化全关
void delay(unsigned int time) {
for (int i = 0; i < time; ++i);
}
void set_led(int index, bool state) {
led_state[index] = state ? 1 : 0;
LED_PORT = LED_PORT & ~(1 << index) | (led_state[index] << index);
}
void switch_handler() {
if (SWITCH_PORT&P3^SW_RESET && SWITCH_PORT&P3^SW_ONOFF) {
// 检查是否为复位开关
if (!led_state[0]) {
// 如果所有LED关闭,启动流水灯
reset_led_sequence();
} else {
// 复位LED状态
for (int i = 0; i < LED_LENGTH; ++i) {
led_state[i] = 0;
}
}
} else if (SWITCH_PORT&P3&SW_ONOFF) {
// 开关S2:开灯或关灯
toggle_all_led();
} else if (SWITCH_PORT&P3^SW_NEXT) {
// 下一个LED
next_led();
} else if (SWITCH_PORT&P3^SW_PREV) {
// 上一个LED
prev_led();
}
}
void reset_led_sequence() {
for (int i = 0; i < LED_LENGTH; ++i) {
led_state[i] = 1;
}
next_led(); // 首先点亮第一个LED
}
void toggle_all_led() {
for (int i = 0; i < LED_LENGTH; ++i) {
led_state[i] ^= 1; // 切换LED状态
}
}
void next_led() {
if (led_state[LED_LENGTH - 1]) {
led_state[LED_LENGTH - 1] = 0;
led_state[0] = 1;
} else {
for (int i = LED_LENGTH - 1; i >= 0; --i) {
if (led_state[i]) {
led_state[i] = 0;
led_state[i + 1] = 1;
break;
}
}
}
}
void prev_led() {
if (led_state[0]) {
led_state[0] = 0;
led_state[LED_LENGTH - 1] = 1;
} else {
for (int i = 0; i < LED_LENGTH; ++i) {
if (led_state[i]) {
led_state[i] = 0;
led_state[i - 1] = 1;
break;
}
}
}
}
int main(void) {
TMOD = 0x01; // 设置T0为模式1自动重装定时器
TH0 = 0xFD; // 设置初始计数值(100ms)
TL0 = 0xFD;
ET0 = 1; // 开启外部中断
EA = 1; // 开启总中断
TR0 = 1; // 启动定时器T0
while(1) {
switch_handler();
}
return 0;
}
阅读全文