arduino的模块化代码

我在void setup()void loop()之外的其他示例经常见到很多编程有void controlLED()等,那么这些其他“void”如何使用呢

在 Arduino 编程中,除了 void setup()void loop() 这两个核心函数外,你还可以自定义任意数量的 void 函数。这些自定义函数用于模块化代码,提高可读性和复用性。以下是详细规则和添加方法:


1. 自定义 void 函数的语法

cpp

// 自定义函数声明(可选)
void myFunction(); 

// 自定义函数定义
void myFunction() {
  // 你的代码
}

2. 添加到 setup/loop 后的规则

(1) 位置自由

自定义函数可以放在 setup()loop() 之后(推荐),也可以放在之前
推荐结构

cpp

void setup() { /* 初始化代码 */ }
void loop()  { /* 主循环代码 */ }

// 自定义函数放在 setup/loop 之后
void myFunction1() { /* 代码 */ }
void myFunction2() { /* 代码 */ }
(2) 函数声明(可选但推荐)

如果自定义函数定义在 setup()/loop() 之后,需在文件顶部添加函数声明(避免编译错误):

cpp

// 函数声明(告诉编译器函数的存在)
void myFunction(); // 结尾带分号

void setup() { 
  myFunction(); // 正确:声明后可在定义前调用
}

void loop() {}

// 函数定义
void myFunction() { 
  // 实际代码
}

3. 调用自定义函数的规则

  • setup()loop() 或其他函数内直接调用:

    cpp

  • void setup() {
      myFunction(); // 初始化时调用
    }
    
    void loop() {
      myFunction(); // 循环中重复调用
      delay(1000);
    }
  • 无返回值void 函数不返回任何值,仅执行操作(如控制引脚、打印数据等)。


4. 完整示例

cpp

// 声明自定义函数
void blinkLED(int times, int duration);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  blinkLED(3, 500); // 启动时闪烁3次
}

void loop() {
  blinkLED(1, 1000); // 每秒闪烁1次
}

// 定义自定义函数(放在setup/loop后)
void blinkLED(int times, int duration) {
  for (int i = 0; i < times; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(duration);
    digitalWrite(LED_BUILTIN, LOW);
    delay(duration);
  }
}

关键规则总结

规则项 说明
自定义函数位置 可放在 setup()/loop() 之后(推荐)或之前
函数声明 若定义在调用之后,必须在顶部声明(如 void myFunc();
无返回值 void 函数不返回数据
命名规则 不能与关键字冲突(如 setup, loop, digitalWrite
作用域 函数内定义的变量是局部的(除非使用全局变量)

通过自定义 void 函数,你可以将复杂逻辑拆分成模块,使代码更清晰。只需遵循声明/定义的位置规则,即可灵活扩展 Arduino 程序的功能。

为什么需要自定义函数?直接写在 loop() 里不行吗?

可以把所有代码都写在 loop() 里,但这会导致严重的代码维护问题。以下是自定义函数的 核心价值 和直接写在 loop() 中的 弊端


自定义函数的优势

优势 说明 示例对比
代码复用 避免重复代码,一处定义多处调用 需要闪烁LED时,只需 blink(3) 而不是重写整个闪烁逻辑
模块化 将复杂系统拆分成独立功能块 将「传感器读取」「数据处理」「电机控制」拆分成独立函数
可读性 函数名即注释,逻辑一目了然 calculateTemperature() 比一堆数学公式更易理解
调试效率 可单独测试特定功能模块 只需调试 readSensor() 函数而非整个 loop()
维护性 修改逻辑只需调整一个函数 修改LED引脚时只需改 blink() 函数,而非搜索替换整个代码

⚠️ 直接写在 loop() 中的弊端

cpp

// ❌ 糟糕实践:所有代码堆砌在loop中
void loop() {
  // 代码块1: 读取传感器
  int raw = analogRead(A0);
  float temp = (raw * 0.488) - 50; 
  Serial.print(temp);

  // 代码块2: 控制LED
  if (temp > 30) {
    for(int i=0; i<5; i++) {
      digitalWrite(13,HIGH);
      delay(200);
      digitalWrite(13,LOW);
      delay(200);
    }
  }

  // 代码块3: 电机控制(混杂在温度逻辑中)
  int speed = map(analogRead(A1), 0, 1023, 0, 255);
  analogWrite(5, speed);
}

问题分析

  1. 代码臃肿:300+行后难以定位关键逻辑

  2. 重复劳动:相同功能(如LED闪烁)需多次复制粘贴

  3. 牵一发而动全身:修改LED逻辑需搜索替换所有相关片段

  4. 调试地狱:无法单独测试传感器读取功能

  5. 可读性差:新人难以理解代码意图


优化方案:自定义函数重构

cpp

// ✅ 清晰的主循环
void loop() {
  float temp = readTemperature();  // 调用传感器函数
  controlLED(temp);               // 调用LED控制函数
  controlMotor();                 // 调用电机函数
}

// 模块1: 温度读取
float readTemperature() {
  int raw = analogRead(A0);
  return (raw * 0.488) - 50; 
}

// 模块2: LED控制(复用blink函数)
void controlLED(float temp) {
  if (temp > 30) blink(13, 5, 200); 
}

// 模块3: 电机控制
void controlMotor() {
  analogWrite(5, map(analogRead(A1), 0, 1023, 0, 255));
}

// ✅ 复用核心功能:闪烁函数
void blink(int pin, int times, int dur) {
  for(int i=0; i 
  

关键决策参考表

场景 推荐方案 原因
简单一次性脚本 直接写 loop() 代码量<50行时可行
重复功能 >2次 必须用自定义函数 避免复制粘贴错误
多人协作项目 强烈推荐模块化 便于分工开发
长期维护项目 函数化+文档注释 降低维护成本70%+

经验法则:当你的 loop() 超过屏幕一屏(约30行),或发现相同代码出现两次,就该使用自定义函数了。

通过自定义函数,你实际上是在构建自己的「代码乐高」—— 每个函数都是可复用的标准件,最终组合成强大而优雅的系统。

你可能感兴趣的:(单片机,嵌入式硬件,arduino)