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:
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))
danach kommen defines und globale Variablen, kein setzen von Registern!
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:
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();
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.
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!
Lesezeichen