Forum: Mikrocontroller und Digitale Elektronik Frage : Vorteiler CLKPR


von M. B. (freiberger77)


Lesenswert?

Hallo,
ich habe bisher den System-Takt nur über FUSE-Bit (CKDIV8) eingestellt.
Jetzt möchte ich aber den Takt per Software steuern.

Der AVR (ATTiny2313) soll die ganze Zeit mit sehr niedriger Frequenz 
laufen, aber bei Bedarf Daten senden (mit Quarztakt - CKDIV8=0).

Ich habe gelesen, dass sowas mit CLKPR gehen soll, aber leider läuft 
mein Beispielprogramm nur mit vollem Takt, egal welchen Wert ich für 
CLKPR angebe...
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
void main()
5
{
6
    CLKPR = 16; // Systemtakt-Teiler  
7
8
    DDRB  = 0b11111111;             // Alle auf OUTPUT
9
    while(1) 
10
    {                
11
     PORTB = 0b00000000;            // LEDs ON
12
     _delay_ms(500);
13
     PORTB = 0b11111111;            // LEDs OFF
14
     _delay_ms(500);
15
    }
16
    return 0;
17
}

Woran kann das liegen ?

von Benedikt K. (benedikt)


Lesenswert?

Lies dir mal den Abschnitt rund um CLKPR im Datenblatt genau durch. Zum 
Umschalten musst du nämlich auch das CLKPCE Bit setzen.
Du stellst das Register auch auf einen ungültigen Wert ein.

von M. B. (freiberger77)


Lesenswert?

Sorry, im Datenblatt habe ich noch nicht geschaut, da es im AVR-Studio 
auch keinen Fehler angezeigt hat.
Habe im Forum aber nix passendes zu diesem Thema gefunden.
Habe es auch mit 0,4,16,32 probiert, aber ohne Änderung.
Werde gleich mal schauen, Danke

von M. B. (freiberger77)


Lesenswert?

OK, ds CLKPCE ist Bit 7 im CLKPR.
Leider ist mein englisch nicht soooo gut, um die ganzen Kleinigkeiten zu 
verstehen.
Ich habe es jetzt mit
CLKPR = 0x10000100;
versucht, aber es klappt auch nicht...

von Benedikt K. (benedikt)


Lesenswert?

Schritt 1:
Nur CLKPCE setzen, alle anderen Bits auf 0.
Schritt 2 (muss innerhalb von 4 Takten nach Schritt 1 ausgeführt 
werden): Den gewünschten Prescaler setzen.

von M. B. (freiberger77)


Lesenswert?

also so ?
CLKPR = 0x10000000;
CLKPR = 0x10000100;

Geht aber auch nicht. Bin scheinbar doch zu blöd für sowas... ;-)

von Benedikt K. (benedikt)


Lesenswert?

Im zweiten Schritt CLKPCE nicht mehr setzen. Das sollte funktionieren.

von M. B. (freiberger77)


Lesenswert?

nee, leider nicht.
Habe ich im Frust auch schon versucht...

Ist es dann eigentlich egal, ob CKDIV8 gesetzt ist, oder wird immer erst 
der CKDIV8 genommen und dazu der CLKPCE ?

von Benedikt K. (benedikt)


Lesenswert?

Es sollte gehen. So stehts zumindest im Datenblatt und so funktioniert 
es auch bei mir.

Die CKDIV Fuse beeinflusst nur den Standardwert den das CLKPR nach dem 
Reset hat.

von M. B. (freiberger77)


Lesenswert?

kann es sein, dass der Optimizer den ersten Wert einfach ignoriert ?
Keine Ahnung, was das Ding alles löscht ?!

von Benedikt K. (benedikt)


Lesenswert?

Nein, die Register sind alle als volatile definiert, somit darf er dort 
nichts wegoptimieren.
Interrupts sollten auch nicht an sein (wegen den max. 4 Takten zwischen 
den beiden Schreibvorgängen).

von M. B. (freiberger77)


Lesenswert?

ja, Interupts habe ich auch nicht aktiviert...
Bin total ratlos... Gibt es noch mehr FUSE-Bits, die ich beachten muß ?

von Benedikt K. (benedikt)


Lesenswert?

Versuch das Umschalten mal über die vom gcc gelieferten Funktionen:
http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html

von M. B. (freiberger77)


Lesenswert?

das schein ganz gut zu klappen.
Allerdings kommt ab Wert 5 oder 6 ein SPI-Mode-Error (habe aber mal die 
SPI-Frequenz auf MIN gesetzt).

Danke, scheint so zu funktionieren..

von Simon K. (simon) Benutzerseite


Lesenswert?

Marco B. schrieb:
> also so ?
> CLKPR = 0x10000000;
> CLKPR = 0x10000100;
>
> Geht aber auch nicht. Bin scheinbar doch zu blöd für sowas... ;-)

Das hat bis jetzt echt niemand gemerkt oder? 0x ist das Prefix für 
Hexadezimal... Und nicht für Binär.

CLKPR = 0x80;
CLKPR = 0x04;

von M. B. (freiberger77)


Lesenswert?

manchmal ist es echt wie verhext...
jetzt klappt es auch so... Vielen Dank ...

CLKPR = 0b10000000;
CLKPR = 0b00000100;

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.