Hey Leute
Ich hab für nen Feuerwehrwettkampf ne Stoppuhr gebaut. Das Teil
funktioniert auch wunderbar. Da ich noch genug Platz aufm Prozessor hab,
hab ich gedacht, kann man ja auch die Echtzeit anzeigen lassen solange
der Wettkampf nicht losgeht. Also hab ich in die Main eine Unterfunktion
gepackt die die ganze Zeit durchlaufen wird wenn die Funktion "Echtzeit"
ausgewählt wurde. Zu Beginn kann man die Uhrzeit Ziffernweise
einstellen. Dazu blinkt die ausgewählte Ziffer. So nun zum eigentlichen
Problem.
Wenn ich die Ziffern blinken sollen, dann gibt es in der Main eine
Routine die die nächste anzuzeigende Zahl berechnet und das
Timer-Interrupt zeigt dann die Zahl an.
Bei der Berechnung dieser Zahl überspringt der AVR aber immer die
Zuweisung der Variable (z_sekunde,zehntel,hundertstel)
Das komische ist, das es bei der Variable (sekunde) alles wunderbar
funktioniert.
Ich hab die komplette Main angehangen und füge hier mal einen der 4
wichtigen Abschnitte ein.
Ich hoffe irgendjemand hat eine Idee was das Problem sein könnte.
1
while(((zahl&0x07)==0)&&(funktion==ECHTZEIT))//einstellen der 10 sekunde
2
{
3
if((k<2)&&(inkrement==1))//uhrzeit kann nicht größer als 24 uhr sein
4
{
5
k+=inkrement;
6
inkrement=0;
7
}
8
9
elseif((k>0)&&(inkrement==-1))
10
{
11
k+=inkrement;
12
inkrement=0;
13
}
14
15
if((NEW_TIME)!=0)//soll neuer wert berechnet werden ?
16
{
17
ziffern|=(1<<3);//Z_SEKUNDE aktualisieren
18
19
if((zahl&(1<<7))!=0)//flag gesetzt ?
20
{
21
z_sekunde=ANZEIGE_LEER;//diese anweisung wird übersprungen
ich bin mir hier nicht sicher ob
volatile uint8_t ziffern=0,zahl=0,rfm_test2=0;
das gleiche ist wie
volatile uint8_t ziffern=0;
volatile uint8_t zahl=0;
volatile uint8_t rfm_test2=0;
es kann durchaus sein das zahl und test2 nicht volatile sind.
Hallo Peter
Also da bin ich mir eigentlich sicher das das mit dem volatile so
stimmt, da ziffern und rfm_test2 im interrupt korrekt geändert werden
und sonst die anzeige der zahlen nicht funktionieren würde, weil die
variable ziffern speichert die bits welche zahlen aktualisiert werden
sollen
Hmm... Hab ich jetz nen Denkfehler ?
Volatile werden doch Variaben deklariert die in einer ISR verändert
werden oder nicht ?
Meine Variablen werden doch hingegen nur in einer ISR benutzt und nicht
verändert. Die Änderung der Werte passiert ja in der Main.
Der code ist leider recht unübersichtlich. Funktionen haben keine klaren
namen und aufgaben.
Du hast viel zu viel code in der ISR, durch funktionaufrufe in der ISR
wird sie selber recht langsam (weil alle Register gesichert werden
müssen) und durch das sleep in ziffer sogar eine warteschleife. Das
ganze sollte man auf jeden fall nicht machen.
Thomas G. schrieb:> Das is ja echt nen Ding. Habs grad geändert und es funktioniert.> Hab ich das mit dem volatile falsch verstanden ?
was hast du geändert? und wie hast du es verstanden?
Ich hab vor die Variablen nen volatile gesetzt und jetz funktioniert es.
Ich hatte volatile immer so verstanden das man damit nur Variablen
deklariert die auch von ISR verändert werden können.
Welche Funktion hat keine richtige Aufgabe ?
die Funktion ziffer muss nen Delay haben sonst erkennt der BCD-Baustein
der hinten dran hängt die Flanke nicht und um Sekundengenau zu sein
berechne ich die neue Zeit in der Main und aktualisiere die Zahlen in
der ISR... ist meine herangehnsweise so falsch ? wie hättest du das denn
gelöst ?
Thomas G. schrieb:> Ich hab vor die Variablen nen volatile gesetzt und jetz funktioniert es.> Ich hatte volatile immer so verstanden das man damit nur Variablen> deklariert die auch von ISR verändert werden können.
fast, alle Variabeln die in der ISR geändert und im Hauptprogramm
gelesen werden. Variabeln die in der ISR geändert werden und sonst nicht
gebraucht werden brauchen kein volatile. Volatile macht auch zugriffe
langsamer, aus dem grund sollte man sparsam damit umgehen.
> Welche Funktion hat keine richtige Aufgabe ?
ziffer
keine weiss damit etwas anzufangen, etweder sotwas wie SetZiffer oder
SendZiffer oder was auch immer das ding macht.
> die Funktion ziffer muss nen Delay haben sonst erkennt der BCD-Baustein> der hinten dran hängt die Flanke nicht und um Sekundengenau zu sein> berechne ich die neue Zeit in der Main und aktualisiere die Zahlen in> der ISR... ist meine herangehnsweise so falsch ? wie hättest du das denn> gelöst ?
das die Zeitberechung in der ISR ist, ist schon richtig. Aber das
übertagen der Ziffer kann man ja in der Main machen.
Thomas G. schrieb:> Volatile werden doch Variaben deklariert die in einer ISR verändert> werden oder nicht ?>> Meine Variablen werden doch hingegen nur in einer ISR benutzt und nicht> verändert. Die Änderung der Werte passiert ja in der Main.
Es spielt keine Rolle wer was verändert. Im Bsp aus Deinem ersten Post
kann der Compiler locker die Zuweisungen zu z_sekunde aus der Schleife
rausoptimieren und dahinter setzen. Woher soll der schließlich auch
wissen, das die (Zwischen-)Werte in irgendwelchen ISRs auch noch benutzt
werden?
... gar nicht gesehen, im Anhang steht direkt hinter der while Schleife
sowiso ein "z_sekunde=k;". Dann sind die Zuweisungen innerhalb der
Schleife für den Compiler einfach mal nur noch sinnlos und er schmeißt
sie komplett weg.
Das mit dem volatile versteh ich nicht meine Variablen veränder ich nur
in der Main und nicht in einer ISR wieso müssen die dann volatile sein ?
Ich hab mir gedacht wenn die in der ISR ein Flag setzte das ich in der
Main auswerte dann dauert das doch bestimmt länger bis es ausgeführt
wird als die Zeit in der Main zu berechnen und wenn der Zeitpunkt
gekommen ist einfach die ziffern zu aktualisieren.
Falscher Ansatz ?
Danke ...
jetz hab ichs verstanden :D
schwere Geburt... Danke
also sagt volatile dem Compiler noch das er die Variable ne optimieren
soll ?
Thomas G. schrieb:> Das mit dem volatile versteh ich nicht meine Variablen veränder ich nur> in der Main und nicht in einer ISR wieso müssen die dann volatile sein ?
Aber Du liest Sie in der ISR!
> also sagt volatile dem Compiler noch das er die Variable ne optimieren> soll ?
Kann man so sagen ja, ist aber eigentlich nur ein Nebeneffekt.
'volatile' sagt dem Compiler, das er alle Operationen auf eine derartige
Variable genau so ausführen muß, wie sie im Source stehen. Er muß immer
damit rechnen, das der Wert außerhalb seines Zuständigkeitsbereiches
geändert wurde bzw. das Schreiboperationen unbekannte Nebeneffekte
haben.
Thomas G. schrieb:> Das mit dem volatile versteh ich nicht meine Variablen veränder ich nur> in der Main und nicht in einer ISR wieso müssen die dann volatile sein ?
Wo du sie veränderst, ist völlig WURSCHT! Du benutzt sie in der ISR und
in der Main, also brauchst du volatile.
> Ich hab mir gedacht wenn die in der ISR ein Flag setzte das ich in der> Main auswerte dann dauert das doch bestimmt länger bis es ausgeführt> wird als die Zeit in der Main zu berechnen und wenn der Zeitpunkt> gekommen ist einfach die ziffern zu aktualisieren.
Eine Warteschleife in der ISR blockiert aber den kompletten Prozessor.
Für das beste Zeitverhalten sind ISRs, die möglichst schnell wieder
zurückkehren, immer von Vorteil.
> also sagt volatile dem Compiler noch das er die Variable ne optimieren> soll ?
volatile sagt dem Compiler, daß die Variable evtl. außerhalb des
normalen Programmablaufs gelesen oder geschrieben werden könnte und
deshalb alle Zugriffe auf diese auch tatsächlich auch dort, wo sie im
Code stehen, ausgeführt werden müssen.
Ihr habt ja recht ich hab grad nochmal gelesen, der Chip brauch ne
Pulsweite von 250ns da könnte ich das delay doch weglassen, die
verzögerung macht die abarbeitung des befehls
ok... Problem gelöst
Danke Leute