ATmega328P Specifications Overview
Table
| Function | ATmega328P Pin | Net | Connected To | Direction | Notes |
|---|---|---|---|---|---|
| VCC | VCC pins 4, 6 | VCC | J1 pin 2, J2 pin 01, C1, C7, R1, L1 | Power | Board supply; 16 MHz requires 4.5–5.5 V per datasheet speed grade |
| Ground | GND pins 3, 5, 21, 33 | GND | J1 pin 6, J2 pin 02, support capacitors, reset switch | Power | Common return |
| Analog supply | AVCC pin 18 | AVCC | L1 P2, C2 | Power | Fed from VCC through 10 uH L1 and decoupled by C2 |
| ADC reference | AREF pin 20 | AREF | C3 to GND | Analog input/reference | Firmware may select DEFAULT, INTERNAL, or EXTERNAL reference as needed |
| Crystal input | XTAL1/PB6 pin 7 | XTAL1 | Y1 pin 1, C4 | Clock | 16 MHz crystal node |
| Crystal output | XTAL2/PB7 pin 8 | XTAL2 | Y1 pin 2, C5 | Clock | 16 MHz crystal node |
| Reset | RESET | R1, C6, S1, J1 pin 5, J2 pin 05 | Input | Active-low reset; C6 can interfere with debugWIRE | |
| SPI MISO | PB4 pin 16 | SPI_MISO | J1 pin 1 | Output during ISP | AVR ISP programming |
| SPI SCK | PB5 pin 17 | SPI_SCK | J1 pin 3 | Input during ISP | AVR ISP programming |
| SPI MOSI | PB3 pin 15 | SPI_MOSI | J1 pin 4 | Input during ISP | AVR ISP programming |
| UART RXD | PD0 pin 30 | UART_RXD | J2 pin 03 | Input | Arduino Serial RX |
| UART TXD | PD1 pin 31 | UART_TXD | J2 pin 04 | Output | Arduino Serial TX |
| Spare GPIO | PB0 pin 12 | GPIO_PB0 | J2 pin 06 | Digital I/O | Example blink/test output |
| CAN SPI CS | PB2 pin 14 | CAN_CS | U5 MCP2515 ~CS | Output | Active-low CAN controller chip select |
| CAN SPI MOSI | PB3 pin 15 | SPI_MOSI | U5 SI, U9 B1, ISP J1 | Output | Shared SPI MOSI for MCP2515 and Ethernet level shifter |
| CAN/Ethernet SPI MISO | PB4 pin 16 | SPI_MISO | U5 SO, U9 B2, ISP J1 | Input | Shared SPI MISO |
| CAN/Ethernet SPI SCK | PB5 pin 17 | SPI_SCK | U5 SCK, U9 B3, ISP J1 | Output | Shared SPI clock |
| CAN interrupt | PD2 pin 32 | CAN_INT | U5 MCP2515 ~INT | Input | Active-low interrupt from CAN controller |
| RS485 RX | PD4 pin 2 | RS485_RXD | U7 RO | Input | SoftwareSerial RX for Modbus RTU |
| RS485 TX | PD5 pin 9 | RS485_TXD | U7 DI | Output | SoftwareSerial TX for Modbus RTU |
| RS485 driver enable | PB1 pin 13 | RS485_DE | U7 DE and ~RE | Output | HIGH transmit, LOW receive |
| Ethernet CS | PD7 pin 11 | ETH_CS_5V | U9 B4 → J9 SCNn | Output | Active-low WIZ850io chip select through level shifter |
| Ethernet interrupt | PD3 pin 1 | ETH_INT_5V | U9 B5 ← J9 INTn | Input | Active-low WIZ850io interrupt through level shifter |
| Ethernet reset | PD6 pin 10 | ETH_RST_5V | U9 B6 → J9 RSTn | Output | Hold low at least 500 us, wait 50 ms after release |
platformio.iniIni
[env:atmega328p] platform = atmelavr board = ATmega328P framework = arduino board_build.f_cpu = 16000000L upload_protocol = custom monitor_speed = 115200 ; Example avrdude upload command for USBasp. Adjust programmer and port for your tool. upload_command = avrdude -p m328p -c usbasp -U flash:w:$SOURCE:i
upload_command to match your local programmer setup.src/main.cpp:Cpp
#include <Arduino.h> // Nets from schematic constexpr uint8_t PIN_UART_RXD = 0; // PD0 / Arduino D0 / J2 pin 03 constexpr uint8_t PIN_UART_TXD = 1; // PD1 / Arduino D1 / J2 pin 04 constexpr uint8_t PIN_GPIO_PB0 = 8; // PB0 / Arduino D8 / J2 pin 06 constexpr uint8_t PIN_RS485_DE = 9; // PB1 / Arduino D9 / U7 DE and ~RE constexpr uint8_t PIN_CAN_CS = 10; // PB2 / Arduino D10 / U5 ~CS constexpr uint8_t PIN_SPI_MOSI = 11; // PB3 / Arduino D11 / ISP J1 pin 4 constexpr uint8_t PIN_SPI_MISO = 12; // PB4 / Arduino D12 / ISP J1 pin 1 constexpr uint8_t PIN_SPI_SCK = 13; // PB5 / Arduino D13 / ISP J1 pin 3 constexpr uint8_t PIN_CAN_INT = 2; // PD2 / Arduino D2 / U5 ~INT constexpr uint8_t PIN_ETH_INT = 3; // PD3 / Arduino D3 / J9 INTn via U9 constexpr uint8_t PIN_RS485_RX = 4; // PD4 / Arduino D4 / U7 RO constexpr uint8_t PIN_RS485_TX = 5; // PD5 / Arduino D5 / U7 DI constexpr uint8_t PIN_ETH_RST = 6; // PD6 / Arduino D6 / J9 RSTn via U9 constexpr uint8_t PIN_ETH_CS = 7; // PD7 / Arduino D7 / J9 SCNn via U9 constexpr unsigned long BLINK_INTERVAL_MS = 500; unsigned long lastToggleMs = 0; bool gpioState = false; void setup() { // UART on PD0/PD1 via J2 pins 03/04 Serial.begin(115200); Serial.println(F("ATmega328P minimal board firmware starting")); // Spare GPIO on PB0 / Arduino D8 pinMode(PIN_GPIO_PB0, OUTPUT); digitalWrite(PIN_GPIO_PB0, LOW); pinMode(PIN_CAN_CS, OUTPUT); digitalWrite(PIN_CAN_CS, HIGH); pinMode(PIN_CAN_INT, INPUT_PULLUP); pinMode(PIN_RS485_DE, OUTPUT); digitalWrite(PIN_RS485_DE, LOW); // receive mode by default pinMode(PIN_ETH_CS, OUTPUT); digitalWrite(PIN_ETH_CS, HIGH); pinMode(PIN_ETH_RST, OUTPUT); digitalWrite(PIN_ETH_RST, LOW); delay(1); // WIZ850io requires at least 500 us reset low digitalWrite(PIN_ETH_RST, HIGH); delay(50); // wait before first SPI access pinMode(PIN_ETH_INT, INPUT_PULLUP); // Keep SPI pins in safe idle state unless used by firmware. pinMode(PIN_SPI_MOSI, INPUT_PULLUP); pinMode(PIN_SPI_MISO, INPUT_PULLUP); pinMode(PIN_SPI_SCK, INPUT_PULLUP); // AREF is decoupled in hardware. Use VCC as default ADC reference unless external reference is connected intentionally. analogReference(DEFAULT); Serial.println(F("Init complete. PB0/D8 will toggle every 500 ms.")); } void loop() { const unsigned long now = millis(); if (now - lastToggleMs >= BLINK_INTERVAL_MS) { lastToggleMs = now; gpioState = !gpioState; digitalWrite(PIN_GPIO_PB0, gpioState ? HIGH : LOW); Serial.print(F("PB0/D8 state: ")); Serial.println(gpioState ? F("HIGH") : F("LOW")); } // UART echo test through J2 pins 03/04. if (Serial.available() > 0) { const int c = Serial.read(); Serial.write(c); } }
VCC and GND.Bash
pio run
Bash
pio run -t upload
Bash
pio device monitor -b 115200
Welcome 👋
Flux helps you build PCBs faster with an AI teammate!
Create your account to collaborate, stay updated, fork your own version, and get instant answers from our AI agent.