跳到主要内容

Arduino 并发控制

在Arduino编程中,并发控制是指在同一时间内处理多个任务的能力。由于Arduino是单线程的微控制器,它无法像现代计算机那样真正同时执行多个任务。然而,通过一些技巧和编程方法,我们可以模拟并发执行的效果,从而实现多任务处理。

什么是并发控制?

并发控制是一种编程技术,允许程序在同一时间内处理多个任务。虽然Arduino的CPU一次只能执行一条指令,但通过快速切换任务,我们可以让多个任务看起来像是同时运行的。这种技术通常用于需要同时监控多个传感器或执行多个操作的场景。

为什么需要并发控制?

在许多Arduino项目中,你可能需要同时执行多个任务。例如:

  • 读取多个传感器的数据
  • 控制多个执行器(如电机、LED灯等)
  • 处理用户输入(如按钮、旋钮等)

如果没有并发控制,这些任务可能会相互干扰,导致程序响应缓慢或无法正常工作。

实现并发控制的方法

在Arduino中,实现并发控制的常见方法包括:

  1. 使用millis()函数进行非阻塞延迟
  2. 使用状态机
  3. 使用定时器中断

1. 使用millis()函数进行非阻塞延迟

millis()函数返回自Arduino启动以来的毫秒数。通过比较当前时间与上一次任务执行的时间,我们可以实现非阻塞延迟,从而避免使用delay()函数导致的程序阻塞。

cpp
unsigned long previousMillis = 0;
const long interval = 1000; // 1秒

void loop() {
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// 执行任务
}
}

在这个例子中,任务每隔1秒执行一次,而不会阻塞其他代码的执行。

2. 使用状态机

状态机是一种编程模式,允许程序在不同的状态之间切换。通过将任务分解为多个状态,我们可以实现并发控制。

cpp
enum State { STATE_1, STATE_2 };
State currentState = STATE_1;

void loop() {
switch (currentState) {
case STATE_1:
// 执行状态1的任务
currentState = STATE_2;
break;
case STATE_2:
// 执行状态2的任务
currentState = STATE_1;
break;
}
}

在这个例子中,程序在两个状态之间切换,每个状态执行不同的任务。

3. 使用定时器中断

Arduino的定时器中断允许我们在特定的时间间隔内执行代码。通过配置定时器中断,我们可以实现精确的并发控制。

cpp
#include <avr/io.h>
#include <avr/interrupt.h>

void setup() {
// 配置定时器1
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
OCR1A = 15624; // 1秒
TIMSK1 = (1 << OCIE1A);

sei(); // 启用全局中断
}

ISR(TIMER1_COMPA_vect) {
// 执行定时器中断任务
}

void loop() {
// 主循环中的其他任务
}

在这个例子中,定时器1每隔1秒触发一次中断,执行中断服务程序(ISR)中的任务。

实际案例:多任务LED控制

假设我们需要同时控制两个LED灯,一个每隔1秒闪烁一次,另一个每隔500毫秒闪烁一次。我们可以使用millis()函数实现这一功能。

cpp
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval1 = 1000; // 1秒
const long interval2 = 500; // 500毫秒

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(2, OUTPUT);
}

void loop() {
unsigned long currentMillis = millis();

if (currentMillis - previousMillis1 >= interval1) {
previousMillis1 = currentMillis;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

if (currentMillis - previousMillis2 >= interval2) {
previousMillis2 = currentMillis;
digitalWrite(2, !digitalRead(2));
}
}

在这个例子中,两个LED灯分别以不同的频率闪烁,而不会相互干扰。

总结

通过使用millis()函数、状态机和定时器中断,我们可以在Arduino中实现并发控制,从而处理多个任务。这些技术可以帮助你编写更高效、更灵活的程序,适用于各种复杂的项目。

附加资源与练习

  • 练习1:尝试使用状态机实现一个简单的交通灯控制系统,控制红、黄、绿三个LED灯的切换。
  • 练习2:使用定时器中断实现一个精确的秒表功能,每隔100毫秒更新一次显示。
提示

如果你对并发控制有更深入的需求,可以进一步学习RTOS(实时操作系统)在Arduino中的应用,它提供了更强大的多任务处理能力。