Hallo,
Ich möchte den Timer 1 (16Bit) eines Attiny 2313 benutzen um ca eine
Minute zu messen.
Danach möchte ich die Ausgänge abschalten...
Nun bekomme ich oft den Fehler:
left-hand operand of comma expression has no effect
Dabei muss ich doch den Timer richtig einstellen.
Hier mein Programm:
1
#include<avr/io.h>
2
#define F_CPU 1000000UL // 1 MHz (fuer delay.h)
3
#include<util/delay.h>
4
5
6
intmain(void)
7
{
8
PORTD=0x00;//Pin für Taster und ADC(Reset) als Eingang
Matze schrieb:> Nun bekomme ich oft den Fehler:> left-hand operand of comma expression has no effect>> Dabei muss ich doch den Timer richtig einstellen.
Schon.
Aber nicht so
Nun inst er hoffentlich auf Compare eingestellt.
Nach allem was ich gelesen habe müsste er bei einem Compare-Match das
Bit OCF1A setzen, und einen Interrupt auslösen.
Der Interrupt soll durch
1
TIMSK|=(1<<OCIE1A);//Compare Interrupt Enable
2
sei();//Globale Interrupts ein
ermöglicht werden.
Leider löst er nicht aus und ich kann die Minute so nicht messen.
Grüße
Matze
Habe den Fehler gefunden.
Ich nutze Timer 1 und stelle das Kontroll-Register von Timer 0 ein.
TCCR1A &= (0<<COM1A0)|(0<<COM1A1); // CTC Modus
TCCR1B &= (0<<ICNC1)|(0<<ICES1)|(0<<CS11); // Prescaler 1024
TCCR1B |= (1<<WGM12)|(1<<CS10)|(1<<CS12);
Grüße
Matze
Matze schrieb:> TCCR1A &= (0<<COM1A0)|(0<<COM1A1); // CTC Modus> TCCR1B &= (0<<ICNC1)|(0<<ICES1)|(0<<CS11); // Prescaler 1024
das ist zwar kein fehler, aber unsinn. da kannst du auch gleich
TCCR1A = 0;
TCCR1B = 0;
schreiben.
Peter II schrieb:> as ist zwar kein fehler, aber unsinn. da kannst du auch gleich>> TCCR1A = 0;> TCCR1B = 0;
Dann kannst du die auch gleich komplett weglassen, da nach einem Reset
diese
IO register eh auf Null sind. (jedenfalls beim dem tiny 2313)
Es ist ziemlich unwahrscheinlich, dass dein Programm ausgerechnet hier
1
while(1)
2
{
3
lauft=TIFR&(1<<OCF1A);
4
if(lauft)
5
{
6
PORTD=0x00;
7
while(1)
8
{
9
;
10
}
11
TIFR|=(1<<OCF1A);
12
}
13
else
14
{
15
PORTD=0x55;
16
}
17
}
das OCF1A Flag als gesetzt antreffen wird. Sobald es vom Timer gesetzt
wird, erfolgt der Aufruf der ISR innerhalb der nächsten 2 bis 3
Taktzyklen, je nachdem welchen Befehl die CPU gerade in Arbeit hat. Dann
passieren 2 Dinge: zum einen wird dadurch genau dieses Flag sofort
wieder gelöscht, so dass die Hauptschleife es nicht zu Gesicht kriegen
kann und zum zweiten hältst du das Programm durch die Endlosschleife
innerhalb der ISR fest, so dass die Hauptschleife schon alleine aus
diesem Grund nicht weiter arbeiten kann.
Und ich seh gerade, dass du da schon wieder eine Endlosschleife
reingeschachtelt hast. Mit Endlosschleifen scheinst du es ganz im
Speziellen zu haben. Lass den Unsinn! Es gibt nur EINE Endlosschleife
und das ist die eine in main()!
Wie kommst du eigentlichg auf die Idee, dass dein Programm im 1
Sekundenrhythmus die ISR aufruft? Wenn ich nachrechne, krieg ich da aber
was ganz anderes raus. Mal abgesehen davon, dass deine 1Mhz vom internen
Takt keine 1Mhz sein werden und die ganze Rechnerei schon alleine
deswegen nicht stimmt. Oder hast du einen 1Mhz QUarz am Tiny hängen?
FAQ: Timer
Und ehe du da jetzt noch weiter rumhampelst:
Mal ausgehend davon, dass du den OCR1A Wert soweit korrigierst, dass du
leidlich genau 1 Sekunden Abstände im ISR Aufruf hast, kann man Zeiten
zb so abmessen, indem man einen Countdown-Zähler rückwärts zählen lässt,
bis er bei 0 ist
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#define F_CPU 1000000UL // 1 MHz (fuer delay.h)
4
#include<util/delay.h>
5
6
7
volatileuint8_ttick;
8
9
intmain(void)
10
{
11
PORTD=0x00;//Pin für Taster und ADC(Reset) als Eingang