Arduino变量详解与嵌入式开发扩展
一、变量基础篇
1.1 变量声明与初始化
<ARDUINO>
int ledPin = 13; // 声明并初始化
float sensorValue; // 先声明后赋值
unsigned long startTime; // 无符号长整型
void setup() {
sensorValue = analogRead(A0) * 0.0048828125;
startTime = millis();
}
1.2 常用数据类型对比
类型 |
字节 |
取值范围 |
典型应用场景 |
bool |
1 |
0/1 |
开关状态 |
char |
1 |
-128~127 |
ASCII字符 |
byte |
1 |
0-255 |
原始字节数据 |
int |
2 |
-32,768~32,767 |
常规计数器 |
unsigned int |
2 |
0~65,535 |
传感器原始值 |
long |
4 |
-2^31~2^31-1 |
时间戳(毫秒) |
float |
4 |
±3.4e±38 |
传感器校准值 |
double |
4 |
同float(Arduino特有) |
高精度计算 |
1.3 作用域实战
<ARDUINO>
int globalVar = 10; // 全局变量
void setup() {
int localVar = 5; // 局部变量
Serial.begin(9600);
{
int blockVar = 3; // 块级作用域
Serial.println(blockVar); // 输出3
}
// Serial.println(blockVar); // 编译错误
}
void loop() {
// localVar++; // 编译错误
globalVar++;
}
二、进阶编程技巧
2.1 类型转换实战
<ARDUINO>
void setup() {
float f = 3.14159;
int i = (int)f; // C风格转换 → 3
int j = round(f); // 四舍五入 → 3
char str[10];
dtostrf(f, 4, 2, str); // 浮点转字符串 → "3.14"
String s = String(i, DEC); // 整型转字符串
}
2.2 volatile与中断
<ARDUINO>
volatile bool interruptFlag = false;
void setup() {
attachInterrupt(digitalPinToInterrupt(2), isr, RISING);
}
void isr() {
interruptFlag = true; // 必须使用volatile
}
void loop() {
if(interruptFlag) {
handleInterrupt();
interruptFlag = false;
}
}
2.3 结构体与枚举
<ARDUINO>
enum State { INIT, RUNNING, ERROR };
struct SensorData {
float temperature;
uint16_t pressure;
byte humidity;
};
void setup() {
State currentState = INIT;
SensorData envData = {25.5, 1013, 60};
}
三、内存管理精要
3.1 Arduino内存分布
<TEXT>
+-------------------+| Flash (程序区) | 32KB+-------------------+| SRAM (内存) | 2KB ← 变量存储区+-------------------+| EEPROM | 1KB ← 持久化存储+-------------------+
3.2 内存优化技巧
<ARDUINO>
PROGMEM const char longString[] = "Save to Flash"; // 将常量存入Flash
void setup() {
char buffer[64]; // 栈内存分配
String dynamicStr; // 堆内存分配(谨慎使用)
EEPROM.write(0, 123); // 持久化存储
}
四、ESP32与树莓派对比
4.1 变量处理差异
特性 |
Arduino Uno |
ESP32 |
树莓派 Pico |
处理器架构 |
8位AVR |
32位双核Xtensa |
ARM Cortex-M0+ |
SRAM |
2KB |
520KB |
264KB |
Flash |
32KB |
4MB/16MB |
2MB |
多线程支持 |
无 |
FreeRTOS支持 |
无 |
持久化存储 |
EEPROM |
NVS系统 |
Flash模拟EEPROM |
变量作用域扩展 |
单程序文件 |
多文件工程 |
MicroPython模块化 |
4.2 ESP32多核编程示例
<ARDUINO>
TaskHandle_t Task1;
void setup() {
xTaskCreatePinnedToCore(
taskCode, // 任务函数
"Task1", // 任务名
1000, // 栈大小
NULL, // 参数
1, // 优先级
&Task1, // 任务句柄
0 // 核心编号
);
}
void taskCode(void * pvParameters) {
volatile int coreCounter = 0; // 需要volatile保证可见性
for(;;){
coreCounter++;
delay(100);
}
}
4.3 树莓派Python对比
<PYTHON>
# Python动态类型示例counter = 10 # 整型counter = "次" # 自动转为字符串# 类型提示(Python3.5+)from typing import Unionvalue: Union[int, float] = 3.14
五、最佳实践建议
- 优先选择const而非#define
<ARDUINO>
const float PI = 3.14159; // 类型安全
// 避免 #define PI 3.14159
跨平台开发技巧
<ARDUINO>
#if defined(ESP32)
const int LED = GPIO_NUM_2; // ESP32内置LED
#elif defined(ARDUINO_AVR_UNO)
const int LED = 13;
#endif
内存敏感型操作
<ARDUINO>
void processData() {
int* buffer = (int*)malloc(100 * sizeof(int)); // 谨慎使用堆内存
if(buffer != NULL) {
// 操作内存
free(buffer); // 必须手动释放
}
}
通过系统学习变量知识,可以更好地在不同嵌入式平台(如Arduino、ESP32、树莓派)之间进行技术迁移。建议实际开发时:
- 对内存敏感项目优先选择Arduino/C++
- 复杂逻辑处理考虑树莓派Python
- 物联网项目首选ESP32平台