Forum: Mikrocontroller und Digitale Elektronik Atmega 328p: Watchdog nicht abschaltbar


von Joschua C. (Gast)


Lesenswert?

Hallo werte Gemeinde,

ich habe auf einem Arduino etwas mit dem Watchdog herumexperimentiert. 
Bis er sich irgendwann nicht mehr abschalten ließ. Die Programmierung 
von dem Ding ging dann auch nicht mehr. Die funktioniert über einen 
Bootloader, der sich seinen Code aus einem USB-zu-RS232 Wandler zieht.

Also habe ich versucht back to the roots zu gehen, meinen avr910 
Programmer angehängt, die fusebits für den Bootloader entfernt und 
programmiere den Arduino jetzt mit avrdude und dem avr-gcc. Code kann 
ich aufspielen.

Jetzt zu folgendem Code:
1
#define F_CPU 16000000UL
2
3
//HEADER
4
#include  <avr/io.h>              // AVR Register und Konstantendefinitionen
5
#include  <inttypes.h>            // erweiterte stdint.h
6
#include  <avr/interrupt.h>         // Anpassung des Interruptregisters
7
//#include  <util/delay.h>            // Header mit definierten Zeitverzögerungen
8
#include  <avr/wdt.h>             //Watchdog
9
#include  "schaltparameter.h"   // Parameterdatei
10
11
12
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init1")));
13
14
void wdt_init(void)
15
{
16
  cli();
17
  wdt_reset();
18
  MCUSR = 0;
19
  WDTCSR |= (1 << WDCE) | (1 << WDE);
20
  WDTCSR = 0x00;
21
  wdt_disable();
22
  DDRB = 0xFF;
23
  PORTB = WDTCSR;
24
25
  return;
26
}
27
28
int main()
29
{
30
  //setup();
31
32
  while(1)
33
  {
34
    cli();
35
    wdt_reset();
36
    MCUSR = 0;
37
    WDTCSR |= (1 << WDCE) | (1 << WDE);
38
    WDTCSR = 0x00;
39
    wdt_disable();
40
    DDRB = 0xFF;
41
    PORTB = WDTCSR;
42
  }
43
44
  return 0;
45
}

Das ist ein Auschnitt aus dem, wa sich eigentlich programmieren will, 
was aber alles auskommentiert ist. schaltparameter.h enthält nur 
Konstantendefinitionen.

wdt_init() ist kopiert aus diesem Forum. Da hatte jemand das Problem, 
dass der Watchdog aktiv bleibt, wenn der uC startet. Wenn die 
Initialisierungen zu lange brauchen, löst der wd aus, bevor er im 
Usercode deaktiviert werden kann. So sollte das nicht mehr auftreten.

Die Mainloop deaktiviert den Watchdog mit der Bibliotheksfunktion und 
von Hand mit Registerzugriffen (feste Sequenz mit WDCE (Watchdog change 
enable) wurde wie im Datenblatt eingehalten).
Dann gibt sie den Inhalt des Watchdogkonfigurationsregisters auf PORTB 
aus, den schaue ich mir mit einem Logic-Analyzer an:

Direkt nach dem Aufspielen vom Programm lesen sich alle Bits des 
Registers zu null. Erst nach einem Power-Reset ist das 
Watchdog-Enablebit plötzlich gesetzt, obwohl es kurz zuvor zurückgesetzt 
wird. Das unterste Prescalerbit ist auch gesetzt. Der Watchdog ist also 
doch aktiv. Er löst aber nicht aus (ich vermute Mal, weil er immer 
wieder doch kurz deaktiviert wird)

Wenn ich das Deaktivieren vom Watchdog in der Mainloop auskommentiere 
und nur das Statusregister in PORTB schreibe (die Deaktivierung in 
wdt_init() bleibt aber im Code), dann löst der Watchdog auch aus. PORTB 
flackert. Die Zeit vom Watchdogprescaler findet sich im Signal wieder.

Compileroptimierung ist aus, das Highfuse ist D9, was die 
Standardeinstellung ist, in der das fusebit WDTON true, also 
unprogrammiert ist.

Hat jemand eine Idee, wie ich den Watchdog deaktivieren kann, ohne dass 
er selbstständig wieder angeht?

Vielen Dank

von spess53 (Gast)


Lesenswert?

HI

WDTON-Fuse gesetzt?

MfG Spess

von Joschua C. (Gast)


Lesenswert?

Fuse ist auf true, also unprogrammiert.

Jetzt habe ich einen gleichen Ardu gefunden (ich weiß, Aufräumen wäre 
mal geil) und habe von dem hfuse, lfuse, lock und flash auf den kaputten 
kopiert und jetzt läuft er.

von spess53 (Gast)


Lesenswert?

Hi

>Jetzt habe ich einen gleichen Ardu gefunden (ich weiß, Aufräumen wäre
>mal geil) und habe von dem hfuse, lfuse, lock und flash auf den kaputten
>kopiert und jetzt läuft er.

Und damit die möglichen Fehlerursachen vernichtet:

MfG Spess

von Joschua C. (Gast)


Lesenswert?

Stimmt, aber das ist ein klassischer Fall von "das muss fertig werden". 
Ich hab keine Zeit mir für ne Woche einen gebrickten uC auf den 
Schreibtisch zu legen und zu schauen wann der Watchdog gnädig wird. 
Jetzt musses ohne wd laufen und das muss später noch eingepflegt werden.

Er wurde nicht mal nach einem PowerOn Reset mit Deaktivierung in der 
Initialisierung abgeschaltet. Dann unterbricht er jedes Mal den 
Bootloader, wenn man den Arduino gerade mit der IDE programmiert. 
Eigentlich muss er so einfach wie möglich laufen und auch jemand mit 
rudimentären Kenntnissen soll das Programm z.B. auf einen zweiten 
aufspielen können, deswegen ists auch ein Arduino. Ich will nicht 
erzwingen, dass man z.B. auf einen zweiten Arduino erstmal mit einem 
AVR-ISP einen anderen Bootloader aufspielen müsste. Bei Zeiten muss ich 
das Programm so umschreiben, dass der WD nur einen Interrupt und keinen 
Reset auslöst, damit er den Bootloader nicht stören kann.

von Joschua C. (Gast)


Lesenswert?

Aber nach all dem Gemoser danke ich dir trotzdem für deine Hilfe :D

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.