制作流水灯,原理电路见下图,8个发光二极管LED0~LED7经限流电阻分别接至P1口的P1.0~P1.7引脚上,阳极共同接高电平。编写程序来控制发光二极管由下至上的反复循环流水点亮,每次点亮一个发光二极管。(要求用循环移位函数及数组两种方法编程)
时间: 2024-10-16 15:17:48 浏览: 59
制作流水灯的基本原理是通过轮流改变各个LED的驱动状态,使其依次点亮,形成从低到高或者从高到低的逐亮效果。这里使用的是单片机控制,比如常见的Arduino系列。以下是两种编程方法:
1. **使用循环移位函数**:
```c
const int LED_PIN[] = {P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7};
int ledIndex = 0; // 当前点亮的LED索引
void setup() {
for (int i = 0; i < sizeof(LED_PIN) / sizeof(LED_PIN[0]); ++i) {
pinMode(LED_PIN[i], OUTPUT);
}
}
void loop() {
digitalWrite(LED_PIN[ledIndex], HIGH); // 点亮当前LED
shiftOut(P1_7, P1_6, MSBFIRST, ledIndex); // 移位输出LED索引
ledIndex = (ledIndex + 1) % sizeof(LED_PIN); // 循环索引
delay(100); // 等待一段时间再切换下一个LED
}
```
在这个例子中,`shiftOut()`是一个模拟移位寄存器的功能,将LED索引值左移一位,并置最高位为1,即点亮下一个LED。
2. **使用数组和定时器**:
```c
const int LED_COUNT = 8;
bool ledState[LED_COUNT] = {false}; // 初始化所有LED为关闭
int ledIndex = 0;
void setup() {
for (int i = 0; i < LED_COUNT; ++i) {
pinMode(LED_PIN[i], OUTPUT);
}
attachInterrupt(digitalPinToInterrupt(P1_7), incrementLed, RISING); // 用中断触发下一LED点亮
}
void loop() {}
ISR(interruptVector) {
if (ledState[ledIndex]) { // 如果当前LED已点亮,则将其关闭
digitalWrite(LED_PIN[ledIndex], LOW);
} else { // 否则点亮并更新索引
digitalWrite(LED_PIN[ledIndex], HIGH);
ledState[ledIndex] = true;
ledIndex = (ledIndex + 1) % LED_COUNT;
}
}
void incrementLed() {
ledIndex++;
if (ledIndex == LED_COUNT) {
ledIndex = 0; // 回到第一个LED
}
}
```
这个版本利用中断技术,在每个LED高电平上升沿时,切换LED状态并更新索引。
阅读全文