创客开发入门(五)Arduino IDE 编程基础

一、Arduino 编程语言

Arduino 核心是 C++ 编程 ,不是纯 C 语言,但它兼容 C 语言语法,新手写简单代码时几乎感觉不到区别。

  1. 官方标准 :Arduino 基于 AVR-GCC C++ 编译器,完整支持 C++ 特性
  2. 新手体验 :默认的 setup()/loop()、数字 / 串口操作,用的是简化版 C++,写法和 C 高度相似
  3. 底层本质 :Arduino 核心库(如 digitalWrite、Serial)都是用 C++ 类、对象 编写的

Arduino 强制使用 C++ 编译,纯 C 能做的它都能做,C++ 独有的特性它也支持,比如:

  • 类(Class)、对象(Object)
  • 构造函数 / 析构函数
  • 函数重载
  • 引用(&)
  • 命名空间

而 纯 C 语言不支持这些特性。

|--------|-------------------|------------------|
| 语言 | 能否在 Arduino 用 | 特点 |
| 纯 C | ✅ 兼容 | 语法简单,无面向对象 |
| C++ | ✅ 原生支持 | 包含全部 C 语法 + 高级特性 |

Arduino IDE 用 C++ 编译,你可以写 C 风格代码 入门,也可以用 C++ 高级特性 写复杂项目。

总结

  1. Arduino 编程本质是 C++,不是纯 C
  2. 新手写基础代码(setup/loop、引脚控制)用 C 语法 完全够用
  3. 进阶开发(库、模块化、面向对象)必须用 C++ 特性
  4. 所有代码最终都会被 C++ 编译器编译

二、Arduino 程序核心函数

Arduino 程序必须有这两个函数,少一个就编译报错。

复制代码
void setup(){
    // 上电 / 复位,只执行 1 次
}

void loop(){
    // setup跑完之后,无限循环反复执行
}

1、void setup()函数

  • 执行时机 :板子通电、按复位按钮之后,只运行一遍,仅此一次。
  • 用途:做初始化工作,只需要设置一次的代码放这里。 适合写:
  • 引脚模式设置 pinMode(LED_BUILTIN, OUTPUT);
  • 串口初始化 Serial.begin(9600);
  • OLED、传感器初始化
  • 变量初始赋值

❌不要把需要反复执行的逻辑写在这里,写完就不再跑了。

示例:

复制代码
void setup() {
    pinMode(42, OUTPUT);      //把42号引脚设置为输出模式,只需要设置1次
    Serial.begin(9600);       //开启串口
}

2、void loop()函数

  • 执行时机 :setup()全部执行完毕之后,自动一遍一遍无限循环 。 loop(){A;B;C;} → 执行 A→B→C,然后立刻回到 A→B→C...... 永不停歇。
  • 用途:放需要不停重复运行的逻辑。

适合写:

  • 读取传感器数值
  • 开关灯、电机控制
  • 判断按键状态
  • 串口接收数据

示例(闪烁 LED)

复制代码
void loop() {
    digitalWrite(42, HIGH);   //灯亮
    delay(1000);              //等1000ms
    digitalWrite(42, LOW);    //灯灭
    delay(1000);              //等1000ms
    //执行完,自动回到loop开头重新运行
}

void 代表:这个函数没有返回值,执行完不返回任何数据给程序。

3、 完整最小样板代码

复制代码
void setup() {
    Serial.begin(9600);
}

void loop() {
    Serial.println("我在循环运行");
    delay(1000);
}

上电后,串口每秒打印一行文字,无限输出。

新手容易踩坑

  1. 把延时delay()写在 setup:只会执行一次,不会循环闪烁。
  2. 把pinMode()写进 loop:可以跑,但每次循环重复设置引脚,属于多余浪费。引脚模式放 setup。
  3. Arduino 程序入口不是main(),IDE 底层帮你封装好了main(),用户只写 setup + loop。

三、 Arduino 自定义函数

setup()、loop()是系统规定函数;自定义函数是我们自己写的,用来把重复的代码打包,简化 loop,减少复制粘贴。

使用自定义函数的好处:

  1. 代码清晰,一个函数做一件事;
  2. 重复逻辑只写一遍,多处调用,修改只改一处;
  3. loop()不会写的几百行一大坨,可读性高。

1、 函数基本语法

复制代码
返回值类型 函数名(参数列表)
{
    //函数内部代码
    return 返回的数据;  //有返回值才写return
}

两种大类

  1. 无返回值函数(void):只干活,最后不返回数据。
  2. 有返回值函数(int /float/bool):干完活返回一个结果给调用处。

2、void 无返回不带参数

比如要实现 LED 闪烁,代码会重复写digitalWrite+delay,封装成函数。

复制代码
//自定义函数:让42号LED闪烁一次
void ledBlink()
{
    digitalWrite(42, HIGH);
    delay(500);
    digitalWrite(42, LOW);
    delay(500);
}

void setup() {
    pinMode(42, OUTPUT);
}

void loop() {
    ledBlink();  //直接调用,执行函数里面全部代码
}

运行效果:LED 持续闪烁。

调用:写ledBlink();加括号加分号,就会跑函数内部代码。


3、void带参数

参数可以向函数传递数值,让函数更加灵活。

复制代码
// 函数:LED闪烁,ms毫秒由调用的时候决定
void ledBlinkTime(int ms)
{
    digitalWrite(42, HIGH);
    delay(ms);
    digitalWrite(42, LOW);
    delay(ms);
}

void setup() {
    pinMode(42, OUTPUT);
}

void loop() {
    ledBlinkTime(100);   //快速闪烁,ms=100
    ledBlinkTime(1000);  //慢速闪烁,ms=1000
}
  • int ms:形式参数,相当于函数内部的局部变量。
  • 调用写 ledBlinkTime(100),此时 ms = 100。

可以写多个参数,逗号隔开:

复制代码
void ledBlink(int pin, int onTime, int offTime)
{
    digitalWrite(pin,HIGH);
    delay(onTime);
    digitalWrite(pin,LOW);
    delay(offTime);
}
//调用
ledBlink(13,300,700);

4、 有返回值函数(int/float/bool)

用return把计算结果送回去。 需求:写一个函数计算两个数字相加。

复制代码
//返回int类型,接收a、b两个参数
int addNum(int a, int b)
{
    int sum = a + b;
    return sum;  //把sum返回给调用地方
}

void setup() {
    Serial.begin(9600);
}

void loop() {
    int result = addNum(3,5); //调用函数,拿到返回值存入result
    Serial.println(result);   //输出8
    delay(1000);
}

逻辑:

  1. addNum(3,5)执行函数内部代码
  2. return sum,把结果返回 ,替换掉 addNum(3,5)这一块
  3. int result = 8;

return 执行之后,函数立刻结束,return 后面的代码不会运行。

布尔返回值示例,判断数值是否大于 100:

复制代码
bool isOver100(int val)
{
    if(val>100){
        return true;
    }else{
        return false;
    }
}

5、 重要规则

  1. 函数写在哪里? 可以写在 setup()、loop() 的外面,全局位置。 ✅正确结构:

    void myFunc(){ }

    void setup(){ }
    void loop(){ }

❌错误:不能把函数定义写在另一个函数里面!

复制代码
void loop(){
  void myFunc(){ } // 错误!Arduino C++不允许函数嵌套定义
}
  1. 变量作用域(局部 vs 全局)

    void test(){
    int a = 10; //局部变量,只在test函数内部有效,外面访问不到
    }
    int b = 20; //全局变量,setup、loop、所有自定义函数都可以访问

尽量少用全局变量,多用参数传递。

  1. 函数声明(当自定义写在 loop 后面时) 如果你把自定义函数写在loop()下方,需要在开头做函数声明,否则编译报错。

    void hello(); //函数声明

    void setup(){
    hello();
    }
    void loop(){}

    //定义写在后面
    void hello(){
    Serial.println("hi");
    }

Arduino IDE 有个小便利:对于简单函数,很多时候会自动帮你生成前置声明,但复杂参数建议手动写。

相关推荐
QMCY_jason38 分钟前
RK3588 usb摄像头 mipi摄像头 hdmi in 调试记录
单片机·嵌入式硬件
国科安芯1 小时前
四重证据,一条逻辑链:商业航天级微控制器MCU抗辐射验证方法学综述——以国科安芯AS32S601为例
人工智能·单片机·嵌入式硬件·mcu·安全·抗辐射
玄芯散人4 小时前
【元婴·100】STM32启动流程:从上电到main()经历了什么
stm32·单片机·嵌入式硬件
梦想出海-Phoebe5 小时前
AI Agent能实现自主复制吗?Anthropic研究揭示模型部署与IoT设备安全问题
人工智能·物联网·安全
SL_staff6 小时前
4G设备掉线三层归因指南:SIM卡、模组、JVS-IOT网关配置精准锁定
java·物联网·产品
恒锐丰科技林技术员6 小时前
EG3525S 推挽半桥 PWM 控制芯片解析与工程应用
经验分享·嵌入式硬件·硬件工程
科芯创展8 小时前
XZ5129:单节锂电池供电36V升压LED恒流驱动芯片设计解析
stm32·单片机·嵌入式硬件
恒锐丰科技林技术员8 小时前
EG44273 低侧单通道栅极驱动芯片解析
经验分享·嵌入式硬件·硬件工程
✎ ﹏梦醒͜ღ҉繁华落℘8 小时前
单片机基础知识 --keil文件乱码,如何转换编码方式?
单片机·嵌入式硬件
创界工坊工作室9 小时前
41-基于STC89C52的避障循迹小车
stm32·单片机·嵌入式硬件·51单片机·proteus