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

一、Arduino 编程语言

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

  1. 官方标准 :Arduino 基于 AVR-GCC C++ 编译器,完整支持 C++ 特性
  2. 新手体验 :默认的 setup()/loop()、数字 / 串口操作,用的是简化版 C++,写法和 C 高度相似
  3. 底层本质 :Arduino 核心库(如 digitalWriteSerial)都是用 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 有个小便利:对于简单函数,很多时候会自动帮你生成前置声明,但复杂参数建议手动写。

相关推荐
派勤电子3 小时前
嵌入式硬件选型|3.5寸工控板与Mini-ITX主板的扩展能力哪个更好?
嵌入式硬件·工控主板·嵌入式主板·工控主板扩展·3.5寸工控板·mini-itx·工业主板io接口
工业胶粘剂技术5 小时前
科耀K-8095M 单组分耐高温环氧 电机磁钢/新能源汽车高温结构粘接技术参数与选型
单片机·嵌入式硬件·汽车
李永奉10 小时前
中科蓝讯SDK开发-BT893x 面条耳机连接vivo手机后连接APP端,最后手机端设置页面手动断开蓝牙连接,此时耳机端假断开
c语言·开发语言·嵌入式硬件·物联网·智能手机·电脑
大爱编程♡10 小时前
STM32-DMA
stm32·单片机·嵌入式硬件
云泽80811 小时前
STM32 USART 详解(三):硬件架构、内部寄存器与物理层收发原理
stm32·嵌入式硬件·硬件架构
天空'之城11 小时前
单片机基础核心知识点汇总(三十三)
数据库·单片机·嵌入式硬件
数字新视界13 小时前
机房动环监控的智能化管理与安全提升探索
嵌入式硬件·物联网·数据中心·数据中心基础设施管理·dcim管理系统
@嵌入式扫地僧14 小时前
TFLite Micro STM32/ESP32 开箱即用推理骨架 + INT8 量化脚本实战:零调试跑通端侧 AI 推理完整步骤
人工智能·嵌入式硬件·tinyml·端侧ai·tflite micro
自小吃多14 小时前
高云FPGA ModelSim中的仿真
笔记·嵌入式硬件·fpga开发