Watchdog verbeißt sich unbegrenzt (RNControl, mega1284P)
Bitte um Hilfe zu meinem Watchdog-Reset. Ich habe bisher keine funktionierende Erfahrung mit Watchdog, die paar Anleitungen haben bisher nicht geholfen - zum Beispiel forumswissen oder dies hier.
Umgebung: mega1284P auf RNControl, 20 MHz, AVRStudio4, Programmer Pololu USB AVR Programmer, Labornetzteil, etliche Peripherie - andere Platinen über UART und I²C - die aber im Test alle abgeklemmt sind ausser UART und LCD auf PortB.
Der Watchdog wird durch avr/wdt.h eingebunden und als erste ausführbare Codezeile im main disabled. Auslösung durch ein Dreierpaket RC-5-Code aus (IR-FB-) Tastencode "0","0","0".
Codeauszüge:
Code:
//...
//
#include <stdlib.h> //
#include <avr/io.h> //
#include <avr/interrupt.h> //
#include <avr/wdt.h> //
// - - - - - - - - - - - - - - - -
// CPU wird NICHT definiert im AVRStudio Current Configuration Options
// wird ab hier von twimaster*.c u. evtl. anderen Libs benötigt
#define F_CPU 20e6//
============================================================================= =
// === HAUPTProgramm ========================================================== =
// Initialisierungen, LED1 kurzblinken als Signal für Programmstart,
// Ausgabe des Identifizierungsstrings per UART
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(void) //
{ //
uint8_t i; //
uint16_t ADC_ist; //
uint16_t l = 500; // Laufvariable für ADC-Abschaltung unten
....
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Anmerkung: bishier nur Includes, Defines, Deklaratonen und Definitionen
wdt_disable(); //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Ports+Pins als Ein- (0) od. Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
// A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp
// - - - - - - - - - - - - - - - -
DDRA = 0b00000000; // siehe aktuell oben oder Fortschritt/R2D2
PORTA = 0b00010000; // Für ADC: PA6+PA7 = ADC-Eingang ##>> OHNE Pullup !!
//
DDRB = 0b11111011; // siehe aktuell oben
PORTB = 0b01000000; // L1g on
//
DDRC = 0b11101100; // PC0 .. 7 (!) aktiv bei mega1284 !, PC0=SCL, PC1=SDA
PORTC = 0b11110000; // PC4 ist Eingang für RC-5 (war PB2)
//
DDRD = 0b11111111; // -> siehe unter DDRB
PORTD = 0b00000000; // Ports/Pull Ups (1) aktivieren
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//for(i=0; i<10; i++) // gLED2(PB5) blinken lassen bevor Interrupts erlaubt sind
Und so wird irgendwann durch Eingabe per RC-5 -- drei Bytes der Zifferntaste "0" -- der Watchdog ausgelöst:
Code:
if ( iBB16 == 0 ) // bei "000" WatchdogReset auslösen
{ //
// #include <avr/wdt.h>
cli(); // Interrupts global abschalten
wdt_enable (WDTO_15MS); // Watchdog aufziehen auf 15ms
while (1); // warten, bis er zubeisst...
}
Meine Programmierung basiert auf diesem Code aus dem RNW issen.
Der Betrieb des Programms läuft in einer zufälligen Testsequenz - verschiedene Aktionen und Ausgaben - sinnvoll. Der Watchdog wird wunschgemäß ausgelöst, nachdem der oben genannte Code "000" eingegeben und erkannt wurde. Danach läuft der Controller/die Platine nicht mehr (sinnvoll). Es dämmert nur eine LED vor sich hin. Drücken des /RESETknopfes oder [Read Signature] im AVR-Studio hilft nicht. Programmieren/Flashen ist nicht mehr möglich. Ein Wiederstart ist nur möglich durch Abklemmen des UART (RxD/TxD auf PD0 und PD1 über den Pololu-Programmer) und Abschalten der allgemeinen Versorgung.
Bitte um Hilfe und danke im Voraus.
Hat der Watchdogtest den Controller ruiniert ?
Nach Monaten mit anderen Baustellen bin ich zurück beim Watchdog. (M)EIN Problem: bei laufendem LCD hängt sich der Controller nach reproduzierbaren 11:15 min auf . . . :-/
Folgende Codeschnippsel wurden erstellt als Zusatz/Einfügung bei sonst problemlosen (bis auf den LCD-Bug) Steuerungsablauf. Damit war ein Test geplant, ob erstmal ne quick´n dirty Lösung per WDT möglich wäre
Code:
// Im Main nach Includierung der
#include <avr/interrupt.h> //
#include <avr/wdt.h> //
// Mainmodul
//..
Isecundn = 1; // Sekundenzähler max 9Stunden - NUR hier nullen
Itmr_RES = 0; // Sekundenzähler für RESET
wdt_init( );
TC2TMR_init(); // Init Timer/Cntr2-Interrupt 20 kHz/50 µsec tmr
// . . .
// Ende Main
//
// Im getrennten Timermodul nach erreichen einer Sekunde:
// . . .
Itmr_RES ++; // Resettimer wegen LCD-Fehlfunktion
if ( Itmr_RES == 30 ) // Zeit erreicht ??
{ //
Itmr_RES = 0; // Setze Timer vorsichtshalber zurück
wdt_enable( 1);
} // Ende if ( Itmr_RES ==
//
// ============================================================================= =
//void wdt_init(void) __attribute__((naked)) __attribute__((section(".init1")));
// ...
// ENde timer-Funktion
void wdt_init(void)
{
MCUSR = 0;
wdt_disable();
DDRA = (1<<PA0);
PORTA &= ~(1<<PA0);
return;
}
// ============================================================================= =
Das funktionierte mit seltsamer Konsequenz: es lief EINMAL ab, stoppte nach dreissig Sekunden, seit der Zeit geht garnix mehr. Nur die Heartbeat-LED - hier üblich auf PC6 - ging auf halbe Kraft bzw. 90 Hz.
Seltsam: Flashen - mit Verify - ist möglich, Fuses setzen und lesen ist möglich. Flashen eines früher sauber lauffähigen Programms ist möglich - aber die Funktion bleibt wie vorher: Heartbeat-LED auf halbe Kraft bzw. 90 Hz. Ansonsten läuft das früher sauber lauffähige Programm nicht :.-.((
Frage: hat jemand von Euch einen ungefähren Tip was los ist?
Danke im Voraus