Hallo zussamen,
nachdem ich mir ein C-Buch zugelegt habe und das Forum bzw. Codesammlung
quasi auswendig gelernt habe stehe ich vor einem riesen Problem...
folgendes:
Ich baue gerade ein kleines Netzteil. Hardware funktioniert, Die meisten
Module des C-Programms auch.
Das Problem ist, ich wollte mit einem NE555 einen Takt generieren, der
ca alle 500ms das Display aktualisiert (TIMER sind leider keiner mehr
übrig.) Soll heißen alle Zahlenwerte löschen,
Werte neu berechnen und wieder auf dem LCD anzeigen.
Solange ich das Display mit einem Taster am INT0 Eingang (10kOhm
Pulldown)
auslöse Funktioniert es auch wenn ich aber den NE555 stecke, hängt sich
nach einer nicht definierbaren anzahl von INT0 Aufrufen irgendwas auf.
Das Display wird nicht mehr aktualisiert, wenige sekunden Später fängt
der µC von vorne im Programm an (schätze mal der Watchdog greift dort
ein)..
Hat vllt irgendwer eine zündende Idee?
Vielen Dank im Vorraus
Matthias
PS:hier erstmal einige Codeauschnitte ( Im Anhang ist die Komplette
Quelldatei die ist viel zu lang)
1
intmain(void)
2
3
{
4
GICR=(1<<INT0);//INT0 config
5
MCUCR=(1<<ISC01);//INT0 config
6
sei();//freigabe interrupts
7
8
9
while(1)
10
{
11
asm("NOP");//Mache nichts in der Haupschleife;
12
asm("NOP");//Verbrenn nur Zeit und warte auf Interrupts!
Matthias Lindner schrieb:> nachdem ich mir ein C-Buch zugelegt habe und das Forum bzw. Codesammlung> quasi auswendig gelernt habe
Dann hätte dir aber auch auffallen müssen
* keine Ausgaben in einer ISR
* keine extensiven Berechnungen in einer ISR, es sei denn es ist
unumgänglich
* man kann eine Timer-ISR durchaus für mehr als eine Sache hernehmen. Es
spricht nichts dagegen, dass zb ein für die Tastenentprellung
zuständiger Timer sich auch noch um so etwas wie eine Systemzeit
kümmert, bzw. regelmässig wiederkehrende Abläufe anstösst.
Dein Encoder-ISR wird zb regelmässig aufgerufen. Warum kann die nicht
auch noch ein Flag setzen und dann
1
volatileuint8_tupdateDisplay;
2
3
4
intmain()
5
{
6
....
7
8
while(1){
9
10
if(updateDisplay)
11
{
12
updateDisplay=0;
13
14
...deinCodefürdieADCAbfrageundAusgabe
15
}
16
}
17
}
18
19
ISR(TIMER0_OVF_vect)
20
{
21
....
22
23
updateDisplay=1;
24
}
Wenn dir das (wegen der fixen Zeit für die Encoder Auswertung) zu häufig
ist, dann eben
Das mit der zählenden variable ist auch eine Lösung. Werd ich mal
versuchen. Danke dafür
wegen dem Interrupt; Interrupts sollen kurzgehalten werden, damit das
Hauptprogramm nicht "verhungert" soweit mein Schulwissen. Da ich jedoch
ab und zu wirre Zeichen auf dem Display hatte, wenn ein Interrupt
während der Display aktualisierung eintrat. hab ich mir weiter nichts
dabei gedacht. Es ist ja auch keine Zeitkritische Sache dabei.
Jetzt habe ich es mit einer zählenden Flag gelöst und während der
Abarbeitung sind alle Interrupts gesperrt!!!
Karl Heinz Buchegger schrieb:>> (schätze mal der Watchdog greift dort ein)..>> Was heißt 'schätze mal'.> Du bist der Programmierer! Das musst du WISSEN, nicht schätzen.
Leider kann ich nicht in den Schwarzen Käfer hineingucken da ich kein
JTAG o.ä. habe. es war auch nicht der Watchdog sondern das Programm ist
beim Rücksprung aus dem Interrupt wieder zum Beginn der int main(void)
Methode
gehüpft. warum muss ich nochmal nachforschen. leider fällt ja simulieren
bei der LCD Library auch flach!
Matthias Lindner schrieb:> Da ich jedoch> ab und zu wirre Zeichen auf dem Display hatte, wenn ein Interrupt> während der Display aktualisierung eintrat.
Das sollt dir zu denken geben. Da fummelt ein Interrupt an Dingen, von
denen er die Finger lassen soll. Falls das aber unumgänglich ist, kann
man immer noch den kritischen Teil (meist nur ein, zwei Statements) in
der main() durch "atomic region" schützen.
Also,
jetzt läuft der Controller seit fast 15 Minuten ohne Fehler bzw.
"abstruz". Es war doch die sinnlose Idee mit dem NE555.
Danke für eure Hilfe!!!
Viele Grüße aus der Oberpfalz
Matthias