在Arduino编程中,代码结构分为三个核心区域,理解它们的执行顺序和作用至关重要:
📌 一、代码执行顺序图解
text
全局声明区(setup前面) ↓ setup() { 初始化代码 } // 上电后**只执行一次** ↓ loop() { 循环代码 } // 反复执行直到断电
🧩 二、必须写在 setup()
前面的内容
这些属于全局声明,在程序编译时就被确定,且能被所有函数访问:
-
库的引用
cpp
-
#include <LibraryName.h> // 如 #include <Servo.h>
-
常量定义
cpp
-
#define LED_PIN 13 // 用宏定义提高可读性 const int BAUD_RATE = 9600; // 推荐用const代替#define
-
全局变量声明
cpp
-
int sensorValue = 0; // 所有函数均可访问此变量 bool isActive; // 默认值false
-
对象实例化
cpp
-
Servo myServo; // 创建舵机控制对象 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // LCD屏幕对象
-
自定义函数声明(非必须,但复杂项目建议写)
cpp
-
void readSensor(); // 告诉编译器此函数存在
⚠️ 重要原则:
在setup()
前只能声明,不能执行操作(如digitalWrite()
等函数调用是无效的)
⚙️ 三、必须写在 setup()
里面的内容
这些是初始化操作,只在Arduino启动时运行一次:
-
引脚模式设置
cpp
-
void setup() { pinMode(LED_PIN, OUTPUT); // 设置13号引脚为输出 pinMode(BUTTON_PIN, INPUT_PULLUP); // 启用内部上拉电阻 }
-
通信接口初始化
cpp
-
Serial.begin(BAUD_RATE); // 启动串口通信(波特率9600) Wire.begin(); // I2C通信初始化
-
外设初始化
cpp
-
myServo.attach(9); // 舵机信号线接9号引脚 lcd.begin(16, 2); // 初始化16x2字符的LCD
-
初始状态设置
cpp
-
digitalWrite(LED_PIN, HIGH); // 上电先点亮LED
-
全局变量初始赋值(若需动态计算)
cpp
-
sensorCalibration = analogRead(A0) / 2; // 基于首次读数校准
❌ 四、常见错误示例
cpp
int counter = 0; Serial.begin(9600); // 错误!函数调用不能放在全局区 void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); }
🔥 编译报错:
'Serial' does not name a type
✅ 正确结构模板
cpp
#include <Servo.h> // ✅ 库引用(setup前) const int SERVO_PIN = 9; // ✅ 常量定义(setup前) Servo myServo; // ✅ 对象创建(setup前) int angle = 0; // ✅ 全局变量(setup前) void setup() { Serial.begin(9600); // ✅ 串口初始化(setup内) myServo.attach(SERVO_PIN); // ✅ 外设初始化(setup内) pinMode(LED_BUILTIN, OUTPUT); // ✅ 引脚模式设置(setup内) } void loop() { // 主循环代码... }
💡 关键总结
位置 | 内容类型 | 执行特点 | 典型内容 |
---|---|---|---|
setup() 前面 | 全局声明 | 编译时确定 | 库引用、常量、全局变量、对象 |
setup() 内部 | 初始化操作 | 上电后只执行1次 | 引脚模式、通信初始化、外设配置 |
loop() 内部 | 主逻辑 | 循环执行 | 传感器读取、电机控制、条件判断 |
记住这个口诀:“前声明,内初始化,loop循环动起来”。理解了这个结构,你的Arduino代码将不再“胡乱” 😉