Arduino编程语句参考

Arduino编程语句参考

Arduino程序可以分为三个主要部分:结构,数值(变量与常量)和函数。

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


结构

基础程序结构

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

if…else

说明

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

结构

1
2
3
4
5
if(条件表达式){
  // 条件为真执行语句块
} else {
  // 条件为假执行语句块
}

代码示例

1
2
3
4
5
6
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 循环将永远不会中止。可以在代码内部改变测试变量,比如让该变量递增;或者通过外部条件改变测试变量,比如将一个传感器的读数赋值给测试变量。

结构

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

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

代码示例

1
2
3
4
5
int i = 0;
while(i < 10){
  Serial.println(i);
  i++; // 修改条件变量,避免死循环
}

注意要点

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

do… while

说明

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

结构

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

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

代码示例

1
2
3
4
5
6
int i = 20;
do{
  Serial.println(i);
  i++;
} while(i <10);
// i初始20,条件不成立,但依旧打印一次

注意要点

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

for

说明

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

结构

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

代码示例

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

注意要点

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

switch case

说明

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

结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
switch(变量){
  case 常量值1:
    语句;
    break;
  case 常量值2:
    语句;
    break;
  default:
    都不匹配时执行;
}

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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。

结构

1
break;

代码示例

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

注意要点

  1. 仅跳出当前一层循环,嵌套循环不会一次性全部跳出;

continue

说明

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

结构

1
continue;

代码示例

1
2
3
4
5
6
for(int i=0;i<10;i++){
  if(i ==5){
    continue; // i=5时跳过打印,直接下一轮
  }
  Serial.println(i);
}

注意要点

  1. 只跳过本轮,不会结束整个循环;

return

说明

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

结构

1
2
3
return;
// 带返回值
return value;

代码示例

1
2
3
int add(int a,int b){
  return a+b;
}

注意要点

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

goto

说明

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

结构

1
2
3
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(串口通讯)

1
2
3
4
5
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 位掩码数值
0%