PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupts gehen nicht mehr



damfino
01.06.2015, 10:21
Verzeifle gerade mit meinem Roboter: alle Motoren getestet, läuft, Deckel rauf, in den Garten, der Start vom Messermotor entspricht schon nicht dem Code, dann gleich alles tot, läuft in den Watchdog rein.

Hab nach langem suchen Herausgefunden dass die Interrupts , bzw Timer nicht aufgerufen werden, aber warum ist mir ein Rätsel. Lief ja schon.

zB Timer3, der steuert den gesamten Programmablauf
Funktion init:

/*+++++++Timer3++++++++++++++++*/
//CTC Mode
TCCR3B = (1<<CS32)|(1<<CS30)|(1<<WGM32); // Prescaler 1024
TIMSK3 = (1<<OCIE3A);//Interupt compare match enable

OCR3A=154; // alle 10ms 1 Interrupt


ISR(TIMER3_COMPA_vect)
{
static unsigned char tasktimer,tasktimersek;
short v, mowersp,temp_mower,drehtemp;
static short i_summe; // Testen ob das passt
static short i_summe_spe_li,i_summe_spe_re;
short spe_li,spe_re;//,temp;
short v_li,v_re;

radcount++;


tasktimer++;
tasktimersek++;
.
.
.
}



grundsätzlich soll bei einer falschen ISR abgeschalten werden:

ISR (__vector_default) // falsche Interrupt erkennen, abbrechen
{cli();PORTC &= ~( (1<<DDC2) | (1<<DDC3) );PORTC &= ~( (1<<DDC4) | (1<<DDC5) );PORTC |= (1<<DDC6) | (1<<DDC7);
LED_rot_ein;
flag_messer_aus=True;TCCR0B &= ~ (1<<CS01)|(1<<CS00);
Anzeige_Sonder(18);
while(1){wdt_reset();}
}


und so ist der Anfang der main:




int main(void)
{
short richtung_soll,richtung_temp,zeitstart,zeittemp;
char modus;//,v_min_count;
unsigned short felder; //,; //16Bit 65535
unsigned char x,y, z, sekunde, temp;
char bl,br,bv,s;//,bh

init(); //Porteinstellungen, Timer, PWM, LCD


lcd_gotoxy(0,0);lcd_puts_p(PSTR("einschalten"));

i2c_init();_delay_ms(10);

LED_gr_ein;LED_rot_aus;
Motor_li_stop();Motor_re_stop();Mower_stop();


// Watchdog

// Watchdog-Reset //Brown out // Power reset
if ((mcusr_mirror & (1 << WDRF)))//||(mcusr_mirror & (1 << BORF)))//||(mcusr_mirror & (1 << PORF)))
{
Anzeige_Sonder(LCD_WATCHDOGK1); // "!WATCHDOG! "
Motoren_stop();Mower_faststop();
}

wdt_enable(WDTO_4S);

sei(); //Interupt ein
wdt_reset();


Einlesen(); // letzten Stand der Karte lesen
Karte_init(); // Karte initializieren ( auch wenn im EEPROM => muss! damit besetzte Felder sicher eingetragen werden)





//----------------------------------- Funktionstest TWI ------------------------------
Anzeige_Sonder(LCD_Kontroller1OK); //"Kontroller 1 OK!"
Akkuspannunglesen();Akkuspannunglesen();Akkuspannu nglesen(); // gleich oft wie Werte gemittelt werden

Akkucheck();

//Warten();Warten();

richtung_kom =0;
if(i2c_start(Adresse_Kompass)==0)
{
i2c_write(1); // register
i2c_rep_start(Adresse_Kompass); // restart
richtung_kom = (short)i2c_readNak(); // read 1 byte //neuen Wert lesen;
i2c_stop();
if (richtung_kom!=0) Anzeige_Sonder(LCD_KompassOk); // "Kompass ok!
}
else {Anzeige_Sonder(LCD_FehlerKompass); // "Kompass Fehler!
//while(1);
}

//Warten();Warten();





Und wenn man die Funktion "Warten()" aktiviert hauts da das Programm raus, oder mit auskommentierter Funktion eben an einer anderen Stelle wo der Watchdog zuschlägt:

/*++++++++ Warten 0,5s +++++++++++++++++++++++++++++++++++++*/
static inline void Warten(void)
{
char x;

x=0;

while (x<2)
{
if (gps_str_complete>GPS_Receive_Complete) GPS();
if (Funk_Daten) RXFunk();
TX_Funk();
if (taskflag==taskdatenflag)
{
taskflag=taskflagclear;
DatatoSlave();
}


if (taskflag==task250msflag)
{ taskflag=taskflagclear;
Messercheck();
x++;
wdt_reset();
}
}
}


Verwendet wird ein Arduino Mega2560, aber nicht in Arduino Umgebung sondern normal mit Atmel Studio 6.2. Stromversorgung über DC Wandler direkt auf 5V, der Linearregler vom Arduino wird umgangen.
Programm funktioniert ansonsten normal, kann Bootloader raufgeben, über Bootloader flashen (via Bluettoth), die Anzeigen am LCD werden alle ausgegeben.
Hatte auch extra eine LED in der Timer ISR geschalten, nichts gesehen. Hatte die ISR auf Timer5 unbenannt, hätte im Programm die falsche ISR erkannt und abgebrochen werden müssen, aber nichts ist passiert.
Hab alles kontrolliert ob nicht irgendwo ein nicht erkanntes cli() versteckt ist.
Ist ja nicht das erste Mal dass ich ISR programmiere, die ersten Tests vom Code nach der Umstellung der Hardware liefen seit Jänner, und hatte keine Probleme.
Hatte schon früher mal eine Frage wegen Anzahl der ISR gestellt, und dabei extra ISR's eingebaut um den Ablauf zu testen, gab damals kein Problem


Kann man über Fuses die ISR /Timer abschalten?
Wie kann es sonst sein dass die ISR nicht mehr funktionieren?
Hab 3 Tage lang die PI Regler der Motoren optimiert (die auch in einer ISR ablaufen), die Akkuanzeigen kalibriert, alles lief normal.
Jetzt kommt man gar nicht mehr soweit dass die Motoren laufen würden...
Habe anstatt Timer 3 auch mal auf Timer 5 (Timer + ISR) umgestellt, exakt das gleiche.


Für einen Hardwaredefekt wäre das wohl zu selektiv, oder? Da müsste doch der ganze Programmablauf hinüber sein. Obwohl, die ersten Sekunden im Garten waren schon ein falscher Programmablauf, aber am Abend zuvor im Arbeitszimmer hatte es zu 100% funktioniert. Sollten die Motoren nach 3 Jahren in Betrieb auf einmal stören??. Aber warum geht es dann auch nicht ohne Motoren?

Ach ja, die Watchdog Ausgabe am LCD kommt nur wenn kein Bootloader drauf ist. Mit Bootloader wird einfach nach 4s das Programm neu gestartet. Dachte deswegen es liegt am Bootloader, aber egal, mit und ohne geht es nur bis der Watchdog zuschlägt

Keine Ahnung nach was ich suchen könnte, jede Idee wäre hilfreich.

LG!

Bumbum
01.06.2015, 19:33
Hallo damfino,

jetzt beim schnellen überfliegen deines Codes fehlt das SEI, um die Interrupts überhaupt freizuschalten. (Zeile aus versehen gelöscht?) Kann es aber auch übersehen haben.

Viele Grüße
Andreas

damfino
01.06.2015, 21:45
Hallo Andreas,
SEI ist da, gleich nach der Watchdog Abfrage. Habs jetzt nach weiter rauf init() geschoben, kein Unterschied.
Die Fuses gerade von normalem externen Crystal (original Einstellung vom Board) auf Fullswing Crystal gesetzt

Noch was anderes ist mir gerade aufgefallen:
Habe nach der Watchdog Abfrage einfach mal das eingebaut:

_delay_ms(100);
LED_gr_aus;LED_rot_aus;
_delay_ms(100);
LED_gr_ein;LED_rot_ein;
_delay_ms(100);
LED_gr_aus;LED_rot_aus;
_delay_ms(100);
LED_gr_ein;LED_rot_ein;
_delay_ms(100);
LED_gr_aus;LED_rot_aus;
_delay_ms(100);

Das Blinken dauert locker 3s anstatt 100ms. Die Clkdiv8 Fuse ist richtig gesetzt, sonst geht gleich gar nichts mehr.
Im Code steht natürlich auch:
#ifndef F_CPU
#define F_CPU 16000000
#endif

Ebenso sind in der TWI und LCD Lib von Fleury die richtigen 16000000 Hz eingetragen, und im AVR Studio unter Compiler -> Symbols "F_CPU=16000000"

LG

- - - Aktualisiert - - -

So, habe die alten Software Versionen neu compiliert und getestet, der Code funktioniert bis dahin wo ich die ISR Eingänge ändern musste, dh mit dieser Konfiguration macht es Probleme:

/*+++ Interrupt Messer +++++++++*/ // PIN PD3 - digital pin 18 (TX1)
EICRB |= (1<<ISC30) ; // jede Flanke
EIMSK |= (1<<INT3); // Int enable

/*+++ Interrupt Vorderrad (pin change interrupt) +++++++++*/
PCICR |= (1<<PCIE0); // Int 7-0 enable
PCMSK0 |= (1<<PCINT5); // Pin B5


/*+++ Interrupt Odo Links +++++++++*/ // PIN PE4 - PWM digital pin 2
// EICRB |= (1<<ISC41) ; // eine Flanke
EICRB |= (1<<ISC40) ; // jede Flanke
EIMSK |= (1<<INT4); // Int enable



/*+++ Interrupt Odo Rechts +++++++++*/ // PIN PE5 - PWM digital pin 3
// EICRB |= (1<<ISC51) ; // eine Flanke
EICRB |= (1<<ISC50) ; // jede Flanke
EIMSK |= (1<<INT5); // Int enable


Es sind Hallsensoren, bzw 1x ein Reed Kontakt....
Eindeutig, wenn diese Interrupts deaktiviert sind, läuft der Timer3 und damit das Programm.
Warum auch immer.
Aber irgendwie muss ich diese Eingänge einlesen können???

LG!

- - - Aktualisiert - - -

Ich glaub ich spinn gerade: Hab alle ISR ausser Timer 3 auskommentiert, und einzeln wieder aktiviert um zu sehen bei welcher ISR das Programm wieder hängt.
Alles ist wieder aktiv, und das Programm geht wieder.
Verstehe das alles nicht mehr.
Einzige Änderung war die Fuse beim Crystal, danach noch 10x flashen, und das wars?
Das wars für heute, vielleicht verstehe ich die Welt morgen wieder.