Forum: Mikrocontroller und Digitale Elektronik ATmega88 Timer mit Interrupt


von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Hi,

Ich nutze:
AVR Studio4
My AVR MKII Board
ATmega88PA@20MHz

Problem:
Ich bekomme den Timer nicht richtig zum laufen.
Wenn ich den TCNT1 Wert in der Interrupt Routine verändere,
verändert sich die Blinkfrequenz der LEDs nicht.

Ich hoffe jemand kann mir hierbei helfen und sagen was ich falsch 
gemacht habe.

Vielen Dank schonmal im Voraus!

Mit freundlichen Grüßen
Philipp D.

von Uwe (Gast)


Lesenswert?

Schalte mal das CTC Flag ein UND verändere mal das Register OCR1B 
anstelle von TCNT1 im Interupt Handler.

von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Hi,

danke für die Antwort aber das hat leider nicht geholfen. Die Leds 
leuchten mit gleicher Helligkeit. Auch wenn ich den Wert verändere.

von Ingo (Gast)


Lesenswert?

Das Compare Register ist OCR1A nicht B! Folglich auchnoch die ISR dazu 
ändern!

Ingo

von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Hi,

danke für die Antwort, nachdem ich CTC eingestellt habe und das Compare 
Register A nehme ändert sich schonmal was wenn ich meinen Wert ändere.

Jetzt blinken die LEDs sehr schnell mit scheinbar konstanter Frequenz 
und werden heller wenn ich den Wert hochzähle (ist das nicht PWM?).

Ich will aber eigentlich "nur" in der Lage sein eine gewisse Zeit zu 
bestimmen wie lange die LEDs an sind.

von Karl H. (kbuchegg)


Lesenswert?

Philipp D. schrieb:

> Jetzt blinken die LEDs sehr schnell mit scheinbar konstanter Frequenz

Die Frequenz müsste sich aber ändern.

> und werden heller wenn ich den Wert hochzähle (ist das nicht PWM?).

Das was du hast, hat mit PWM noch nicht viel zu tun.
Aber wenn man sehr schnell blinkt, geht das blinken schnell mal für das 
Auge in einen Helligkeitswert über.

> Ich will aber eigentlich "nur" in der Lage sein eine gewisse Zeit zu
> bestimmen wie lange die LEDs an sind.

Das müsste schon passen. Geh halt mal mit dem OCR1A Wert höher. Du 
kannst bis 65535 hochgehen. Wenn dir das nicht reicht dann kannst du 
noch nachsehen ob es noch einen größeren Vorteiler für den Timer gibt 
und wenn das auch noch nicht reicht, dann schaltest du eben deine LED 
nur bei jedem 2ten mal um.

von Uwe (Gast)


Lesenswert?

> TIMSK1 = (1<<OCIE1B)|(0<<OCIE1A)|(0<<TOIE1);//Select Interrupt Type for
> Timer 1

Laut diesert zeile solltest du dann aber auch noch das schreiben 
(0<<OCIE1B)|(1<<OCIE1A)

von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Hi,

habe jetzt nochmal den externen Clock um 8 dividiert und kann jetzt eher 
sehen was los ist.

Beispiel OCRA1=20;
LED ist viel Länger an als aus.

je weiter ich OCRA1 erhöhe, desto kürzer wird die An-Zeit der LED.

Irgendwas ist hier doch faul oder?:)

Vielen Dank für die Hilfe!

Mit freundlichen Grüßen

Philipp D.

von Michael (Gast)


Lesenswert?

Philipp D. schrieb:
> Irgendwas ist hier doch faul oder?:)

Was funktioniert denn nicht? Hast du das ganze mal Schritt für Schritt 
im Simulator ablaufen lassen und mit dem verglichen, was deiner Ansicht 
nach passieren soll?

von Philipp D. (peacefish)


Lesenswert?

Hi,

ich will dass die LED genausolange an wie aus ist, das ist das was ich 
auch dabei erwarten würde.
Das ist sie aber nicht und das verwirrt mich eben.

von Thomas E. (thomase)


Lesenswert?

Philipp D. schrieb:
> Das ist sie aber nicht und das verwirrt mich eben.
Warum auch?
Stell den CTC-Modus ein und dann klappt das auch.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Speck jetzt erst mal deine ISR ab
1
ISR(TIMER1_COMPA_vect)
2
{
3
  PORTB^=0xff;
4
}
das OCR Register veränderst du erst mal nur im main(). Dann ist schon 
mal was weg und du hast zumindest ein paar Konstante.

von Thomas E. (thomase)


Lesenswert?

Und speck' diesen Quatsch mal ab:
> TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|
>(0<<WGM10);//Set Mode for Timer 1

>TCCR1B =  (0<<FOC1A)|(0<<FOC1B)|(0<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);

Was soll das "(0<<Bla)"? Das macht gar nichts, also muß das auch gar 
nicht hingeschrieben werden. Und der Übersichtlichkeit dient das auch 
nicht. Sonst würde man auf einen Blick sehen, daß das "|(1<<WGM11)" 
nicht den CTC einstellt, sondern 9-Bit PWM. Und dann ändert sich die 
Frequenz nun mal nicht.

"TCCR1B |= (1 << WGM12);" ist dein Freund.

mfg.

von bitte löschen (Gast)


Angehängte Dateien:

Lesenswert?

Thomas Eckmann schrieb:
> Was soll das "(0<<Bla)".

So sieht man wenigstens, dass an WGM13 nicht gedacht wurde, auch wenn 
das in diesem Fall nicht von Belang ist. ;-)

Ich habe neulich die Register-Beschreibungen für Timer/Counter 0, 1 und 
2, die sich in den ATmega8 und ATmega88-Handbüchern jeweils über mehrere 
Seiten erstrecken, in einem Dokument zusammengefasst und dabei versucht, 
es optisch halbwegs übersichtlich zu gestalten und vor allen Dingen 
nicht mit Informationen zu überladen.
Es ist eher als schnelle Referenz gedacht, welcher Timer bei welchem 
ATmega8[8] was kann und wie die Register und Bits heißen.

Aufgrund des Umfangs kann ich Fehler nicht ausschließen und würde mich 
über entsprechende Meldungen freuen. Dass die Seitenzahlen-Verweise zu 
den Handbüchern unvollständig sind und die Missachtung englischer 
Kleinschreibung (wie in den meisten Handbüchern) inkonsistent ist, weiß 
ich schon.

Eine Entschuldigung mit Kniefall und demütigstes Umverzeihungbitten, 
falls es so etwas schon gibt. Ich war dann nur zu doof zum Suchen und 
bitte darum, nachsichtig zu sein.

Ich habe es einfach mal in diesen Thread gestellt, weil es zumindest mir 
hilft, genau solche Probleme zu lösen.

von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Thomas Eckmann schrieb:
> Warum auch?
> Stell den CTC-Modus ein und dann klappt das auch.
1
 TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|(0<<WGM10);//Set Mode for Timer 1

Das mach ich in dieser Zeile.
Oder mach ich da was falsch?

Wenn ich OCR1A außerhalb der Interrupt Routine definiere, habe ich aber 
dann immer noch das ursprüngliche Problem, dass die Zeit in der die LED 
an ist länger bzw. kürzer ist als die Zeit in der sie aus ist.

Erwarten würde ich:

Das TCNT1 Register wird hochgezählt
Bis es mit dem CompA Register übereinstimmt
dann wird der entsprechende Interrupt ausgelößt, der die LEDs umschaltet
dabei wird TCNT1 zurückgesetzt
und anschließend wieder hochgezählt
...

Daher sollte doch die Zeit in der die LEDs an sind genau gleich sein wie 
die Zeit in der die LEDs aus sind.
Aber irgendwas scheine ich da noch zu übersehen.

Vielen Dank für die Hilfe!

Mit freundlichen Grüßen

Philipp D.

von bitte löschen (Gast)


Lesenswert?

CTC ist Modus 4 oder 12, nicht 2.

von Philipp D. (peacefish)


Lesenswert?

Hi,

ich habe das Gefühl jetzt kommen wir der Sache näher,
meine Information habe ich aus

http://pdf1.alldatasheet.com/datasheet-pdf/view/83751/ATMEL/ATMEGA88.html
seite 97 entnommen:
Da steht das Mode 2 = CTC Mode ist.

von Philipp D. (peacefish)


Lesenswert?

"In Clear Timer on Compare or CTC mode (WGM02:0 = 2), the OCR0A Register 
is used
to manipulate the counter resolution. In CTC mode the counter is cleared 
to zero when
the counter value (TCNT0) matches the OCR0A. The OCR0A defines the top 
value for
the counter, hence also its resolution. This mode allows greater control 
of the compare
match output frequency. It also simplifies the operation of counting 
external events.
The timing diagram for the CTC mode is shown in Figure 32. The counter 
value
(TCNT0) increases until a compare match occurs between TCNT0 and OCR0A, 
and
then counter (TCNT0) is cleared." [ATmega88 datasheet]

bedeutet das nicht, dass WGM02 gesetzt werden muss um CTC Mode zu 
aktivieren?

von Thomas E. (thomase)


Lesenswert?

Philipp D. schrieb:
> Da steht das Mode 2 = CTC Mode ist.

Philipp D. schrieb:
> bedeutet das nicht, dass WGM02 gesetzt werden muss um CTC Mode zu
> aktivieren?
Nein. Zumindest nicht, wenn du weiterhin Timer1 verwendest. Das ist 
jetzt für Timer0.

Philipp D. schrieb:
> Aber irgendwas scheine ich da noch zu übersehen.
Eigentlich müsste das laufen.

mfg.

von Carsten G. (carry)


Lesenswert?

Hallo,

der Abschnitt gehört zu Timer0. Der Code aber zu Timer1 (mit mehr Modi). 
Im entsprechenden Abschnitt zu Timer1 steht dann auch: "[...] CTC mode 
(WGM13:0 = 4 or 12) [...]"


Carsten

von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Hi,

ja ich verwende weiterhin Timer1.
Ich lade aber nochmal sicherheitshalber den Code hoch den ich momentan 
verwende. Ich frage mich echt an was das liegen kann.

Mir scheint es so als ob das Ding auf PWM eingestellt ist.
Aber die Einstellungen habe ich jetzt ja schon mehrfach nachgesehen.
Ich bin eben auch der Meinung, dass die so korrekt sind.

Auf dem ATmega8 war das alles noch so einfach...

Mit freundlichen Grüßen
Philipp D.

von Thomas E. (thomase)


Lesenswert?

Philipp D. schrieb:
> Auf dem ATmega8 war das alles noch so einfach...
Quatsch.

Thomas Eckmann schrieb:
> Eigentlich müsste das laufen.
Auch Quatsch. Jetzt bin ich schon völlig durcheinander.

>TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|(0<<WGM10);// 
Set  Mode for Timer 1
Das ist NICHT der Ctc-Mode!

mfg.

von Philipp D. (peacefish)


Angehängte Dateien:

Lesenswert?

Hi,

super jetzt habe ichs auch begriffen.
Ich dachte die Register für Timer0 entsprechen derer für Timer1 nur mit 
anderen Zahlen.

Weit gefehlt!

Habe Timer0 anstatt Timer1 verwendet und siehe da auf einmal gehts!
[wenn man nur immer einfach das machen würde was im Datenblatt steht ... 
(schähm)]

Vielen Dank für die tolle Hilfe!

Mit freundlichen Grüßen

Philipp D.

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.