watchdog atmega328

Gast #4275356
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?
Gast #4275390
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?
Gast #4275485
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
}
Gast #4275614
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.
Gast #4275649
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.
Gast #4275998
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.....
Gast #4276371
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.