In my project I need to toggle some I/Os in a pretty short time, so I chose the new Arduino Nano Every with the ATmega4809 microcontroller which runs at 20MHz instead of the usual 16MHz.
With my Arduino Uno I was able to toggle an I/O with a frequency of 4MHz, which means it took the Microcontroller only two clock cycles to change the PORTx register. (See ArduinoUno.jpg attachment)
The Arduino IDE has the option to emulate the registers of the ATmega328 when using the Arduino Nano Every, because the ATmega4809 uses different mnemonics for the port registers.
This is the code I used for testing, with "registers emulation" activated and the registers for the ATmega328 used:
void setup() {
DDRB |= 0x01; // D8 is an output
}
void loop() {
PORTB |= 0x01; // set D8
PORTB &= 0xFE; // clear D8
}
With this code, i got a maximum frequency of about 2.7MHz which i expected because the ATmega328 registers had to be translated to the ATmega4809 registers. (see ArduinoEvery.jpg the lower trace)
But when I use the ATmega4809 registers directly with "registers emulation" turned off, I get a even lower frequency of only 2MHz. (see ArduinoEvery.jpg the upper trace)
I got the register names from the megaAVR 0-series data sheet:
To use pin number n as an output only, write bit n of the PORTx.DIR register to '1'. This can be done by writing bit n in
the PORTx.DIRSET register to '1', which will avoid disturbing the configuration of other pins in that group. The nth bit
in the PORTx.OUT register must be written to the desired output value.
Similarly, writing a PORTx.OUTSET bit to '1' will set the corresponding bit in the PORTx.OUT register to '1'. Writing a
bit in PORTx.OUTCLR to '1' will clear that bit in PORTx.OUT to zero. Writing a bit in PORTx.OUTTGL or PORTx.IN to
'1' will toggle that bit in PORTx.OUT.
This is the code with the ATmega4809 registers "registers emulation" turned off and the registers for the ATmega4809 used:
void setup() {
PORTE.DIRSET = 1<<3;
}
void loop() {
PORTE.OUTSET = 0x08;
PORTE.OUTCLR = 0x08;
}
I didn't use the toggle function, because I have to set the pin explicitly to either high or low.
I expected the frequency to be higher or at least the same with the correct registers than with registers emulation.
Can anyone explain why the frequency was even lower with the correct registers?