AVR clock prescaler (CLKPR) und gcc-Codeoptimierung

OP #3108946
Lesenswert?
• ▲
▼
Da der Clock Prescaler mich die letzten zwei Tage beschäftigt hat, habe 
ich mal meine Ergebnisse zusammengetragen. Alles was ich hier schreibe, 
habe ich am attiny2313 ausprobiert, das Problem besteht aber auch bei 
anderen AVR µCs.


Um den Faktor des clock prescalers einzustellen, muss man innerhalb von 
4 Taktzyklen zweimal auf das Register CLKPR zugreifen: im ersten Zugriff 
setzt man das höchste Bit (CLKPCE) auf 1 alle anderen auf 0, im zweiten 
Zugriff stellt man den Teilungsfaktor ein. Mit avr-gcc code sieht das 
etwa so aus:
1
  CLKPR = (1<<CLKPCE);
2
  CLKPR = 1;

Sofern man Code-Optimierung benutzt (gcc Schalter -Os), funktioniert das 
auch wie erwartet, verwendet man keine Optimierung (-O0), funktioniert 
es auf einmal nicht mehr. Der Faktor des clock prescalers wird einfach 
nicht geändert. Den Grund dafür kann man im Assemblerlisting finden.
Mit Optimierung erhält man:
1
  ldi r24,lo8(-128)   ;  tmp44,
2
  out 70-32,r24   ; ,, tmp44
3
  ldi r24,lo8(1)   ;  tmp46,
4
  out 70-32,r24   ; ,, tmp46

Ohne Optimierung wird daraus:
1
  ldi r24,lo8(70)   ;  D.2172,
2
  ldi r25,hi8(70)   ;  D.2172,
3
  ldi r18,lo8(-128)   ;  tmp54,
4
  movw r30,r24   ; , D.2172
5
  st Z,r18   ; , tmp54
6
  ldi r24,lo8(70)   ;  D.2173,
7
  ldi r25,hi8(70)   ;  D.2173,
8
  ldi r18,lo8(1)   ;  tmp55,
9
  movw r30,r24   ; , D.2173
10
  st Z,r18   ; , tmp55

Man erkennt direkt, dass die Zugriffe auf das Register CLKPR (das sind 
die Zeilen mit "st Z,r18") nicht mehr innerhalb von 4 Taktzyklen 
erfolgt.

Sofern man nicht auf die Optimierung zurückgreifen möchte, lässt sich 
das Problem umgehen, indem man den Zugriff per inline assembler 
realisiert:
1
  asm volatile (
2
    "st Z,%1" "\n\t"
3
    "st Z,%2"
4
    : :
5
    "z" (&CLKPR),
6
    "r" ((uint8_t) (1<<CLKPCE)),
7
    "r" ((uint8_t) 1)  // neuer Wert für CLKPR
8
  );

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.