Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt Probleme -> LED blinkt nicht
Olle_Filzlaus
01.12.2005, 08:57
Hallo,
ich habejetzt mal versucht eine LED mittels interrupt blinken zu lassen.
auf die art und weiße will ich später damit mal eine uhr bauen. deswegen der interrupt, sonst könnte ich ja auch wait 1 nehmen.
nur leider blinken die an portd angeschloßenen led nicht. entweder die blinken zu schnell so das ich es nicht sehen kann, oder der interrupt funktioniert nicht (was ich eher denke).
findet ihr ein fehler?
hier mein programm:
'******************************
'* Atmega8 mit 8MHz *
'* Interupt-testprogramm *
'******************************
$regfile "m8def.dat"
$crystal = 8000000
Config Portd = Output
Dim A As Byte , N As Byte
N = 0
A = 0
On Timer1 Ontimer1 'Interrupt-Routine für Timer1-Overflow
Config Timer1 = Timer , Prescale = 256 'Takt: Quarz/256
Enable Timer1 'Timer1-Overflow-Interrupt einschalten
Enable Interrupts 'Interrupts global zulassen
'---------------------------------------------------------
Do 'Hauptschleife
Loop
'---------------------------------------------------------
Ontimer1: 'Interrupt-Routine
N = N + 1
If N = 255 Then
A = A + 1
If A = 255 Then
Toggle Portd.0
A = 0
End If
End If
Return
wie kann man die frequenz berechnen.
weil 8MHz/256 = 31,25KHz / 256 = 122Hz /256 = 0,5Hz.
also müsste meine led aller 2 sekunden an und aus gehen. macht sie aber nicht.
danke für die hilfe
arno
Hinter :
If N = 255 Then
A = A + 1
Fehlt noch das "N=0" sonst läuft N gegen unendlich....
hardstyleroxx
01.12.2005, 12:04
Versuche mal das Programm, das sollte so funktionieren! Die Werte sind mit rnAVR berechnet, was du auch hier irgentwo im Forum findest.
$regfile "m8def.dat"
$crystal = 8000000
Config Portd = Output
led alias portd.0
Config Timer1 = Timer, Prescale = 256
Const Timervorgabe = 3036
on timer1 ontimer1
enable timer1
enable interrupts
do
loop
ontimer1:
Timer1 = Timervorgabe
Toggle Led
Return
Rage_Empire
01.12.2005, 12:07
n läuft nicht in unendlich, da es als byte deffiniert wurde und somit bis 255 läuft und danach wieder bei 0 beginnt.
Dann kann man dann auch "A=0" in der Schleife weglassen.
Rage_Empire
01.12.2005, 12:53
theoretisch ja, ist aber schlampig so zu programmieren ;-)
Ja eben,mein Reden.
Entweder alle oder keinen.
Egal:
Was mir gerade mal so ein- und auffällt:
Der Timer läuft ja fröhlich weiter wärend er in der Int.Schleife steckt.
So übern Daumen kommt der vermutlich nicht mal bis zum Toggle weil er auf den nächsten Timer-Int läuft.
Also am Anfang der Int-Routine Timer abschalten und am Ende wieder einschalten (Disable Timer1/Enable Timer1)
Werner_Just
01.12.2005, 13:14
Hallo,
> wie kann man die frequenz berechnen.
> weil 8MHz/256 = 31,25KHz / 256 = 122Hz /256 = 0,5Hz.
> also müsste meine led aller 2 sekunden an und aus gehen. macht sie
> aber nicht.
Verständlich!
Der Timer1-OVF wird nach 2^16 * 256 Prozessortakten ausgeführt.
Der Timer1-OVF muss 255 * 256 mal ausgefürt werden bis der Portpin getoggelt wird.
Mach bei 8MHz Prozessortakt alle 136.902,08 Sekunden einen Zustandswechsel, bzw eine Blinkfrequenz von 0,00000365 Hz
(3.65 * 10^-6 Hz)!
Gruß Werner
P.S.
> Also am Anfang der Int-Routine Timer abschalten und am Ende wieder
> einschalten (Disable Timer1/Enable Timer1)
2^24 Takte wird die Interrupt Routine nicht benötigen ;)
Yep,da bin ich auch gerade drauf gestoßen.
Der Simulator is ja langsam aber sooo langsam nu auch wieder nicht :D
Olle_Filzlaus
01.12.2005, 16:56
Hallo,
danke an eure Hilfe, leider habe ich mein Programm nicht zu laufen bekommen. Aber das programm von hardstyleroxx läuft super.
nur mal noch paar fragen. was ist das:
Const Timervorgabe = 3036
ich denke mal damit wird doch der timer irgendwie eingestellt. aber wie genau.
ich würde das gerne auch mal selber mal berechnen.
weil die nächste mir selber gestellte aufgabe ist eine Uhr.
und da brauche ich ja einen schönen 1 sekundentakt.
thx for help
Arno
hardstyleroxx
01.12.2005, 18:34
Die Konstante wurde wie gesagt von dem Programm rnAVR berechnet, was du hier im Forum auch als Download findest.
Die Konstante ist glaube ich da zu da, damit man die Auflösung feiner einstellen kann.
Torsten_G
01.12.2005, 21:29
Nun, wenn ich das richtig sehe, wird der Timer nach seinem Interrupt mit diesem Wert geladen, somit vergeht weniger Zeit bis zu seinem nächsten Interrupt.
"Const" deklariert die Variable "Timervorgabe" als Konstante, damit ist sie sozusagen schreibgeschützt und man kann nicht einfach im Programm einen neuen Wert drüberbügeln.
Allerdings dürfte der erste Zyklus nach dem Anlauf nicht stimmen, weil der Timer bei 0 startet, sonst ist der erste Timerdurchlauf zu lang.
Etwa so müsste es aber von Anfang an richtig gehen:
$regfile "m8def.dat"
$crystal = 8000000
Config Portd = Output
led alias portd.0
Config Timer1 = Timer, Prescale = 256
Const Timervorgabe = 3036
on timer1 ontimer1
enable timer1
enable interrupts
Timer1=Timervorgabe
do
loop
ontimer1:
Timer1 = Timervorgabe
Toggle Led
Return
Ich hab mal einfach hardstyler´s Programm geklaut... O:)
Viele Grüße
Torsten
Olle_Filzlaus
02.12.2005, 00:08
Hallo,
habe jetzt mal das programm rnavr probiert. ein feines tool. meine uhr läuft schon.
lasse die jetzt mal laufen um rauszubekommen wie genau die läuft. werde ich dann morgen früh mitbekommen.
cu arno
Olle_Filzlaus
05.12.2005, 23:29
habe die uhr jetzt ne weile laufen lassen und rausbekommen das die ca nach 7 stunden ( da ist die nacht vorbei *grins*) 20sekunden falsch geht.
das ist ne ganz schön große Abweichung. woran kann das liegen?
ich würde ja mal vermuten, das der interrupt zwar korekt funktioniert aber ebend ne mini sekunde ungenau geht und dadurch bei hoch rechnen und zählen sich fehler einschleichen. weil die ganzen werte habe ich mit dem tool rnavr berechnet. danke also mal das es stimmt :-)
mir würde am ende adann nur einfallen das ich die stunden anders hochrechne und dort ebend so 2-3 sekunden unter den tisch fallen lasse damit die zeit wieder stimmt, nur wäre das für mich keine richtige lösung.
achja, das programm soll einfach eine zeit zählen, es läuft bis 9999h und so. deswegen sind halt bei 7h 20 sekunden fehler schon ne menge.
hier mein Programm:
'********************************
'* Atmega8 mit 8MHz *
'* Uhrenbeispiel *
'********************************
$regfile "m8def.dat"
$crystal = 8000000
Config Lcdpin = Pin , Db4 = Portd.3 , Db5 = Portd.4 , Db6 = Portd.5 , Db7 = Portd.6 , E = Portd.2 , Rs = Portd.0
Config Lcdbus = 4
Config Lcd = 16 * 2
Dim S As Byte , M As Byte , H As Byte , G As Byte 'Zeit definieren
S = 0
M = 0
H = 0
G = 0
Config Timer1 = Timer , Prescale = 256
Const Timervorgabe = 34286
On Timer1 Ontimer1
Enable Timer1
Enable Interrupts
Cls
Do
Waitms 200
Locate 1 , 1
Lcd "UHR-Zeit"
Locate 2 , 2
Lcd ; G ;
Locate 2 , 4
Lcd ; H ;
Locate 2 , 7
Lcd ; M ;
Locate 2 , 10
Lcd ; S ;
Loop
'************************************************* ******************************
Ontimer1:
Timer1 = Timervorgabe
S = S + 1
If S = 60 Then 'Sekunde
S = 0
M = M + 1
If M = 60 Then 'Minute
M = 0
H = H + 1
If H = 100 Then 'Zehner Stunde
G = G + 1
If G = 99 Then 'hunderter stunden
End If
End If
End If
End If
Return
'************************************************* ******************************
thx für eure hilfe
Torsten_G
05.12.2005, 23:53
Der interne Quarz des Mega 8 ist nicht so genau wie ein Externer.
Schau doch mal ins Datenblatt, da steht die Abweichung drin.
Viele Grüße
Torsten
habe die uhr jetzt ne weile laufen lassen und rausbekommen das die ca nach 7 stunden ( da ist die nacht vorbei *grins*) 20sekunden falsch geht.
das ist ne ganz schön große Abweichung. woran kann das liegen?
Erstmal keine Panik.
Grundsätzlich gehts ja richtig.
Nun kommt die Feinabstimmung.
Thorsten hats ja schon gesagt das der Interne Schwinger nicht gerade ein Muster an Genauigkeit ist was übrigens auch im Datenblatt behandelt wird.
Wenn du deine Schaltung bei unterschiedlichen Temperaturen betreibst (Mal ne Nacht auffer Heizung bzw. im Gemüsefach vom Kühlschrank) wirst du feststellen das der interne Schwinger auch recht Temperaturabhängig ist.
Für eine Anwendung die auf ein genaues Timing setzt ist ein genauerer Takt unbedingt nötig.
Also ein Quarz ist da minimum.
der wird dir schon bessere und Temperaturstabilere Werte liefern.
Was dann noch an Ungenauigkeit übrigbleibt kannst du dann ausgleichen indem du ihn "ziehst".
dh. mit einem kleinen Drehkondensator (Oder ausgemesenem Festkondensator) wird die Schwingfrequenz etwas angepasst.
Dabei gilt natürlich auch hier die Regel des Aufwandes.
Je genauer du es brauchst desto mehr must du anstellen.
Die Steigerung für einen quarz ist ein Qarzofen (Ein Kästchen in dem die Temperatur konstant gehalten wird) oder ein speziell Kompensierter Schwinger.
Natürlich schlägt das im Preis nieder also sollte man sich genau überlegen was man braucht.
Ich würde erstmal ,zwecks Erfahrungswerte,mit nem quarz und nem Trimmerkondensator anfangen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.