Forum: Mikrocontroller und Digitale Elektronik Timer1 in CTC Modus


von Roland K. (roland_k)


Lesenswert?

Hallo,
bin gerade dabei den Timer1 im CTC Modus zu betreiben.
Also Vergleichswert ins Register schreiben.

Irgendwie läuft der Timer viel zu schnell ab. Woran kann das liegen?

Ich programmiere mit mikroC pro for AVR also keine includes.

Der Timer soll den Pin B0 5760 mal pro Sekunde schalten also 
"Interruptfrequenz" von 11520Hz (wegen toggeln)

Hier der Quelltext:

int Timer1counter;


void Timer1COMPA_ISR() org IVT_ADDR_TIMER1_COMPA {
PORTB.B0 = ~PORTB.B0;

//Nur zum Überprüfen
Timer1counter++;
if(Timer1counter>11000){
PORTB.B1 = ~PORTB.B1;
Timer1counter=0;
}

}

void main() {



  DDRB   = 0xFF;                // set PORTB as output
  PORTB  = 0;                   // clear PORTB

  TIMSK1 = 0b00010010;       //compare A Register Interrupt on

  y=1736;                 // write Compare Value in register
  OCR1AL = y;
  OCR1AH = (y>>8);
//MCU Clock Frequency 20 MHz
  TCCR1A = 0b00000000;
  TCCR1B = 0b00001001;
// 0b00000001 starte Timer1 mit Prescaler 1   s.D.-sheet 160

  SREG_I_bit = 1;                      // Interrupt enable



  while (1)
// Endless loop, port is changed inside Interrupt Service Routine (ISR)
    ;
}

Was könnte hier falsch sein?
Danke für Eure Hilfe.

Grüße Roland

von BrettvormKopf (Gast)


Lesenswert?

der code sieht ein wenig verwirrend aus^^ btw  ist das wirklich ein 
Atmel die register würden eher zum ARM passen.

wäre gut wenn du sagst wenn du  wichtige externe schaltteile wie zb 
einen oszillator verwendet hat.

beim atmel musst du auch einen prescaler einstellen da er ansonsten mit 
der normalen cpu ferquenz läuft.....

von Stefan E. (sternst)


Lesenswert?

1
  OCR1AL = y;
2
  OCR1AH = (y>>8);
Falsche Reihenfolge.

PS: Und warum gibst du 2 Interrupts frei, wenn du nur eine ISR hast?

von Roland K. (roland_k)


Lesenswert?

Jupp, ist ein ATmega 1284PU und läuft momentan mit internem Oszillator 
mit 20MHz.

Die Register sollten schon passen.
Hier das Datenblatt dazu:
http://www.atmel.com/Images/doc8272.pdf

20MHz / 65536 = 305 Interrupts pro Sek.
dann noch Prescaler von 8 -> 38 Interrupt pro Sek.

wegen toggeln -> 38/2 = 19 mal blinkt LED.

Also habe jetzt den ganzen Tag herumprobiert, aber irgendwie solls nicht 
sein xD

von Roland K. (roland_k)


Lesenswert?

@Stefan:

Danke, Ich glaub das wars!

Nur zum Verständnis. Wieso zuerst das H-Register
      H        L
Y= 00000000 00000000

OCR1AL = y /// werden hier nicht die letzten 8bit in das Register 
geschrieben

Dann 8mal shift nach rechts.
      H        L
y= xxxxxxxx 00000000


Jetzt ist das eigtl. Highbyte das Lowbyte also:

OCR1AH = (y>>8);

2 Interrupts? Gute Frage, zu oft rumprobiert? ;-)

Habs geändert:
TIMSK1 = 0b00000010;       //compare A Register Interrupt on
stimmts so?

Danke für Eure Hilfe!

von spess53 (Gast)


Lesenswert?

Hi

>Jupp, ist ein ATmega 1284PU und läuft momentan mit internem Oszillator
>mit 20MHz.

Halte ich für ein Gerücht.

MfG Spess

von Stefan E. (sternst)


Lesenswert?

Roland K. schrieb:
> Nur zum Verständnis. Wieso zuerst das H-Register
>       H        L
> Y= 00000000 00000000
>
> OCR1AL = y /// werden hier nicht die letzten 8bit in das Register
> geschrieben
>
> Dann 8mal shift nach rechts.
>       H        L
> y= xxxxxxxx 00000000
>
>
> Jetzt ist das eigtl. Highbyte das Lowbyte also:
>
> OCR1AH = (y>>8);

Es geht nicht um die Aufteilung des 16-Bit Wertes in zwei 8-Bit Werte, 
es geht darum, in welcher Reihenfolge die beiden Register zu beschreiben 
sind. Ließ das im Datenblatt nach.

von Roland K. (roland_k)


Lesenswert?

spess53 schrieb:
> spess53

Ich lasse mich gerne belehren!

von holger (Gast)


Lesenswert?

>Es geht nicht um die Aufteilung des 16-Bit Wertes in zwei 8-Bit Werte,
>es geht darum, in welcher Reihenfolge die beiden Register zu beschreiben
>sind. Ließ das im Datenblatt nach.

OCR1A = y;

Das macht der Compiler schon richtig.

von Roland K. (roland_k)


Lesenswert?

@Stefan: Danke Dir! War wohl die Verlinkung, der ich nicht gefolgt bin.


Für alle die den gleichen Fehler machen. Hier der Text aus dem 
Datenblatt:
To do a 16-bit write, the high byte must be written before the low byte. 
For a 16-bit read, the low
byte must be read before the high byte.


@holger: Danke! Ja, sollte. Aber leider nicht bei MikroC :-/

von spess53 (Gast)


Lesenswert?

Hi

>Ich lasse mich gerne belehren!

Der interne RC-Oszillator läuft normalerweise mit 8 MHz. Mit dem 
OSCCAL-Register lässt er sich auf maximal 15MHz trimmen. Kannst ja 
selbst im Datenblatt nachsehen.

MfG Spess

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.