Forum: Mikrocontroller und Digitale Elektronik Attiny3216/3217: Taktänderung


von Peder (st_peter)


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

von Harald K. (kirnbichler)


Lesenswert?

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

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

von N. M. (mani)


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

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


Lesenswert?

an Peder:

Die ersten zwei Zeilen sind unnötig (werden ja ohnehin nachfolgend 
wieder überschrieben). Die zwei letzten sollten eigentlich 
funktionieren, allenfalls hätte ich 'CPU.CCP =' geschrieben.

von Georg M. (g_m)


Lesenswert?

Peder schrieb:
> a) Fehler in diesen vier Zeilen gemacht hab oder warum diese ignoriert
> werden?

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

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

von S. L. (sldt)


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)

: Bearbeitet durch User
von Peder (st_peter)


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.

von Georg M. (g_m)


Lesenswert?

Peder schrieb:
> "_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.

Funktioniert mit ATtiny412 und allen anderen.

von Peter D. (peda)


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).

: Bearbeitet durch User
von A. B. (Firma: ab) (bus_eng)


Angehängte Dateien:

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!

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.