Ich glaube kaum dass 4500 Zeilen für mehr Übersicht sorgen, deshalb hier genau die Teile die das Programm beim Start durchläuft
Code Anfang:
danach kommen defines und globale Variablen, kein setzen von Registern!Code:#ifndef F_CPU #define F_CPU 16000000 #endif #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include <lcd.h> #include <math.h> #include <string.h> #include <avr/pgmspace.h> #include <i2cmaster.h> #include <avr/eeprom.h> #include <avr/wdt.h> unsigned char mcusr_mirror __attribute__ ((section (".noinit"))); // Watchdog ausschalten void get_mcusr(void) \ __attribute__((naked)) \ __attribute__((section(".init3"))); void get_mcusr(void) { mcusr_mirror = MCUSR; MCUSR = 0; wdt_disable(); } #define LED_gr_ein (PORTB &= ~(1<<PB0)) #define LED_gr_aus (PORTB |= (1<<PB0)) #define LED_rot_ein (PORTB &= ~(1<<PB1)) #define LED_rot_aus (PORTB |= (1<<PB1))
Diese Interrupts sind definiert:
Code:/* Interrupts */ volatile unsigned char timecount; volatile short radcount,i_summe,v_alt; volatile unsigned char odo_messer,odo_m; ISR(ISR_Timer2) { timecount++; if (timecount>250) timecount=250; radcount++; if (radcount>10000) radcount=10000; //static short ; short v, mowersp; if (timecount==25) {timecount++; odo_m=odo_messer; odo_messer=0; if (messer_aus==0) { v = (short)(drehzahl-odo_m); //Vergleich i_summe = i_summe + v; //Integration I-Anteil //mit "vergessen": (i_summe*9)/10 + v; if (i_summe < -1280) i_summe = -1280; //Begrenzung I-Anteil if (i_summe > 1280) i_summe = 1280; // mowersp=1*v+3*(i_summe*25)/100+1*((v -v_alt)*100)/25; // stabile Ausgangsbasis // mowersp=(3*v+5*((i_summe)/4)+3*((v -v_alt)*4)+320)/4; // 320 (320/4=80) als Startwert, alles /4 für geringe PWM Stufung mowersp=(5*v+3*((i_summe)/4)+5*((v -v_alt)*4)+560)/7; v_alt=v; if (mowersp < 40) mowersp = 40; //Begrenzung Stellgröße if (mowersp >= 255) mowersp = 255; mowerspeed=(unsigned char)(mowersp); Mower=mowerspeed; } } } ISR(INT2_vect) {odo_messer++;} ISR(PCINT0_vect) { radcount=0; } SIGNAL (__vector_default) // falsche Interrupt erkennen, abbrechen {cli();PORTC &= ~( (1<<PC2) | (1<<PC3) );PORTC &= ~( (1<<PC4) | (1<<PC5) );PORTC |= (1<<PC6) | (1<<PC7); lcd_gotoxy(0,0);lcd_puts_p(PSTR("Bad Interrupt ")); while(1); }
und hier der Anfang von main:
Hier habe ich die Wachtdog Abfrage ganz am Anfang eingebaut, hier extra für den Test noch bevor die einzelnen Register für I/O, PWM, LCD, USART; TWI etc gesetzt werden.Code:int main(void) { //char buffer[10]; short richtung_temp, richtung_soll,x_temp,y_temp; char korr_l,korr_r, modus; unsigned short speed_li, speed_re, felder,speed_fakt; // unsigned char x,y, z, sekunde, sekk, sekkk,sek_f, min,minstd,temp; //, odo_m, sek_gps modus=0; richtung_soll=1;korr_l=0;korr_r=0; sekunde=0;sekk=0;sekkk=0;sek_f=0; min=0;minstd=0; radcount=0;odo_m=0; x_temp=0;y_temp=0; //odo_li=14;odo_re=4;pos_x=2000;pos_y=1800;richtung=4700;Pos_odo(0); // Odometrie Test für Simulator //pos_x=300;pos_y=1300;GotoXY(1000,1300,1); // Test Navi // Watchdog LED_rot_aus;LED_rot_aus; // Watchdog-Reset if (mcusr_mirror & (1 << WDRF)) { LED_gr_ein;LED_rot_ein; while(1); } else wdt_enable(WDTO_1S); sei(); //Interupt ein while(1); //Test für Watchdog init(); //Porteinstellungen, PWM, LCD lcd_clrscr(); i2c_init();
Und genau dieser Code funktioniert im Simulator, nach 1s schlägt der Watchdog an, beim Neustart erkennt er das WDRF gesetzt ist, "schaltet" die LED's ein und bleibt wie er soll dort in der while Schleife.
Am Atmega funktioniert das nicht, sieht so aus als hängt er in endlosen Resets fest. Anscheinend wird der Watchdog am Anfang nicht ausgeschalten, aber das soll genau dieser Beispielcode aus der GCC lib erledigen.
LG!







Zitieren

Lesezeichen