Hallo,
ich möchte für mein Programm auf einem Atmega168 mit 16 MHz Quarz ein
vorgeschriebene Programmlaufzeit einrichten.
Dafür verwende ich einen 8-Bit Timer wie im Code s.u. zu sehen. Das
Programm läuft in der Simulation genau so wie es sein soll, ein
Programmdurchlauf dauert genau 0,1ms bzw. 1ms (je nach Divisor).
16.000.000/8 = 2.000.000 --> zähler bis 200 ergibt 0,1ms pro Durchlauf
bzw.
16.000.000/64 = 250.000 --> zähler bis 250 ergibt 1ms pro Durchlauf
Unglücklicherwiese ist die Programmlaufzeit auf dem Controller DEUTLICH
größer! Woran kann das liegen?!? Hab ich bei dem Prescaler etwas falsch
verstanden?!
Hier mein Code:
main.c:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<general.h>
4
5
intmain(void)
6
{
7
sei();//Globale Interrupts aktivieren
8
initPorts();//Funktionen der Ports definieren
9
initTimer8(0);//Timer starten
10
11
inta=0;
12
13
while(1)
14
{
15
16
if(a==1000)//nach 100ms
17
{
18
PORTB=0x04;//Leuchtdiode ein
19
}
20
21
if(a==2000)//nach 100ms
22
{
23
PORTB=0x00;//Leuchtdiode aus
24
a=0;
25
}
26
27
a++;
28
29
while(isTimerRunning(0)==0){}
30
}
31
return0;
32
}
und hier der Timer:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<general.h>
4
5
volatileBYTEgbTimerIrqFlag0=0;//Globale Variable für Interrupt-Flag
6
volatileBYTEgbTimerIrqFlag2=0;//Globale Variable für Interrupt-Flag
7
8
9
voidinitTimer8(BYTEbNr)//Timer initialisieren, Übergabe Nummer des Timers bNr
10
11
{
12
switch(bNr)//Ansprechen des gewählten Timers
13
14
{
15
case0://Timer 0,1ms
16
17
TCCR0A=0x02;//Output-Compare-Pin aus, kein PWM, Timer-Typ: CTC
18
TCCR0B=0x02;//Timer auf Taktrate 2 MHz setzen (Teiler auf 8)
19
TCNT0=0x00;//Zähler Register auf 0 setzen
20
OCR0A=200-1;//Vergeich des Timers mit vorgegebenen Wert: Laufzeit 0,1ms
21
OCR0B=0x00;//Compare-Register B wird nciht verwendet
22
TIMSK0=0x02;//OCR0A-Interrupt ein, Overflow- und OCR0B-Interrupt aus
23
24
break;
25
26
case2://Timer 1ms
27
28
29
TCCR2A=0x02;//Output-Compare-Pin aus, kein PWM, Timer-Typ: CTC
30
TCCR2B=0x03;//Timer auf Taktrate 250 kHz setzen (Teiler auf 64)
31
TCNT2=0x00;//Zähler Register auf 0 setzen
32
OCR2A=250-1;//Vergeich des Timers mit vorgegebenen Wert: Laufzeit 1ms
33
OCR2B=0x00;//Compare-Register B wird nciht verwendet
34
TIMSK2=0x02;//OCR2A-Interrupt ein, Overflow- und OCR2B-Interrupt aus
35
36
break;
37
}
38
39
}
40
41
42
43
BYTEisTimerRunning(BYTEbNr)//Funktion zum Feststellen, ob vorgegebene Zeit abgelaufen
44
{
45
BYTEbReturn=0;
46
47
switch(bNr)//Ansprechen des gewählten Timers
48
{
49
50
case0:
51
bReturn=gbTimerIrqFlag0;//Solange die OCR-Flag nicht gesetzt ist bleibt die Rückgabe 0, anderenfalls wird sie 1
52
gbTimerIrqFlag0=0;//OCR-Flag zurücksetzen
53
54
break;
55
56
case2:
57
bReturn=gbTimerIrqFlag2;//Solange die OCR-Flag nicht gesetzt ist bleibt die Rückgabe 0, anderenfalls wird sie 1
Carsten schrieb:> Unglücklicherwiese ist die Programmlaufzeit auf dem Controller DEUTLICH> größer!
Kannst du "DEUTLICH größer" in Zahlen ausdrücken?
> Woran kann das liegen?!?
Dein Controller läuft nicht mit den von dir angenommenen 16MHz.
Gruß,
Magnetus
Grob gestoppt sind es ca. 1,7 statt der erwarteten 0,1 sekunden!!
Mit welcher geschwindigkeit läuft denn der Controller... bei dem
verhältnis würde ich vermuten dass der nur auf 1 MHz läuft, aber warum
?!
Die Standard-Taktquelle ist ein interner RC-Oszillator.
So lange du den Chip nicht so umkonfigurierst, dass er mit einer
externen Taktquelle zusammenarbeitet, läuft der Chip mit den internen
1MHz (Stichwort: Fuse-Bits, aber GRÜNDLICH lesen!)
Carsten schrieb:> Grob gestoppt sind es ca. 1,7 statt der erwarteten 0,1 sekunden!!
Das wäre dann Faktor 17.
> Mit welcher geschwindigkeit läuft denn der Controller... bei dem> verhältnis würde ich vermuten dass der nur auf 1 MHz läuft,
Richtig
> aber warum?!
Siehe Beitrag von ElektoMaus.
Gruß,
Magnetus
17 wäre es bei einer genauen Messung, aber 16 wird ja vermutlich eher
passen, da die controller vermutlich nicht auf 941.176 Hz laufen.
Mit den Fuse Bits ist das beim AVR-Studio ja recht komfortabel
gestaltet, dort kann man ja einfach den externen Quarz wählen... nun ist
aber die Frage, welchen ich denn nehme, für einen 16MHz Quarz, es gibt
dor ja viele zur auswahl!
Klar ist natürlich einer mit 8-...MHz, alle anderen sind langsamer, aber
was hat es mit dem "Reset" auf sich... leider kann man die unteren
auswahlmöglichkeiten im AVR-Studio nicht mehr ganz lesen!
Wenn mir das eben jemand sagen könnte, wäre super!
Ja, ich weiß, ich kann jetzt auch 3 Stunden danach googlen und finde es
evtl. dann auch...
hmm, mit dem
"Ext. Crystal Osc.; Frequency 8.0- MHz; Start-up time PWRDWN/RESET:
16K CK/14CK + 65 ms; [CKSEL=1111 SUT=11]"
funktioniert es jedenfalls, allerdings komme ich jetzt auf 0,7s statt
0,1s... was passt denn da nicht ?!?!
Aha, alles klar, wird geteilt durch 8... soll natürlch nicht!!
jetzt funktionierts... naja, besser... nun zeigt er nach 1minute nur 46
sekunden an!
Aber trotzdem schonla danke!!
Noch ne idee, wo diese restabweichung herkommen könnte?!