# Arduino编程语句参考



# Arduino编程语句参考

Arduino程序可以分为三个主要部分：**结构，数值（变量与常量）和函数**。

> 提示：本文同时兼容 AVR‑Arduino 和 ESP32‑S3，部分函数行为会因硬件平台略有差异。

---

## 结构
### 基础程序结构
| 语法 | 说明 |
|---|---|
| `setup()` | 上电/复位后**仅运行一次**，用于初始化引脚、串口、外设。无返回值。 |
| `loop()` | setup执行完毕后无限循环执行，项目主业务逻辑写在此函数内。无返回值。 |

### if...else
#### 说明
`if...else` 用于条件判断。当if后的表达式结果为真，则执行if内代码；表达式为假时，执行else分支的代码。可以实现二选一的逻辑判断。

#### 结构
```cpp
if(条件表达式){
  // 条件为真执行语句块
} else {
  // 条件为假执行语句块
}
```

#### 代码示例

```
int val = analogRead(A0);
if(val > 512){
  digitalWrite(2,HIGH);
} else {
  digitalWrite(2,LOW);
}
```

#### 注意要点

1. 区分赋值运算符`=`和判断相等`==`，新手极易写错；
2. else 不能单独使用，必须搭配 if；
3. 支持多分支 `if‑else if‑else` 链式判断。

### while

#### 说明

while 循环将会连续地循环，直到圆括号`()`中的表达式变为假。被测试的表达式变量必须被改变，否则 while 循环将永远不会中止。可以在代码内部改变测试变量，比如让该变量递增；或者通过外部条件改变测试变量，比如将一个传感器的读数赋值给测试变量。

#### 结构

```
while(表达式/循环条件){
  语句块/循环体
}
```

> 
> 其中表达式称为循环条件，语句块称为循环体。
> while 语句的意思是：**先计算表达式的值，当值为真（非 0）时，执行循环体语句；执行完循环体语句，再次计算表达式的值，如果为真，继续执行循环体…… 这个过程会一直重复，直到表达式的值为假（0）才退出循环。**

#### 代码示例

```
int i = 0;
while(i < 10){
  Serial.println(i);
  i++; // 修改条件变量，避免死循环
}
```

#### 注意要点

1. while 是**先判断，后执行**；条件初始为假，循环体一次都不会运行；
2. 循环体内必须有改变条件的逻辑，否则死循环卡死 MCU；
3. `while(1)` 代表无限死循环。

### do... while

#### 说明

do‑while 属于后判断循环，先执行循环体内代码，之后再判断条件表达式。无论条件真假，循环体**至少执行一次**。

#### 结构

```
do{
  语句块/循环体
} while(表达式/循环条件);
```

> 
> ⚠️末尾 while 括号后面**必须加分号**。

#### 代码示例

```
int i = 20;
do{
  Serial.println(i);
  i++;
} while(i <10);
// i初始20，条件不成立，但依旧打印一次
```

#### 注意要点

1. 末尾分号不要遗漏，编译报错；
2. 至少执行一次，这是和 while 最大区别。

### for

#### 说明

for 循环多用于已知循环次数的场景，将变量初始化、循环条件、变量更新写在一行，代码更加紧凑。

#### 结构

```
for(初始化表达式; 循环条件; 更新表达式){
  循环体语句块
}
```

#### 代码示例

```
for(int i=0; i<10; i++){
  Serial.println(i);
}
```

#### 注意要点

1. 三个表达式之间使用**分号**分隔，不是逗号；
2. 初始化仅在循环最开始执行 1 次；
3. 更新表达式每轮循环体结束后执行。

### switch case

#### 说明

多分支条件判断，用于匹配变量离散的取值，替代大量`if‑else if`。

#### 结构

```
switch(变量){
  case 常量值1:
    语句;
    break;
  case 常量值2:
    语句;
    break;
  default:
    都不匹配时执行;
}
```

#### 代码示例

```
int key = 2;
switch(key){
  case 1:
    Serial.println("按键1");
    break;
  case 2:
    Serial.println("按键2");
    break;
  default:
    Serial.println("未知按键");
}
```

#### 注意要点

1. `case`后面只能写常量，不能写范围表达式；
2. **不要忘记`break`，缺少 break 会发生 case 穿透，顺序执行后面 case 代码**；
3. default 是可选分支。

### break

#### 说明

跳出当前`for/while/do‑while`循环，或者跳出`switch‑case`语句，直接结束当前循环 /switch。

#### 结构

```
break;
```

#### 代码示例

```
for(int i=0;i<10;i++){
  if(i ==5){
    break; // i等于5直接跳出for循环
  }
  Serial.println(i);
}
```

#### 注意要点

1. 仅跳出**当前一层循环**，嵌套循环不会一次性全部跳出；

### continue

#### 说明

跳过本次循环剩余代码，直接进入下一轮循环条件判断，不会终止整个循环。

#### 结构

```
continue;
```

#### 代码示例

```
for(int i=0;i<10;i++){
  if(i ==5){
    continue; // i=5时跳过打印，直接下一轮
  }
  Serial.println(i);
}
```

#### 注意要点

1. 只跳过**本轮**，不会结束整个循环；

### return

#### 说明

提前结束当前函数，若是有返回值函数，需要携带返回数据。

#### 结构

```
return;
// 带返回值
return value;
```

#### 代码示例

```
int add(int a,int b){
  return a+b;
}
```

#### 注意要点

1. `void`类型函数使用`return;`不带数值；
2. return 之后的代码不会执行。

### goto

#### 说明

跳转到标记的代码位置，语法支持，但普通项目不推荐使用，容易打乱程序执行流程。

#### 结构

```
goto label_name;
// ...
label_name:
```

#### 注意要点

- 仅建议在极端出错复位场景少量使用，业务逻辑尽量避免。

---

## 数值

### 常量

- IO 电平常量：`HIGH` / `LOW`
- 引脚模式常量：`INPUT` / `OUTPUT` / `INPUT_PULLUP`
- 布尔常量：`true` / `false`
- 整数常量：支持十进制、十六进制`0x`、八进制`0`开头
- 浮点数常量：带小数点数字，例如`3.14`

> 
> 注意：ESP32**没有 INPUT_PULLDOWN**，该常量仅部分 AVR 板子支持。

### 数据类型

表格

| 类型 | 中文名称 | 说明 |
| --- | --- | --- |
| `void` | 无返回值 | 仅用于函数声明，代表函数不返回任何数据，不能用来定义变量 |
| `boolean` | 布尔型 | 取值 `true` / `false`；底层存储为 1 字节 |
| `char` | 字符型 | 单个字符，1 字节；AVR 是有符号 (-128~127)，ESP32 char 默认为无符号 |
| `unsigned char` | 无符号字符型 | 1 字节，数值范围 `0‑255` |
| `byte` | 字节型 | 等价 `unsigned char`，范围`0‑255`，硬件位操作常用 |
| `int` | 整型 | AVR：16 位 `-32768 ~ 32767`；**ESP32 是 32 位 int**，范围大幅扩大 |
| `word` | 字型 | 无符号 16 位，取值 `0‑65535` |
| `long` | 长整型 | 32 位带符号整数 |
| `float` | 单精度浮点型 | 4 字节，保存小数 |
| `double` | 双精度浮点 | AVR 为 8 字节；**ESP32 下 double 和 float 完全等价，没有更高精度** |
| `String` | 字符串对象 | Arduino 封装类，方便文本操作；内存碎片风险，嵌入式谨慎高频使用 |
| `array` | 数组 | 相同类型数据集合；`int arr[10];` 定义数组 |

### 类型转换函数

> 
> 强制把数据转为对应类型

- `char()` 转为 char
- `byte()` 转为 byte
- `int()` 转为 int
- `word()` 转为 word
- `long()` 转为 long
- `float()` 转为 float

### 变量范围与限定符

- **变量作用域**
  - 全局变量：写在所有函数外面，整个程序全部函数都可以访问；上电初始化一次
  - 局部变量：写在函数 / 大括号`{}`内部，仅该代码块内有效；每次进入代码块重新创建
- `static`：静态局部变量；函数退出后，变量数值保留，不会销毁
- `volatile`：易变限定符；阻止编译器优化读取，**中断服务函数访问共享变量必须加 volatile**
- `const`：常量，赋值后数值不可修改

### 运算符

#### 算术运算符

- `=` 赋值运算符，把右侧值存入左侧变量，不等于数学等于
- `+` 加法
- `-` 减法
- `*` 乘法
- `/` 除法；整数相除结果为整数，舍弃小数
- `%` 取模（求余数）；**仅支持整数，不能用于浮点数**

#### 关系运算符（比较运算，返回 true/false）

- `==` 判断是否相等，**不要和赋值`=`混淆**
- `!=` 判断不等于
- `<` 小于
- `>` 大于
- `<=` 小于等于
- `>=` 大于等于

#### 布尔逻辑运算符（逻辑与 / 或 / 非）

- `&&` 逻辑与，两边条件全部为真结果才为真
- `||` 逻辑或，任意一边条件为真结果即为真
- `!` 逻辑非，取反，真变假，假变真

#### 位运算符

- `&` 按位与
- `|` 按位或
- `^` 按位异或
- `~` 按位取反
- `<<` 位左移
- `>>` 位右移

#### 指针运算

- 指针的概念
- 指针变量

> 
> 提示：普通 Arduino 项目很少用到指针，高级 C 语言特性。

### 工具

- `sizeof()` 获取变量 / 数据类型占用内存字节大小

---

## 函数

### 通信 Serial（串口通讯）

```
Serial.begin(波特率);
Serial.print();      // 打印不换行
Serial.println();    // 打印并换行
Serial.read();       // 读取1字节串口数据
Serial.available();  // 获取接收缓冲区可用字节数量
```

### 数字 I/O

- `pinMode(pin, mode)` 设置引脚模式：`INPUT` / `OUTPUT` / `INPUT_PULLUP`
- `digitalWrite(pin, val)` 输出引脚电平：`HIGH` / `LOW`
- `digitalRead(pin)` 读取数字引脚电平，返回`HIGH`或`LOW`

### 模拟 I/O

- `analogRead(pin)` 读取 ADC 模拟输入；返回采样数值；ESP32 ADC 存在噪声
- `analogWrite(pin, duty)` PWM 脉冲宽度调制输出；**不是 DAC 模拟电压输出**

### 高级 I/O

- `tone(pin, freq)` 在指定引脚输出方波，常用于驱动蜂鸣器
- `noTone(pin)` 停止 tone 方波输出
- `shiftOut(dataPin, clockPin, bitOrder, value)` 串行移位输出
- `shiftIn(dataPin, clockPin, bitOrder)` 串行移位输入
- `pulseIn(pin, value)` 读取引脚上指定电平脉冲持续时间（微秒）

### 时间函数

> 
> millis/micros 为非阻塞，推荐优先使用；delay 是阻塞延时，程序卡在该处不能做别的任务

- `millis()` 返回系统上电运行总毫秒数，返回 unsigned long
- `micros()` 返回系统上电运行总微秒数，返回 unsigned long
- `delay(ms)` 毫秒级阻塞延时
- `delayMicroseconds(us)` 微秒级阻塞延时

### 数学函数

- `min(a,b)` 返回两个数最小值
- `max(a,b)` 返回两个数最大值
- `abs(x)` 返回绝对值
- `constrain(x,min,max)` 将数值限制在 min‑max 区间，超出直接截断到边界
- `map(val,in_min,in_max,out_min,out_max)` 将输入区间线性映射到输出区间
- `pow(base,exp)` 幂运算，求 base 的 exp 次方，返回 float
- `sqrt(x)` 平方根运算

### 三角函数

> 
> ⚠️ 参数单位是**弧度，不是角度**，角度需要先转换 `角度 * PI / 180`

- `sin(rad)` 正弦
- `cos(rad)` 余弦
- `tan(rad)` 正切

### 随机数

- `random(max)` / `random(min,max)` 获取随机整数；范围 [min, max‑1]，上限不包含
- `randomSeed(seed)` 设置随机数种子；通常用`analogRead(悬空引脚)`获取噪声做种子

### 位与字节操作

- `lowByte()` 获取 16 位数值低字节
- `highByte()` 获取 16 位数值高字节
- `bitRead()` 读取指定 bit 位
- `bitWrite()` 修改指定 bit 位
- `bitSet()` 将指定 bit 置 1
- `bitClear()` 将指定 bit 置 0
- `bit()` 返回第 n 位掩码数值


---

> 作者: [Buray](http://www.buray.top)  
> URL: http://www.buray.top/posts/arduino-program-reference/  

