创客开发入门(五)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 有个小便利:对于简单函数,很多时候会自动帮你生成前置声明,但复杂参数建议手动写。

相关推荐
HZZD_HZZD41 分钟前
NILM模型换个楼F1就从0.87跌到0.62?合众致达跨楼宇迁移实测:冻结卷积微调7天数据让洗衣机分解F1回升至0.81
大数据·物联网
嵌入式分享1 小时前
驱动之路#44:硬件 I2C 和软件 I2C 谁更坑?
linux·嵌入式硬件
嵌入式分享2 小时前
嵌入式分享#19:《嵌入式外设调试思路》--I2C设备篇
单片机·嵌入式硬件
WD137298015572 小时前
WD5030K输入工作电压 7.5‑30V,适合12A 及以内量产项目
stm32·单片机·嵌入式硬件·51单片机
千秋岁rr2 小时前
12.IIC
单片机·嵌入式硬件
新中地GIS开发老师2 小时前
空间信息与数字技术VS地理空间信息工程,两个专业有什么区别?考研有哪些选择?
物联网·gis开发
光子物联单片机3 小时前
STM32传感器模块编程实践(二十二)DIY智能WIFI视频控制小车
c语言·stm32·单片机·嵌入式硬件·音视频
jucat3 小时前
拆个烟雾报警器
嵌入式硬件
HRTOS4 小时前
HRTOS 高速任务与中断嵌套的 8051 寄存器组资源说明
单片机·嵌入式硬件·系统架构·51单片机
新晨单片机设计4 小时前
S010C-基于STM32单片机水温控制系统(OLED显示)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·水温控制系统