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;
> 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
> 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.
> 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.
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?
> Wie erreiche ich denn 20MHz in einer 5V Appllikation?
Na, wie gezeigt, nur eben mit CLKCTRL.MCLKCTRLB auf 0 gesetzt.
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
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
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.