Attiny3216/3217: Taktänderung

OP #7858361
Lesenswert?

Hi Leute,

wenn ich in bisherigen XMega-Projekten die Taktquelle oder den Prescaler ändern wollte, ging das über diesen Weg hier:

1
CCP = CCP_IOREG_gc;

Im Attiny wollte ich nun den Prescaler aktivieren, weil der µC nicht bei 5V, sondern 3.3V arbeitet. Das habe ich mit folgendem Code versucht:

1
CCP = CCP_IOREG_gc;
2
CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_2X_gc;
3
CCP = CCP_IOREG_gc;
4
CLKCTRL.MCLKCTRLB = CLKCTRL_PEN_bm;

Das scheint aber nicht mehr zu funktionieren. Der Code wird vom Compiler nicht beanstandet, ist aber trotzdem wirkungslos. Stattdessen bin ich erst in einer Appnote auf Lösung mit "ccp_write_io()" gestoßen - statt wie erhofft im Datenblatt selbst. Zudem taucht online immer wieder "_PROTECTED_WRITE()" - auch in den microchip-docs selbst - auf, das aber mit dem beschriebenen Include von <avr/io.h> unter Microchip Studio nicht bekannt ist.

Kann hier jemand meine Verwirrung lösen und mir erklären, ob ich

a) Fehler in diesen vier Zeilen gemacht hab oder warum diese ignoriert werden?

b) Wie ich die Quelle von "ccp_write_io()" finde? Im Header "cpufunc.h" ist nur deren Deklaration.

c) Woher nun plötzlich "_PROTECTED_WRITE()" stammt?

Vielen Dank

#7858380
Lesenswert?

Ich habe nicht das Datenblatt deines Controller gelesen, aber:

Peder schrieb:

a) Fehler in diesen vier Zeilen gemacht hab oder warum diese ignoriert werden?

So wie ich das sehe ist das Register was du schreiben möchtest protected. Mittlerweile gibt es von vielen Herstellern solche Mechanismen. Es soll verhindern dass aus Versehen (Wild Pointer o.ä) Einstellungen verändert werden. Dafür definieren sie spezielle abfolgen die Taktgenau eingehalten werden müssen. Ansonsten wird der write abgelehnt. Dafür sollen diese Makros/Funktionen dienen. In ihnen wird die Abfolge sicher gestellt. Bei dir ist halt die Frage was der Compiler daraus macht und ob die Abfolge stimmt. Oder ob allgemein noch etwas fehlt (kann ich nicht beurteilen).

Peder schrieb:

c) Woher nun plötzlich "_PROTECTED_WRITE()" stammt?

https://onlinedocs.microchip.com/oxy/GUID-317042D4-BCCE-4065-BB05-AC4312DBC2C4-en-US-2/GUID-D8441E18-BA0F-48F0-949E-19B27108C3A7.html

#7858537
Lesenswert?

ATtiny1614 (sollte aber keine Rolle spielen): ohne die auskommentierten Zeilen hat B0 eine Frequenz von 562 kHz, mit 1.68 MHz (mein uC läuft offenbar etwas zu schnell):

1
#include "avr/io.h"
2
int main (void)
3
{
4
// CCP = CCP_IOREG_gc;
5
// CLKCTRL.MCLKCTRLB = CLKCTRL_PEN_bm;   // /2 (statt /6)
6
VPORTB_DIR = 0b00000001;
7
while (1) {
8
  VPORTB_IN = 0b00000001;
9
}
10
}

PS:

Im Attiny wollte ich nun den Prescaler aktivieren ...

Der Prescaler ist nach Reset aktiv, denn der Reset-Wert von CLKCTRL.MCLKCTRLB ist 0x11, d.h. /6.

PPS: Alternativ geht bei mir auch

1
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB,0x01);  // /2 (statt default /6)
OP #7858565
Lesenswert?

Also erstmal Danke vorab an alle und: der Grund, warum überhaupt nichts ins Register geschrieben wurde, auch nicht das Enable-Bit aus der vierten Zeile, ist anscheinend der Optimierungsgrad des Compilers. Wenn ich (zum Debuggen) die Optimierung auf (-O0) setze, funktioniert da überhaupt nichts. Mit Level (-O3) geht das. Etwas.

Harald K. schrieb:

Volltextsuche im Dateisystem, dort, wo auch immer der Compiler/die Toolchain installiert ist?

1
> cd wohin/auch/immer
2
> findstr /s /c:"ccp_write_io" *.c

Da gibt es bei mir nur Header und html-Dokus. Ohne sinnvollen Inhalt. Aber ich nehme die jetzt einfach so hin.

Georg M. schrieb:

Die zweite Zeile wird einfach durch die vierte Zeile überschrieben.

1
>   _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);

Das stimmt, und es zeigt sich ein Neues Problem: Selbst, wenn ich (CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm) direkt als Zahl ins Register schreibe, steht trotzdem nachher was anderes drin.

1
CCP = CCP_IOREG_gc;
2
CLKCTRL.MCLKCTRLB = 0b00000011; // führt aus irgendeinem Grund zu 0b00010001

Unabhängig von der Methode. Ob ich nun (CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm) ver-odere oder wie oben in vier Zeilen Beides getrennt setze - aber mit |=, es kommt immer das gleiche falsche Ergebnis heraus.

So langsam wird mein Post unübersichtlich, aber wenn ich im Debugger Zeile für Zeile voranschreite (mit Step-Into), ist alles richtig. Egal ob in Form von zwei oder vier Zeilen. Wenn der Code aber normal durchlaufen wird, dann kommt das Falsche Ergebnis heraus. Keine Ahnung, was ich davon halten soll.

Im Moment funktioniert zumindest diese Methode:

1
ccp_write_io( (void *)&CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);

"_PROTECTED_WRITE()" kennt mein Atmel Studio nicht, genausowenig wie "CPU.CCP". Zudem wird "_PROTECTED_WRITE()" auf der Webseite nicht näher beschrieben. Oder aber, es funktioniert nur mit XMEGAs und nicht mit ATtinys.

#7858626
Lesenswert?

Peder schrieb:

Wenn ich (zum Debuggen) die Optimierung auf (-O0) setze, funktioniert da überhaupt nichts.

Das ist klar, -O0 macht alle Zugriffe mindestens 16-Bittig, d.h. der AVR rechnet max 50% schnell. Am besten ist eigentlich immer -Os.

Für die klassic AVRs gibt es in der <power.h> entsprechende Assembler-Macros (clock_prescale_set), die auch unter -O0 laufen. Die kümmern sich auch um den atomaren Zugriff (Interruptsperre).

(Firma: ab) #7858742
Lesenswert?

Peder schrieb:

"_PROTECTED_WRITE()" kennt mein Atmel Studio nicht,

Ein neues Projekt mit ATtiny3216 in Microchip Studio erstellt und mit Native-Toolchain compiliert.

Compiler compiliert ohne Fehler und includiert

C:\Microchip\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\xmega.h.

Darin finden sich:

1
#define _PROTECTED_WRITE(reg, value)
2
#define _PROTECTED_WRITE_SPM(reg, value)

Die neuen ATtinys sind von XMEGA abgeleitet!

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren