Arduino Nano V3 (ATmega328P)

元器件
开发板
库存 500

介绍

最经典的小型Arduino开发板,ATmega328P主控,5V/16MHz,32KB Flash,2KB SRAM,1KB EEPROM,14路数字IO(6路PWM),8路10位ADC,Mini-USB接口,支持USB-TTL串口,兼容所有Arduino生态。尺寸仅18×45mm,面包板友好。广泛用于原型开发、教学、嵌入式控制

规格参数

参数
I2C1路(A4=SDA,A5=SCL)
SPI1路(D11=MOSI,D12=MISO,D13=SCK,D10=SS)
SRAM2KB
Flash32KB(含2KB Bootloader)
EEPROM1KB
串口1路UART
主频16MHz晶振
尺寸18mm×45mm
重量约7g
数字IO14路(D0-D13,其中D3/D5/D6/D9/D10/D11为PWM)
USB接口Mini-USB(Type-B Mini)
板载LEDD13
bootloaderOptiboot
主控芯片ATmega328P-AU
工作电压5V DC
模拟输入8路(A0-A7,10位ADC)
输入电压7-12V(极限6-20V)
逻辑电平5V

代码例程

Arduino Nano V3 — 代码例程.md
# Arduino Nano V3 (ATmega328P) 代码例程

## 例程 1:基础 GPIO — LED 闪烁 + 按钮读取

```cpp
// Arduino Nano V3 - 基础 GPIO 示例
// D13 板载 LED 闪烁 + D2 按钮控制(内部上拉)

const int LED_PIN = 13;     // 板载 LED
const int BTN_PIN = 2;      // 按钮(D2,使用内部上拉)

void setup() {
    pinMode(LED_PIN, OUTPUT);
    pinMode(BTN_PIN, INPUT_PULLUP);  // 内部上拉,按下为LOW
    digitalWrite(LED_PIN, LOW);
    
    Serial.begin(115200);    // 与 Optiboot 一致
    Serial.println("Arduino Nano V3 - GPIO Demo");
}

void loop() {
    // 非阻塞按钮检测
    static unsigned long lastDebounce = 0;
    static int lastState = HIGH;
    static bool ledState = false;
    
    int reading = digitalRead(BTN_PIN);
    
    if (reading != lastState) {
        lastDebounce = millis();
    }
    
    if ((millis() - lastDebounce) > 50) {
        if (reading == LOW && lastState == HIGH) {
            // 按钮按下:切换 LED 状态
            ledState = !ledState;
            digitalWrite(LED_PIN, ledState ? HIGH : LOW);
            Serial.print("Button pressed. LED: ");
            Serial.println(ledState ? "ON" : "OFF");
        }
    }
    lastState = reading;
}
```

---

## 例程 2:PWM 呼吸灯(6路PWM任意一路)

```cpp
// Arduino Nano V3 - PWM 呼吸灯(D9)
// 支持 D3/D5/D6/D9/D10/D11 任意一路

const int PWM_PIN = 9;

void setup() {
    pinMode(PWM_PIN, OUTPUT);
    // 可选:修改PWM频率(Timer1控制D9/D10)
    // TCCR1B = (TCCR1B & 0xF8) | 0x01;  // 分频=1,PWM≈31.25kHz(消声)
}

void loop() {
    // 渐亮
    for (int duty = 0; duty <= 255; duty++) {
        analogWrite(PWM_PIN, duty);
        delay(5);
    }
    // 渐暗
    for (int duty = 255; duty >= 0; duty--) {
        analogWrite(PWM_PIN, duty);
        delay(5);
    }
}
```

---

## 例程 3:10位ADC读取 + 串口绘图

```cpp
// Arduino Nano V3 - ADC 读取 A0(电位器/传感器)
// 工具 → 串口绘图器 可实时查看波形

const int ADC_PIN = A0;

void setup() {
    Serial.begin(115200);
    // 可选:设置外部基准
    // analogReference(EXTERNAL);  // AREF接精密基准
}

void loop() {
    int raw = analogRead(ADC_PIN);           // 0-1023
    float voltage = raw * (5.0f / 1023.0f);  // 换算电压
    
    // 串口绘图器格式:直接输出数值
    Serial.print(raw);
    Serial.print(",");
    Serial.println(voltage, 3);   // 保留3位小数
    
    delay(50);
}
```

---

## 例程 4:I²C 扫描器 + OLED 显示

```cpp
// Arduino Nano V3 - I²C 总线扫描(A4=SDA, A5=SCL)
#include <Wire.h>

void setup() {
    Serial.begin(115200);
    Wire.begin();          // Nano: SDA=A4, SCL=A5
    
    Serial.println("\n=== I2C Scanner ===");
}

void loop() {
    byte count = 0;
    for (byte addr = 1; addr < 127; addr++) {
        Wire.beginTransmission(addr);
        if (Wire.endTransmission() == 0) {
            Serial.print("Found device at 0x");
            if (addr < 16) Serial.print("0");
            Serial.println(addr, HEX);
            count++;
        }
    }
    if (count == 0) {
        Serial.println("No I2C devices found.");
    } else {
        Serial.print("Total: ");
        Serial.print(count);
        Serial.println(" device(s)");
    }
    delay(3000);
}
```

---

## 例程 5:外部中断检测旋转编码器

```cpp
// Arduino Nano V3 - 旋转编码器(D2=INT0, D3=INT1)
// 使用外部中断,不丢脉冲

volatile int counter = 0;
const int ENC_A = 2;    // INT0
const int ENC_B = 3;    // INT1(仅作读取)
const int SW   = 4;     // 编码器按钮

void setup() {
    Serial.begin(115200);
    pinMode(ENC_A, INPUT_PULLUP);
    pinMode(ENC_B, INPUT_PULLUP);
    pinMode(SW, INPUT_PULLUP);
    
    // D2 上升沿中断(根据编码器型号可能需改为FALLING/CHANGE)
    attachInterrupt(digitalPinToInterrupt(ENC_A), encoderISR, RISING);
    
    Serial.println("Rotary Encoder Demo. Turn the knob...");
}

void encoderISR() {
    // 根据B相电平判断方向
    if (digitalRead(ENC_B) == LOW) {
        counter++;  // 顺时针
    } else {
        counter--;  // 逆时针
    }
}

void loop() {
    static int lastCounter = -999;
    static bool lastSW = HIGH;
    
    if (counter != lastCounter) {
        lastCounter = counter;
        Serial.print("Position: ");
        Serial.println(counter);
    }
    
    // 按钮检测(非阻塞)
    bool sw = digitalRead(SW);
    if (sw == LOW && lastSW == HIGH) {
        Serial.println("Button clicked!");
        delay(50);  // 简单消抖
    }
    lastSW = sw;
}
```

---

## 例程 6:EEPROM 读写(ATmega328P 内部 1KB)

```cpp
// Arduino Nano V3 - 内部 EEPROM 读写
#include <EEPROM.h>

struct Config {
    uint8_t  version;
    uint16_t setpoint;
    float    kp, ki, kd;
    char     name[16];
};

void setup() {
    Serial.begin(115200);
    
    Config defaults = {1, 250, 1.5f, 0.2f, 0.1f, "Nano-001"};
    Config loaded;
    
    // 写入
    EEPROM.put(0, defaults);
    Serial.println("Config saved to EEPROM.");
    
    // 读取
    EEPROM.get(0, loaded);
    Serial.println("--- Loaded Config ---");
    Serial.print("Version:  "); Serial.println(loaded.version);
    Serial.print("Setpoint: "); Serial.println(loaded.setpoint);
    Serial.print("KP/KI/KD: "); 
    Serial.print(loaded.kp); Serial.print("/");
    Serial.print(loaded.ki); Serial.print("/");
    Serial.println(loaded.kd);
    Serial.print("Name:     "); Serial.println(loaded.name);
}

void loop() {
    // 注意:EEPROM 约10万次擦写寿命,不要在 loop 中频繁写入
}
```

---

## 例程 7:软串口扩展(SoftwareSerial)

```cpp
// Arduino Nano V3 - 软串口扩展
// Nano 仅有1路硬件UART(D0/D1),软串口可实现第2路串口
#include <SoftwareSerial.h>

// RX=D8, TX=D9(软件模拟),注意软串口最高波特率约38400
SoftwareSerial mySerial(8, 9);

void setup() {
    Serial.begin(115200);      // 硬件串口 → PC
    mySerial.begin(9600);      // 软串口 → 外设(如蓝牙模块)
    
    Serial.println("Dual Serial Demo");
    Serial.println("Hardware UART → PC (115200 bps)");
    Serial.println("Software UART → Peripheral (9600 bps)");
}

void loop() {
    // 软串口 → 硬件串口
    if (mySerial.available()) {
        char c = mySerial.read();
        Serial.write(c);
    }
    // 硬件串口 → 软串口
    if (Serial.available()) {
        char c = Serial.read();
        mySerial.write(c);
    }
}
```

---

## 例程 8:毫秒级非阻塞调度(避免 delay)

```cpp
// Arduino Nano V3 - 非阻塞任务调度框架
// 替代 delay(),实现多任务"伪并发"

struct Task {
    unsigned long interval;
    unsigned long lastRun;
    void (*callback)();
};

Task tasks[3];
unsigned long taskCount = 0;

void addTask(unsigned long interval_ms, void (*cb)()) {
    if (taskCount >= 3) return;
    tasks[taskCount].interval = interval_ms;
    tasks[taskCount].lastRun = millis();
    tasks[taskCount].callback = cb;
    taskCount++;
}

// --- 任务回调 ---
void task_ledBlink() {
    static bool state = false;
    state = !state;
    digitalWrite(13, state);
}

void task_readSensor() {
    int val = analogRead(A0);
    Serial.print("ADC: ");
    Serial.println(val);
}

void task_heartbeat() {
    Serial.println("♥");
}

// --- 主程序 ---
void setup() {
    Serial.begin(115200);
    pinMode(13, OUTPUT);
    
    addTask(500, task_ledBlink);    // 每500ms
    addTask(300, task_readSensor);  // 每300ms
    addTask(1000, task_heartbeat);  // 每1秒
}

void loop() {
    unsigned long now = millis();
    for (int i = 0; i < taskCount; i++) {
        if (now - tasks[i].lastRun >= tasks[i].interval) {
            tasks[i].lastRun = now;
            tasks[i].callback();
        }
    }
    // 空闲时间可执行低优先级任务或进入休眠
}
```

> **说明**:以上所有例程均基于 Arduino IDE 标准库,无需额外安装。编译选择 `Tools → Board → Arduino Nano`,处理器选 `ATmega328P`。

参考资料

暂无参考文献