BXT

Back PSA: If you're a fan of ATmega, try AVR Dx

PSA: If you're a fan of ATmega, try AVR Dx

The first AVR ATmega microcontroller debuted in 1998 and took the world by storm. In contrast to other embedded 8-bit processors of the era, it required no external components, could run off a wide range of supply voltages, and worked with the GNU C Compiler when others required you to learn assembly or pay for proprietary tools.

Since then, ATmega MCUs remained the staple of hobby engineering. In recent years, their market position has been challenged by single-board computers and the wi-fi-capable ESP32; still, the AVR architecture remains the go-to option for those who want to get things done without wrangling schedulers or debugging congestion on the Cortex-M AHB.

Yet, what relatively few ATmega hobbyists realize is that Microchip recently released a revamped series of 8-bit AVR MCUs: AVR DA and DB, along with the more specialized AVR DD and DU. The products are not being marketed to hobbyists. Instead, they’re advertised for automotive and industrial applications. Still, they’re cheaper and better in almost all respects — and just as easy to use.

The price difference can be stark; for example, if you want a microcontroller with 128 kB of program memory, you can get AVR128DA28 for under $2 a piece; the cheapest older-generation chip with the same amount of flash — ATMEGA1284P — is $6.

When it comes to architectural improvements, the most universally useful change is that AVR Dx can internally generate clocks up to 24 MHz; the ATmega can only do 8 MHz, and you need external timing to reach 20 MHz. Another nice touch is a single-wire UPDI programming interface, simplifying PCB layout and saving space. The new chips also feature reduced power consumption, better ADCs and DACs, on-board op-amps, and programmable LUT-based logic units that can implement real-time automation without involving the CPU.

From the software side, the differences are small; you use the same avr-gcc, avr-libc, and avrdude toolchain, and most of the on-die peripherals are configured and operated roughly the same way. AVR Dx is not a drop-in replacement, but porting is a breeze.

To the extent that the semantics differ, the changes are for the better. For example, on the ATmega, you had no C-level idiom for the exceedingly common task of clearing or setting single output pins. Instead, you had to spell it out as read-modify-write operation. You then crossed your fingers and hoped the compiler outputs a single SBI or CBI opcode instead of what your program asked it to do:

void oled_send_cmd(uint8_t cmd) {  PORTA &= ~_BV(OLED_A_DC);  /* Clear the DC bit  */  PORTA &= ~_BV(OLED_A_WR);  /* Clear the WR- bit */  PORTB  = cmd;              /* Prepare command   */  PORTA |= _BV(OLED_A_WR);   /* Set the WR- bit   */}

In contrast, on an AVR Dx chip, you have separate “set” and “clear” registers, removing the need for wishful thinking and error-prone Boolean logic. The same function can be rewritten as:

void oled_send_cmd(uint8_t cmd) {  PORTA.OUTCLR = _BV(OLED_A_DC);  /* Clear the DC bit  */  PORTA.OUTCLR = _BV(OLED_A_WR);  /* Clear the WR- bit */  PORTB.OUT    = cmd;             /* Prepare command   */  PORTA.OUTSET = _BV(OLED_A_WR);  /* Set the WR- bit   */}

Microchip has a short migration doc explaining the differences between the platforms. If you prefer to learn from examples, I also published the source code for two of my earlier AVR Dx projects: an audio toy and an OLED game.

For more articles about MCU programming and electronics, click here.


source: https://lcamtuf.substack.com/p/psa-if-youre-a-fan-of-atmega-try
https://bxt.org/djfn5