Forum: Mikrocontroller und Digitale Elektronik watchdog atmega328


von grundschüler (Gast)


Lesenswert?

hallo

habe Probleme mit dem wd:
1
#include <avr/wdt.h>
2
...
3
4
wdt_enable(WDTO_8S); 
5
//============== Hauptschleife =================
6
while(1){
7
//================================================
8
....
9
10
//++++++++++++ volleSecunde ++++++++++++++++++++++
11
if(timer_smh>100){//1sec
12
wdt_reset();
13
led1_tog;
14
15
sec=sec+timer_smh/100;
16
timer_smh=timer_smh%100;
17
if(sec>59){sec=sec-60;  min++;
18
if(min==60){min=0; hou++;
19
if(hou==24){hou=0;}}}
20
}//-1sec
21
22
...

Der WD wird alle 8sec ausgelöst, funktioniert also grundsätzlich.

Jetzt soll der WD aber nur dann auslösen, wenn sich das Hauptprogramm 
wegen eines Fehlers aufgehängt hat. Deswegen soll der WD-counter bei 
jedem Sekundendurchlauf im Hauptprogramm zurückgesetzt werden.

Mit >wdt_reset();< funktioniert das nicht. Was mache ich falsch?

von Ulrich F. (Gast)


Lesenswert?

Nach:
>timer_smh=timer_smh%100;

Kann dieses niemals wahr werden:
> timer_smh>100

von grundschüler (Gast)


Lesenswert?

deswegen kommt die Abfrage auf  timer_smh>100 vor und nicht nach.

Der timer
1
//===========================================================
2
void timer_proc_10ms(void){
3
timer_smh++;
4
timer_10ms++;
5
#if USE_MMC
6
if(Timer1)Timer1--;//100Hz f�r sd-karte
7
#endif
8
}
9
//===========================================================
funktioniert.



Ich habe jetzt
wdg_reset();
durch
wdt_enable(WDTO_8S);
ersetzt.

Damit geht das ganze. Der aufruf der vollen Funktion
1
#define wdt_enable(value)   \
2
__asm__ __volatile__ (  \
3
    "in __tmp_reg__,__SREG__" "\n\t"    \
4
    "cli" "\n\t"    \
5
    "wdr" "\n\t"    \
6
    "sts %0,%1" "\n\t"  \
7
    "out __SREG__,__tmp_reg__" "\n\t"   \
8
    "sts %0,%2" "\n\t" \
9
    : /* no outputs */  \
10
    : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
11
    "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
12
    "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
13
        _BV(WDE) | (value & 0x07)) ) \
14
    : "r0"  \
15
)
kann ja nicht die Lösung des Problems sein?

von Ulrich F. (Gast)


Lesenswert?

In Scheibchen sie sich offenbart, die Realität....

> void timer_proc_10ms(void)
Wo kommt denn die plötzlich her?

Von wo wird sie aufgerufen?

von grundschüler (Gast)


Lesenswert?

das ist langbewährte software, wenn du da noch einen Fehler findest, 
bist du wirklich gut - jedenfalls danke für das Interesse.
1
init_timer_smh() {
2
/*
3
cs02+01+00:
4
0 no clock
5
1 no presc
6
2 /8
7
3 /64
8
4 /256
9
5 /1024
10
*/
11
12
TCCR0A |= (1<<WGM01);
13
    // 1; Timer0 Vorteiler: 64 -> bei 16 MHz: 
14
    // 16.000.000 / 64 = 250000 Mal pro Sek gibts einen Takt an den Timer
15
    // 8.000.000 / 1024 = 7812 Mal pro Sek gibts einen Takt an den Timer
16
TCCR0B |= ((1<<CS02)|(1<<CS00));//1024
17
    
18
    // Timer0 soll bei 250 einen Output Compare Interrupt ausl�sen ->
19
    // 250.000 / 250 = 1000 mal pro Sek gibts einen Interrupt
20
    // 7812 /78 = 100 mal pro Sek gibts einen Interrupt
21
OCR0A = 77;//abgleich mit uhr
22
23
    //Compare Interrupt aktivieren
24
TIMSK0 |= (1<<OCIE0A);
25
26
    //Globale Interrupts aktivieren
27
sei();
28
}
29
30
31
ISR(TIMER0_COMPA_vect)
32
{
33
timer_proc_10ms();
34
}
35
36
37
int main(void)
38
{
39
MCUSR = 0;//wdg statusregister
40
wdt_disable();
41
zucMain();   
42
    
43
return(0);
44
}

von Ulrich F. (Gast)


Lesenswert?

grundschüler schrieb:
> wenn du da noch einen Fehler findest,
> bist du wirklich gut - jedenfalls danke für das Interesse.

Meister!!
Ich habe wenig Interesse deine Fehler zu finden, wenn du dich so 
sperrst....
Auch wenig Spass an der Salami Taktik.

Die Aussage timer_proc_10ms(); wird in einer ISR aufgerufen hätte fast 
gereicht.....
Schön wäre es noch zu sehen, wie du timer_smh definiert hast.....
(aber das ist wohl erst die nächste Salamischeibe)

§1:
timer_smh muss volatile  deklariert werden.

§2:
Das Bearbeiten von timer_smh im Hauptprogramm muss ATOMIC erfolgen.

> das ist langbewährte software,
Und auch diese muss man richtig verwenden...

Tipp:
Der Fehler findet sich immer an der Stelle, wo man zuletzt sucht.

Tipp2:
Es macht keinen Sinn, den Boten mit Verachtung zu überschütten.

von grundschüler (Gast)


Lesenswert?

Ulrich F. schrieb:
> Tipp2:
> Es macht keinen Sinn, den Boten mit Verachtung zu überschütten.

Das war keineswegs gewollt, ich bin für alle Hinweise dankbar, auch wenn 
sie nicht direkt zielführend sind. Ich gehe davon aus, dass du besser 
programmieren kannst als ich.

timer_smh ist volatile  deklariert, da es außerhalb der ir im 
Hauptprogramm bearbeitet wird

Der Timer funktioniert und ist nicht das Problem. Die Zeit wird am LCD 
fortlaufend angezeigt.Die LED blinkt.



Die Frage bleibt, warum die Atmel-wdt_reset-Funktion den wdg-Timer nicht 
ordnungsgemäß zurücksetzt und wie man das richtig handelt. WDG müsste 
doch eigentlich Standard in vielen Programmen sein. Ich habe aber trotz 
einigem Suchen keinen lauffähigen Beispielcode gefunden.

von Ulrich F. (Gast)


Lesenswert?

Vielleicht ist es ja unter gegangen.....


Darum nochmal:
Ulrich F. schrieb:
> §2: Das Bearbeiten von timer_smh im Hauptprogramm muss ATOMIC erfolgen.

Denn das fehlt in deinem gepostetem Code.

grundschüler schrieb:
> ich gehe davon aus, dass du besser
> programmieren kannst als ich.
Da kannst du von ausgehen, wobei ich mir aber nicht sicher bin, ob das 
stimmt....
KA!

grundschüler schrieb:
> timer_smh ist volatile  deklariert,
Ja, da ist sie ja die Salamischeibe....
Zumindest die halbe...
Der Datentype ist mir dadurch auch noch nicht bekannt....
Wie gesagt, wenn die zu bearbeitende Struktur mehr als 1 Byte 
beinhaltet, oder mehrfach gelesen/geschrieben wird (und das wird sie bei 
dir), ist die Angelegenheit ATOMIC zu machen.


Solange das nicht ATOMIC ist, hast du da einen Zufallsgenerator.
Und das wollen wir doch nicht.....

von Ulrich F. (Gast)


Lesenswert?

Nachtrag:

Bei mir funktioniert es in der Arduino IDE!
(nach dem ich Timer0 frei geschaufelt habe)

von grundschüler (Gast)


Lesenswert?

Ulrich F. schrieb:
> Bei mir funktioniert es in der Arduino IDE!
> (nach dem ich Timer0 frei geschaufelt habe)

danke für deine hilfe. ich hab es jetzt nocheinmal ohne timer aufgebaut. 
Es funktioniert wie es soll. hätte ich nicht gedacht, dass der wdg von 
anderen timern beeinflusst wird.

von holger (Gast)


Lesenswert?

>hätte ich nicht gedacht, dass der wdg von
>anderen timern beeinflusst wird.

Das wird er nicht. Du hast einfach nur Mist gebaut irgendwo
in deinem Programm.

von Ulrich F. (Gast)


Lesenswert?

holger schrieb:
> Das wird er nicht. Du hast einfach nur Mist gebaut irgendwo
> in deinem Programm.

Das sehe ich ähnlich.

Timer0 musste ich von dem Arduino - Ballast befreien, um deinen 10mSec 
Timer betreiben zu können.
Bin halt nur so ein Arduino C++ Jünger.....

von grundschüler (Gast)


Lesenswert?

holger schrieb:
> Das wird er nicht. Du hast einfach nur Mist gebaut irgendwo
> in deinem Programm.

guter Hinweis. Fehler gesucht, Fehler gefunden, hatte absolut nichts mit 
dem Timer zu tun.

Ulrich F. schrieb:
> Das sehe ich ähnlich

Nochmals danke für die Unterstützung. Der Hinweis auf den 
funktionierenden wdg beim arduino war hilfreich.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.