0

I am programming an attiny202 which as per datasheet can run up to 20Mhz, but after compiling/uploading this simple code to the attiny202 and watch the PA2 pin on the oscilloscope, I see that the pin oscilates at ~2.5MHz which is around 10x slower than I would expect, this is even I disable prescaling, am I missing something? (I am new into programming microcontrollers)

note: VCC is 5V (from lab bench PSU)

main.c

#include <avr/io.h>
int main(void)
{
 // no prescaling (if lesss than 4.5V, this is overclocking)
 _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);
 PORTA_DIR = _BV(2);
 while(1)
 {
 PORTA_OUTTGL = _BV(2);
 }
}

Makefile

PRG = main
CC = avr-gcc
MCU_TARGET = attiny202
OPTIMIZE = -Os
OBJCOPY = avr-objcopy
UART = /dev/ttyUSB0
all: $(PRG).elf $(PRG).hex
$(PRG).elf: $(PRG).c » $(CC) -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(PRG).c -o $(PRG).elf
%.hex: %.elf
» $(OBJCOPY) -j .text -j .data -O ihex $< $@
clean:
» rm *.elf *.hex
burn: $(PRG).hex
» pymcuprog -t uart -d $(MCU_TARGET) -u $(UART) write -f $(PRG).hex --erase --verify

bitmaps from oscilloscope:

-enter image description here

same picture with more measurement information:

enter image description here

asked Nov 29, 2022 at 9:03
2
  • 2
    So you are toggling a pin in code and expect it to change at the same frequency as the clock? That won't work, since even such a simple action takes more clock pulses than one. I'm not that much into this to tell you how many cycles are needed, but I'm very sure it is significantly more than 1 Commented Nov 29, 2022 at 9:06
  • of course it wont run at same freq as the main clock!, toggling a value into a reg takes more than 1 cycle, I feel dumb, I am sorry, I have not slept much in the last 48 hours out of excitement seeing this working, is my first SOP8!, please, post your answer so I can accept it, going to sleep now before I ask more questions before thinking... Commented Nov 29, 2022 at 9:09

2 Answers 2

3

Just as a complement to chrisl's answer, if you disassemble the compiled program, you should see that your infinite loop looks like this:

1: sts 0x0407, r24 ; write to PORTA_OUTTGL
 rjmp 1b ; jump back to previous instruction

These instructions take two cycles each, for a total of four cycles per loop iteration. The loop is thus expected to run at F_CPU÷4 = 5 MHz. Since a cycle of the output waveform takes two toggles, you expect to see 2.5 MHz on the oscilloscope.

You should be able to speed this up by writing to the virtual port register VPORTA_IN instead of PORTA_OUTTGL. Virtual port registers are equivalent to regular port registers, but they are mapped into the I/O space of the microcontroller. This allows the compiler to replace the sts instruction by the shorter and faster out instruction. The loop should then complete in only 3 CPU cycles and output a waveform at 3.33 MHz.

answered Nov 29, 2022 at 10:30
3
  • oh thanks for this explanation!, why is the advantage then of using just non virtual port if vports are "better"? (of course there is a reason, but I am noob), care to explain?, thank you so much for your time Commented Nov 29, 2022 at 22:59
  • @JoeCabezas: The regular ports have extra functionality: set, clear and toggle register addresses for each underlying register. Also, the address space available for virtual ports is tiny, so most peripherals only have regular ports. Commented Nov 30, 2022 at 8:12
  • thank you, I will study more about vports then, very helpful! Commented Nov 30, 2022 at 10:32
1

You are constantly toggling a pin in software. This involves copying the register data to the working register, toggling the bit and writing the result back.

This takes way more than only 1 clock cycle. So the resulting frequency is way lower. With only software you just cannot get near the clock frequency of the microcontroller.

answered Nov 29, 2022 at 9:49
3
  • The code writes to an "output toggle" register, which is more efficient than doing the read-modify-write sequence entirely in software. Commented Nov 29, 2022 at 10:35
  • @EdgarBonet thank you, but still it seems like it takes a lot of cycles enought to reduce from 20MHz to 2.5Mhz, 10 cycles?, I really think I am missing something :/ Commented Nov 29, 2022 at 22:58
  • 1
    @JoeCabezas: 20 MHz / 2.5 MHz = 8 cycles, not 10. That is two loop iterations (because the output signal is toggled twice) at 4 CPU cycles per iteration. See my answer for the detailed cycle count. Commented Nov 30, 2022 at 8:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.