Arduino 串行口和中断实现 8 个 LED 流水灯效果
使用串行口实现 8 个 LED 流水灯效果
以下是通过串行口实现 8 个 LED 灯流水灯的示例代码:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // 创建软件串口对象
int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; // LED引脚数组
int ledCount = 8; // LED数量
int index = 0; // 当前LED的下标
void setup() {
mySerial.begin(9600); // 初始化串行口
for (int i = 0; i < ledCount; i++) {
pinMode(ledPins[i], OUTPUT); // 初始化LED引脚为输出
}
}
void loop() {
if (mySerial.available() > 0) { // 如果有数据可读
char value = mySerial.read(); // 读取一个字符
if (value == '1') { // 如果是1,则流水灯向右移动
digitalWrite(ledPins[index], LOW); // 关闭当前LED
index = (index + 1) % ledCount; // 下标加1
digitalWrite(ledPins[index], HIGH); // 打开下一个LED
delay(100); // 延迟100ms
} else if (value == '2') { // 如果是2,则流水灯向左移动
digitalWrite(ledPins[index], LOW); // 关闭当前LED
index = (index + ledCount - 1) % ledCount; // 下标减1
digitalWrite(ledPins[index], HIGH); // 打开上一个LED
delay(100); // 延迟100ms
}
}
}
在上面的代码中,我们使用了 SoftwareSerial 库来创建一个软件串口对象,并设置其接收和发送的引脚分别为 10 和 11。然后,我们定义了一个 LED 引脚数组和 LED 数量,以及一个当前 LED 的下标变量。在 setup 函数中,我们将 LED 引脚初始化为输出。在 loop 函数中,我们通过 mySerial.available() 函数判断是否有数据可读,如果有,则使用 mySerial.read() 函数读取一个字符,并根据字符的值来判断流水灯是向左还是向右移动。在移动 LED 的过程中,我们使用 digitalWrite() 函数来打开和关闭 LED,并通过 delay() 函数来控制移动的速度。
使用中断方式实现 8 个 LED 流水灯效果
以下是使用中断方式实现流水灯的示例代码:
#include <avr/interrupt.h>
int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; // LED引脚数组
int ledCount = 8; // LED数量
int index = 0; // 当前LED的下标
void setup() {
for (int i = 0; i < ledCount; i++) {
pinMode(ledPins[i], OUTPUT); // 初始化LED引脚为输出
digitalWrite(ledPins[i], LOW); // 关闭所有LED
}
cli(); // 禁用中断
TCCR1A = 0; // 设置TCCR1A寄存器
TCCR1B = 0;
TCNT1 = 0; // 初始化计数器
OCR1A = 15624; // 设置比较值
TCCR1B |= (1 << WGM12); // 开启CTC模式
TCCR1B |= (1 << CS12) | (1 << CS10); // 设置预分频值为1024
TIMSK1 |= (1 << OCIE1A); // 开启比较中断
sei(); // 启用中断
}
void loop() {
// 不需要任何操作
}
ISR(TIMER1_COMPA_vect) { // 中断服务程序
digitalWrite(ledPins[index], LOW); // 关闭当前LED
index = (index + 1) % ledCount; // 下标加1
digitalWrite(ledPins[index], HIGH); // 打开下一个LED
}
在上面的代码中,我们首先定义了 LED 引脚数组、LED 数量和当前 LED 的下标变量,并在 setup 函数中将 LED 引脚初始化为输出。然后,我们禁用中断并设置定时器的各项参数,包括比较值、预分频值和 CTC 模式。最后,我们开启比较中断并启用中断。在 loop 函数中不需要任何操作。在中断服务程序中,我们使用 digitalWrite() 函数来打开和关闭 LED,并根据当前 LED 的下标来控制 LED 的流水效果。定时器的中断服务程序会在每隔 1s 的时间间隔内执行一次,从而实现了 LED 流水灯的效果。
代码说明
- SoftwareSerial 库: 用于创建软件串口对象,可以方便地在任意引脚上实现串口通信功能。
- digitalWrite() 函数: 用于控制 LED 的打开和关闭。
- delay() 函数: 用于控制流水灯的速度。
- 中断: 通过定时器中断实现流水灯的自动控制,不需要在 loop 函数中进行繁重的循环操作。
- 定时器: Arduino 的定时器可以用来定时执行特定的操作。
- CTC 模式: 定时器的 CTC 模式可以用来实现比较中断。
- 预分频值: 控制定时器计数速度,预分频值越大,计数速度越慢。
- 比较中断: 当定时器计数器值达到比较值时,就会触发比较中断。
- ISR() 函数: 中断服务程序,在中断触发时会被自动执行。
总结
本文介绍了两种方法在 Arduino 上实现 8 个 LED 流水灯效果,一种使用串行口控制,另一种使用中断控制。使用串行口控制方法简单,但需要手动输入指令来控制流水灯方向,而使用中断控制方法则可以实现自动的流水灯效果。选择哪种方法取决于具体的需求。
原文地址: https://www.cveoy.top/t/topic/oh3P 著作权归作者所有。请勿转载和采集!