Forum: Mikrocontroller und Digitale Elektronik ATTiny861, Timer, OCR1A, Output Compare


von beginner (Gast)


Lesenswert?

Hallo,

Ich möchte output compare mode des ATTiny861 nutzen.
das Problem hierbei ich übersehe scheinbar eine notwendige Einstellung 
bei den Registern.

egal welchen Wert ich in OCR1A schreibe, am Ausgang ändert sich die 
Frequenz nicht.

bei "aktiviertem" Interrupt(TIMSK = 0b01000000;) ergeben sich 250kHz
wenn ich Diesen(TIMSK = 0b01000000;) auskommentiere, fällt die Frequenz 
auf 125kHz ab.

Als Timer/System Clock möchte ich die 64MHz der PLL nutzen.

BTW: ich hab das Programm(in abgeänderter Form) zuvor für einen Tiny45 
benutzt => hat tadellos funktioniert.

Was hab ich vergessen ??

Danke
1
int main(void)
2
{  
3
  sei();
4
  DDRB = 0b00000010;
5
6
  PLLCSR = 0b00000110; 
7
  
8
        TCCR1A = 0b01001000;
9
  TCCR1B = 0b00000001;
10
  
11
  TCCR1C = 0b01000000;
12
  TCCR1E = 0b00000010;
13
  
14
  TIMSK = 0b01000000;
15
  
16
    while(1)
17
    {    
18
    OCR1A = 0b00000001;
19
    }  
20
}

von Karl H. (kbuchegg)


Lesenswert?

beginner schrieb:

> Was hab ich vergessen ??

Das hier im Forum keiner großartig Lust hat, derartige Bitkonstanten ...

>   TCCR1A = 0b01001000;
>   TCCR1B = 0b00000001;
>
>   TCCR1C = 0b01000000;
>   TCCR1E = 0b00000010;
>
>   TIMSK = 0b01000000;

... mit dem Datenblatt auseinanderzupfriemeln, nur um zu sehen was du da 
eigentlich alles eingestellt hast.

Grundregel: mach es deinem Helfer leicht dir zu helfen. Wenn ich dauernd 
im Datenblatt hin und herscrollen muss, nur um die symbolischen Bitnamen 
zu eruieren um dann in der weiteren Beschreibung nachzulesen, was diese 
nunmehr bekannten Bits bedeuten, dann ... pfeif ich drauf.

von spess53 (Gast)


Lesenswert?

Hi

>Als Timer/System Clock möchte ich die 64MHz der PLL nutzen.

Timer ja. System 16MHz. Hast du auch die Fuses passend eingestellt?

MfG Spess

von beginner (Gast)


Lesenswert?

hallo

arbeite mit avr studio 5, PLL ist als sysclk eingestellt.

.....zu den registern(hab inzwischen Änderungen vorgenommen welche 
jedoch keinerlei Änderung bewirkten) bzw deren bedeutung:
1
TCCR1A = 0b01001000;//bit 7&6:Toggle on Compare match OC1A Pin 
2
                    //bit 3:Force Output Compare Match 1A
3
  
4
  TCCR1B = 0b00000001;//Timer/Counter1 Prescaler Select: 
5
                      //timer clk wird nicht geteilt 
6
  
7
  TCCR1C = 0b01001000; //shadow bits gleicher INhalt wie TCCR1A 
8
9
  
10
  TIMSK = 0b01000000;//bit 6: OCIE1A Timer/Counter1 Output Compare Interrupt Enable  
11
  
12
  PLLCSR = 0b00000111;// 64 MHz clock für Timer 1

Danke

von kommentar (Gast)


Lesenswert?

Hallo Beginner,

lernen zu lernen, wenn Karl-Heinz dich bitte die Bits umzuschreiben, 
dann solltest Du nicht darüber hinweg lesen !

Das sieht dann so aus und die 'Funktion' ist sehr schnell zu Überprüfen:
1
TCCR1A = _BV(COM1A0) | _BV(FOC1A);

von kommentar (Gast)


Lesenswert?

Dann findet man noch im Datenblatt

Bit 0 – PLOCK: PLL Lock Detector
When the PLOCK bit is set, the PLL is locked to the reference clock. The 
PLOCK bit should be
ignored during initial PLL lock-in sequence when PLL frequency 
overshoots and undershoots,
before reaching steady state. The steady state is obtained within 100 
μs. After PLL lock-in it is
recommended to check the PLOCK bit before enabling PCK for 
Timer/Counter1.

von Beginner (Gast)


Lesenswert?

hallo Kommentar,

also das sollte kein absichtliches drüber hinweg lesen sein, ich hab 
seine Aufforderung so interpretiert, dass ich mittels Kommentare die 
Funktion der einzelnen Bits aufzeigen!

bzgl. _BV()
"However, using the macro often makes the program better 
readable."[avr-libc 1.8.0]
Was hats mit dem auf sich, noch nie zuvor gesehen(Beginner;+)

kommentar schrieb:
> lernen zu lernen, wenn Karl-Heinz dich bitte die Bits umzuschreiben,

In den Kommentaren steht doch drinnen, ..."Toggle on Compare match 
OC1A", ...Force Output.....usw...
verbirgt sich hinter Deinem Code etwas Anderes ?


Soweit ich den Hinweis mit dem Datenblatt richtig verstehe sollte man 
warten bis die PLL auch wirklich arbeitet/initialisiert ist bevor man 
das Bit im Timer Register setzt.

Das hab ich übersehen(danke für den Hinweis), nur die Sache ist die, der 
Timer läuft ja, nur ständig mit dem gelichen Takt(im Falle der 
ausbleibenden PLL), das erklärt mir aber noch nicht wieso sich beim 
ändern des Compare Wertes die Frequenz des ausgegebenen Signal nicht 
ändert ?

Danke

von Karl H. (kbuchegg)


Lesenswert?

Beginner schrieb:

> In den Kommentaren steht doch drinnen, ..."Toggle on Compare match
> OC1A", ...Force Output.....usw...
> verbirgt sich hinter Deinem Code etwas Anderes ?

Das was 'kommentar' geschrieben hat ist für den Compiler verbindlich. 
Die Bits werden tatsächlich gesetzt (Sofern man sich nicht im Register 
vertan hat).

Dein Kommentar ... ist Schall und Rauch. Du kannst da hinschreiben was 
du willst. Deswegen muss das noch lange nicht mit den Bitnamen 
übereinstimmen.


Nur so als Beispiel:
Du hast geschrieben
1
  TIMSK = 0b00100000;//bit 6: OCIE1A Timer/Counter1 Output Compare Interrupt Enable
Genausogut hättest du auch schreiben können
1
  TIMSK = 0b00100000;//bit 6: OFVIE1 Timer/Counter1 Overflow Interrupt Enable
Interessiert keine Sau (und vor allen Dingen nicht den Compiler) dass 
der Kommentar falsch ist.

Benutzt du aber eine der beiden Schreibweisen
1
  TCCR1A = _BV(OCIE1A);
2
  TCCR1A = ( 1 << OCIE1A );
dann kann der Kommentar nicht falsch sein, weil es keinen Kommentar 
gibt und auch nicht braucht, der mich darüber aufklärt, dass das Output 
Compare Bit des Timers 1 (und zwar vom Kanal A) gesetzt wird. Das steht 
nämlich im Code! Das dadurch das Bit 6 auf 1 gesetzt wird, ist nett, mir 
aber völlig wurscht. Das ist ein Detail, das ich nicht wissen brauche, 
das weiß dafür der Compiler. Was ich wissen will ist, das das OCIE1A 
gesetzt wird! Und da das im Code steht, und nicht in einem Kommentar, 
kann ich mich auch darauf verlassen, dass das OCIE1A auch wirklich 
gesetzt wird. Egal welche konkrete Bitnummer es jetzt im TCCR1A hat.

Nota Bene:
Ist dir aufgefallen, dass ich (absichtlich) bei
1
  TIMSK = 0b00100000;//bit 6: OCIE1A Timer/Counter1 Output Compare
das 1 Bit um 1 Stelle nach rechts geschoben habe? Das ist nicht mehr Bit 
6 sondern Bit 5. Ich wette es ist dir nicht aufgefallen. Und auch nach 
dem 10-ten mal drüberlesen wäre es dir nicht aufgefallen. Selbst wenn du 
draufkommst, das deine ISR nicht angesprungen wird, wäre es dir nicht 
sofort aufgefallen, denn du hättest dich immer am (falschen) Kommentar 
orientiert. Soviel zur Relevanz von derartigen Detail-Kommentaren und 
deren Wert bzw. deren Tendenz zu Verschleierung und Verwirrung, wenn es 
um Fehlersuche geht.
Wenn du etwas mittels Code ausdrücken kannst, dann tu das auch!
Das spart dir zum einen das Kommentarschreiben und sorgt zudem dafür, 
dass dieser nicht geschriebene Kommentar nicht falsch sein kann.

> das erklärt mir aber noch nicht wieso sich beim ändern des
> Compare Wertes die Frequenz des ausgegebenen Signal nicht
> ändert ?

Welchen Timer Modus benutzt du denn?
Wenn OCR1A die Frequenz ändern soll, sollte das der CTC Modus sein. Hast 
du den eingestellt?
Und wo ist eigentlich die ISR zum freigegebenen Interrupt?

von Beginner (Gast)


Lesenswert?

servus Karl Heinz,

danke für Deine Tipps mit den Register Inits!(habs entsprechend 
geändert)

entscheidend war aber der Hinweis hier:
Karl Heinz Buchegger schrieb:
> Welchen Timer Modus benutzt du denn?
> Wenn OCR1A die Frequenz ändern soll, sollte das der CTC Modus sein. Hast
> du den eingestellt?
> Und wo ist eigentlich die ISR zum freigegebenen Interrupt?

blöder Weise kann der Timer1 nicht nach meinen Vorstellungen(wie zuvor 
beim erwähnten Tiny45 Bsp.) arbeiten, weil er gar keinen CTC Mode 
bereitstellt.

=> ich werde den Timer0 benützen der kann das nämlich.

Danke

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.