使用串行口实现 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 流水灯效果,一种使用串行口控制,另一种使用中断控制。使用串行口控制方法简单,但需要手动输入指令来控制流水灯方向,而使用中断控制方法则可以实现自动的流水灯效果。选择哪种方法取决于具体的需求。

Arduino 串行口和中断实现 8 个 LED 流水灯效果

原文地址: https://www.cveoy.top/t/topic/oh3P 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录