Forum: Mikrocontroller und Digitale Elektronik ATTiny816 System Clock


von Dob S. (dobstronsky)


Lesenswert?

Hallo,

ich habe ein Projekt welches einen ATTiny816 involviert. Ich habe das 
makefile soweit aufgesetzt und kann jetzt losprogrammieren.

Ich wollte mich jetzt darum kümmern, dass die Systemclock auf 10KHz 
eingestellt wird. Im Datenblatt steht nämlich 10KHz bei 3,3v. Zum 
flashen nutze ich eine Microchip IDE mit Atmel ICE programmer, darin ist 
die FUSE auf 20MHz konfiguriert ist, ich könnte noch 16KHz auswählen 
aber nichts weiter.
Ich habe sehr schnell festgestellt, dass der Controller sehr langsam ist 
und habe dann versuchsweise mal die untenstehende Main programmiert, 
umzusehen wie schnell die Clock tatsächlich ist.

Ich setze einen Pin high mache 200 nops (1 Takt Zyklus pro nop) und es 
dauert 240 us. Demnach läuft meine Systemclock mit 0,8 MHZ. Das ist 
ganzschön wenig. uint32_t variablen werden unerträglich lange 
verarbeitet.





int main(void)
{

  gpio_init(PER_PORT_A_DIR, PER_PORT_B_DIR, PER_PORT_C_DIR);


    while (1)
    {
        PORTB.OUTSET = 0x04;


    uint8_t i;
    for(i=0; i<200; i++) asm volatile("nop");



        PORTB.OUTCLR = 0x04;

    uint8_t j;
        for(j=0; j<100; j++) { asm volatile("nop"); }
    }
}

Ich bin jetzt absolut ratlos wie ich die korrekte Clock setze. Über die 
IDE kann ich wie gesagt zwischen 20MHz und 16MHz wählen, die High Phase 
verändert sich dann auch, also funktioniert das, aber es ist immernoch 
viel zu langsam.

Die Clockregister händisch zu schreiben ändert auch nichts.
    CLKCTRL.MCLKCTRLA = 0x00u;

    // Schritt 2: Divider auf 1 setzen (PDIV = 0)
     CLKCTRL.MCLKCTRLA = 0x00u;

von H. H. (hhinz)


Lesenswert?

Dob S. schrieb:
> Im Datenblatt steht nämlich 10KHz bei 3,3v.

In welchem Datenblatt?

von S. L. (sldt)


Angehängte Dateien:

Lesenswert?

> Im Datenblatt steht nämlich 10KHz bei 3,3v.

?
  In meinem steht, u.a., '0-10 MHz @ 2.7V – 5.5V'. Und CLKCTRL.MCLKCTRLA 
steht unter CCP, s. Anhang.

PS:

Kilo mit Mega verwechselt, sowie CLKCTRL.MCLKCTRLA mit 
CLKCTRL.MCLKCTRLB?

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

> Ich setze einen Pin high mache 200 nops (1 Takt Zyklus pro nop)
> und es dauert 240 us.

Passt doch: 200 Schleifendurchgänge mit 1+1+2 Takten: Kehrwert von (240 
us durch 800) = 3.33 MHz - und genau damit läuft der ATtiny816 ab Werk.

von S. L. (sldt)


Angehängte Dateien:

Lesenswert?

> Ich bin jetzt absolut ratlos wie ich die korrekte Clock setze.

"Nach Diktat verreist" oder noch am Grübeln?

Das Programm im Anhang stellt den Systemtakt auf 10 MHz. 10 MHz / (1+2) 
/ 2 = 1.67 MHz an Pin B0.

von Dob S. (dobstronsky)


Lesenswert?

S. L. schrieb:
> Passt doch: 200 Schleifendurchgänge mit 1+1+2 Takten: Kehrwert von (240
> us durch 800) = 3.33 MHz - und genau damit läuft der ATtiny816 ab Werk

Stimmt es sind tatsächlich 4 Takte, ich hätte mir das im Assembler 
angucken sollen.

Ich habe viel mit uint32_t gearbeitet, die sind unfassbar langsam. Ich 
stricke das jetzt um zu uint8_t.

Nichtsdestotrotz, die Fuse steht auf 20MHz, aber ab Werk sind es 3,33 
MHz.

Wie erreiche ich denn 20MHz in einer 5V Appllikation?

von S. L. (sldt)


Lesenswert?

> Wie erreiche ich denn 20MHz in einer 5V Appllikation?

Na, wie gezeigt, nur eben mit CLKCTRL.MCLKCTRLB auf 0 gesetzt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Dob S. schrieb:
> Ich setze einen Pin high mache 200 nops (1 Takt Zyklus pro nop) und es
> dauert 240 us.

Wenn du eine bestimmte Anzahl von Cycles vertrödeln willst, dann 
__builtin_avr_delay_cycles().

https://gcc.gnu.org/onlinedocs/gcc/AVR-Built-in-Functions.html#index-_005f_005fbuiltin_005favr_005fdelay_005fcycles

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Dob S. schrieb:
> Hallo,
>
> Im Datenblatt steht nämlich 10KHz bei 3,3v. Zum
> ich könnte noch 16KHz auswählen
> Demnach läuft meine Systemclock mit 0,8 MHZ.

Du haust die Einheiten durcheinander. Möchtest du 10MHz oder 16MHz statt 
10kHz? Hz -> kHz -> MHz. Jeweils Faktor 1000.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

In Default Einstellung taktet er mit 20MHz internen Oszillator mit 
Prescaler 6, was am Ende 3,33MHz ergibt. Verfügbare Prescaler stehen im 
Manual im Kapitel 10.5.2. Wenn du 10MHz möchtest, verwendest du Teiler 2 
inkl. Enable Bit. Wenn du 20MHz möchtest, brauchst keinen Teiler. Dafür 
entweder alles auf 0 oder Enable Bit auf 0.
Weil das Register ein geschütztes Register ist, kann man das nicht 
einfach so ändern. Siehe Kapitel 10.3.5. Vor jeder solcher 
Registeränderungen muss folgende Zeile um die Sperre aufzuheben.
CPU_CCP = CCP_IOREG_gc;
1
// Main Clock Prescaler
2
CPU_CCP = CCP_IOREG_gc;
3
CLKCTRL.MCLKCTRLB = (  );

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Veit D. schrieb:
> Vor jeder solcher
> Registeränderungen muss folgende Zeile um die Sperre aufzuheben.
> CPU_CCP = CCP_IOREG_gc;
>
1
> // Main Clock Prescaler
2
> CPU_CCP = CCP_IOREG_gc;
3
> CLKCTRL.MCLKCTRLB = (  );
4
>

Davon würde ich abraten.  Besser:
1
#include <avr/io.h>
2
3
void func (uint8_t value)
4
{
5
    _PROTECTED_WRITE (CLKCTRL.MCLKCTRLB, value);
6
}

Nur so ist sichergestellt, dass das CCP Timing eingehalten wird.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

gut zu wissen. Danke.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.