介绍
Arduino Nano系列的升级版,基于ATmega4809主控,5V/20MHz,48KB Flash,6KB SRAM,256B EEPROM,14路数字IO(6路PWM,全部可作外部中断),8路10位ADC,Micro-USB接口。相比经典Nano:更大的Flash和SRAM、更强的PWM、所有IO均可中断、内置硬件乘法器。尺寸与经典Nano完全兼容(18×45mm),代码迁移无缝
Arduino Nano系列的升级版,基于ATmega4809主控,5V/20MHz,48KB Flash,6KB SRAM,256B EEPROM,14路数字IO(6路PWM,全部可作外部中断),8路10位ADC,Micro-USB接口。相比经典Nano:更大的Flash和SRAM、更强的PWM、所有IO均可中断、内置硬件乘法器。尺寸与经典Nano完全兼容(18×45mm),代码迁移无缝
| 参数 | 值 |
|---|---|
| I2C | 1路(A4=SDA,A5=SCL) |
| SPI | 1路 |
| SRAM | 6KB |
| Flash | 48KB |
| EEPROM | 256B |
| 串口 | 1路硬UART |
| 主频 | 20MHz内部振荡器 |
| 尺寸 | 18mm×45mm |
| 重量 | 约6g |
| 数字IO | 14路(全部支持外部中断,6路PWM) |
| USB接口 | Micro-USB |
| 板载LED | D13 |
| bootloader | Optiboot(Atmel SAMD11桥接) |
| 主控芯片 | ATmega4809 |
| 工作电压 | 5V DC |
| 模拟输入 | 8路(A0-A7,10位ADC) |
| 输入电压 | 7-18V(推荐7-12V) |
# Arduino Nano Every (ATmega4809) 代码例程
## 例程 1:Flash 模拟 EEPROM(替代 256B 硬件 EEPROM 不够用)
```cpp
// Nano Every - FlashStorage 库实现大容量非易失存储
// 安装: 库管理器搜索 "FlashStorage" by Arduino
#include <FlashStorage.h>
// 定义存储结构(最大Flash一页=256B)
struct ConfigData {
uint8_t magic; // 校验字
uint32_t bootCount;
float calibration;
char deviceName[32];
};
// 声明Flash存储对象(变量名即标识符)
FlashStorage(flash_config, ConfigData);
ConfigData config;
void setup() {
Serial.begin(115200);
delay(500);
// 读取Flash
config = flash_config.read();
// 检查是否首次启动(magic校验)
if (config.magic != 0xAA) {
Serial.println("First boot! Initializing config...");
config.magic = 0xAA;
config.bootCount = 0;
config.calibration = 1.0f;
strcpy(config.deviceName, "Every-001");
}
config.bootCount++;
Serial.print("Boot count: ");
Serial.println(config.bootCount);
// 写回Flash
flash_config.write(config);
Serial.println("Config saved to Flash.");
}
void loop() {
// Flash写次数有限(~10,000次),不要在loop中频繁写入
}
```
---
## 例程 2:全部14路外部中断演示
```cpp
// Nano Every - 多路外部中断演示
// Every 所有 14 个数字 IO 均支持外部中断!
volatile int interruptCounts[14] = {0};
const int PINS[14] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13};
// D0/D1 为串口引脚,演示时注意不要冲突
void isr0() { interruptCounts[0]++; }
void isr1() { interruptCounts[1]++; }
void isr2() { interruptCounts[2]++; }
void isr3() { interruptCounts[3]++; }
void isr4() { interruptCounts[4]++; }
void isr5() { interruptCounts[5]++; }
void isr6() { interruptCounts[6]++; }
void isr7() { interruptCounts[7]++; }
void isr8() { interruptCounts[8]++; }
void isr9() { interruptCounts[9]++; }
void isr10() { interruptCounts[10]++; }
void isr11() { interruptCounts[11]++; }
void isr12() { interruptCounts[12]++; }
void isr13() { interruptCounts[13]++; }
void (*isrList[14])() = {isr0,isr1,isr2,isr3,isr4,isr5,isr6,isr7,
isr8,isr9,isr10,isr11,isr12,isr13};
void setup() {
Serial.begin(115200);
// 以 D2-D7 为例配置中断(避开串口D0/D1)
for (int i = 2; i <= 7; i++) {
pinMode(PINS[i], INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PINS[i]), isrList[i], FALLING);
}
Serial.println("Multi-interrupt demo. Ground pins D2-D7 to trigger.");
}
void loop() {
static unsigned long lastPrint = 0;
if (millis() - lastPrint > 1000) {
lastPrint = millis();
Serial.println("--- Interrupt Counts ---");
for (int i = 2; i <= 7; i++) {
Serial.print("D"); Serial.print(i);
Serial.print(": "); Serial.println(interruptCounts[i]);
}
}
}
```
---
## 例程 3:TCA0 定时器高精度PWM
```cpp
// Nano Every - TCA0 高精度PWM(16位,最高65535级)
// 相比经典Nano 8位(0-255),精度大幅提升
void setup() {
Serial.begin(115200);
// 使用 Arduino 标准 API 即可(内部自动使用 TCA0)
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
}
void loop() {
// 16位渐变(0-65535),但 analogWrite 仍为 8 位 API
// 如需16位分辨率,直接操作 TCA0 寄存器:
// 配置 TCA0 为 16 位模式,D9(W0) D10(W1)
TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc | TCA_SINGLE_CMP0EN_bm;
TCA0.SINGLE.PER = 65535; // 16 位分辨率
// 16位呼吸灯
for (uint16_t duty = 0; duty < 65535; duty += 256) {
TCA0.SINGLE.CMP0 = duty;
delayMicroseconds(500);
}
for (uint16_t duty = 65535; duty > 0; duty -= 256) {
TCA0.SINGLE.CMP0 = duty;
delayMicroseconds(500);
}
}
```
---
## 例程 4:超低功耗睡眠模式
```cpp
// Nano Every - 休眠与唤醒(功耗降至 μA 级)
#include <avr/sleep.h>
const int WAKE_PIN = 2; // 唤醒引脚
void setup() {
Serial.begin(115200);
delay(1000);
pinMode(WAKE_PIN, INPUT_PULLUP);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
Serial.println("Entering sleep in 3 seconds...");
Serial.println("Pull D2 LOW to wake up.");
delay(3000);
// 配置唤醒源(D2 下降沿)
attachInterrupt(digitalPinToInterrupt(WAKE_PIN), wakeISR, FALLING);
// 进入 Power-Down 模式
Serial.println("Sleeping now... (will resume after wake)");
Serial.flush();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu(); // ← CPU 在此处停止
// --- 唤醒后从下面继续执行 ---
sleep_disable();
digitalWrite(13, LOW);
Serial.println("Woke up!");
}
void wakeISR() {
// 仅用于唤醒,无需操作
}
void loop() {
Serial.print("Working... uptime: ");
Serial.println(millis());
delay(2000);
// 再次休眠
Serial.println("Sleeping again...");
Serial.flush();
sleep_enable();
sleep_cpu();
sleep_disable();
Serial.println("Woke again!");
}
```
---
## 例程 5:高速 ADC 连续采样(4809 支持 150ksps)
```cpp
// Nano Every - ADC 连续采样(ATmega4809 ADC 最高 150ksps)
#define ADC_BUFFER_SIZE 256
volatile uint16_t adcBuffer[ADC_BUFFER_SIZE];
volatile uint8_t adcIndex = 0;
volatile bool adcComplete = false;
void setup() {
Serial.begin(115200);
// 配置 ADC0 自由运行模式(Free-Running)
ADC0.CTRLA = ADC_ENABLE_bm | ADC_FREERUN_bm; // 使能 + 自由运行
ADC0.CTRLB = ADC_PRESC_DIV4_gc; // 预分频=4
ADC0.CTRLC = ADC_REFSEL_VDD_gc; // 基准=VDD(5V)
ADC0.CTRLE = 64; // 采样持续时间
ADC0.MUXPOS = ADC_MUXPOS_AIN0_gc; // A0 输入
ADC0.INTCTRL = ADC_RESRDY_bm; // 结果就绪中断
ADC0.COMMAND = ADC_STCONV_bm; // 开始转换
}
// ADC 结果就绪中断
ISR(ADC0_RESRDY_vect) {
adcBuffer[adcIndex] = ADC0.RES;
adcIndex++;
if (adcIndex >= ADC_BUFFER_SIZE) {
adcIndex = 0;
adcComplete = true;
ADC0.CTRLA &= ~ADC_ENABLE_bm; // 停止ADC
}
}
void loop() {
if (adcComplete) {
adcComplete = false;
// 输出采样数据
Serial.println("--- ADC Buffer (256 samples) ---");
for (int i = 0; i < ADC_BUFFER_SIZE; i++) {
float voltage = adcBuffer[i] * (5.0f / 1023.0f);
Serial.println(voltage, 3);
}
// 重新启动
adcIndex = 0;
ADC0.CTRLA |= ADC_ENABLE_bm;
ADC0.COMMAND = ADC_STCONV_bm;
}
}
```
> **编译提示**:Arduino IDE → `Tools → Board → Arduino Nano Every`,需安装 `Arduino megaAVR Boards`。上述代码中直接操作寄存器的部分(例程3/5)为 ATmega4809 特有,无法在经典 Nano 上运行。
暂无参考文献