Hallo,

ich bin gerade dabei ein kleines Programm für eine Ladeschaltung zu Programmieren. Ich benutze einen Atmega8. Im Allgmeinen ist das Programm wie folgt aufgebaut:

Ich benutze 2 Timer. Timer1 für die PWM generierung der LED. Einmal steuern der Helligkeit und einmal Ein und Aus schalten in abhängigkeit des ADUs. Außerdem ereuge ich durch zwei hochzählende Variablen Takte als abaufsteuerung des restlichen Programms

Timer0 soll den µC aus dem Idle Mode wecken.

Das alles funktioniert auch schön und gut. Allerdings möchte ich auch das der µC durch INT0 geweckt wird durch eine Positive Flanke. Leider funktioniert es nicht wirklich. Er springt glaub ich in die ISR rein allerdings hab ich da wohl nicht sauber Programmiert. Kann mir da einer helfen? Wäre super hab mir schon total den kopf zerbrochen....

Ich bedanke mich schon einmal für die Hilfe.

Gruß Jonas

Hier der Code:

Code:
#define F_CPU 1000000UL            //CPU takt auf 1MHz#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "ADC.h"


#define Uladeschluss 1014
#define UladeschlussLED Uladeschluss-0
#define UladeschlussR 914
#define Uladeunter 814
#define UladeunterLED Uladeunter+0
#define UladeunterR 914
#define adupwmmin Uladeunter
#define adupwmmax Uladeschluss
#define helligkeit 5 //10 ist maximum


#define devidedeltaU (((UladeschlussLED)-(UladeunterLED))/100)


#define ledddr DDRD
#define ledPort PORTD
#define ledG PD7
#define ADC_ONddr DDRB
#define ADC_ONPort PORTB
#define ADC_ON PB0
#define ladeddr DDRD
#define ladeport PORTD
#define ladeschlussS PD3
#define ladeschlussR PD4
#define ladeunterS PD5
#define ladeunterR PD6
#define ladeschlussRelais PD0
#define ladeunterRelais PD1
#define DynOn PD2
#define Relaisddr DDRD
#define RelaisPort PORTD
#define RelaisPins PIND


volatile unsigned char timerz=0;
volatile unsigned char timerpwm = 0;
volatile unsigned short adupwm;
volatile unsigned short takt1 = 0;
volatile unsigned short takt2 = 0;
volatile unsigned char status1 = 0;
volatile unsigned short adu, adu1, adu2;


ISR(INT0_vect)
{
    GICR &= ~(1<<INT0);        //INT0 aus
    MCUCR &= ~(1<<SE);
    timerz=0;
    timerpwm=0;
    takt1=0;
    takt2=0;
    TCCR0 |= (1<<CS01);  //Timer0 ein mit prescler 8
    TCCR1B = 0;            //Timer1 aus
}


ISR(TIMER0_OVF_vect)
{
    takt1++;
    takt2++;
    timerz++;
    if(timerz <= helligkeit)
    {    
        if (adupwm < timerpwm)
        {
            ledPort &= ~(1<<ledG);
        }
        else
        {
            ledPort |= (1<<ledG);
        }
        if (timerpwm>=100)
        {
            timerpwm=0;
        }
    }
    else
    {
        ledPort &= ~(1<<ledG);
    }
    
    if(timerz==10)
    {
        timerz=0;
        timerpwm++;
    }    
}


ISR(TIMER1_OVF_vect)
{
    MCUCR &= ~(1<<SE);
    GICR &= ~(1<<INT0);        //INT0 aus
    timerz=0;
    timerpwm=0;
    takt1=0;
    takt2=0;
    TCCR0 |= (1<<CS01);  //Timer0 ein mit prescler 8
    TCCR1B = 0;            //Timer1 aus
}    


void impuls(volatile uint8_t *port, uint8_t pin);


int main(void)
{
    //extern ref.. ADC0 als Eingang, rechts Ausrichtung
    ADMUX = 0;
    //ADU Einstellung:Einzelwandlung, 128 Teilung, keine Interrupts
    ADCSRA = 0;
    ADCSRA |= (1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0);
    
    //Timer0 Teiler
    TCCR0 = 0;
    TCCR0 |= (1<<CS01);  //prescaler auf 8 2ms pro Überlauf bei 1MHz
    //Timer0 Interrupt einschalten
    TIMSK = 0;
    TIMSK |= (1 << TOIE0);
    
    //Timer1 Teiler
    TCCR1B = 0;
    TCCR1B |= (1<<CS12)|(1<<CS10);    //prescaler auf 1024 alle 61sec ein Überlauf bei 1MHz
    //Timer1 Interrupt einschalten
    TIMSK |= (1<<TOIE1);
    
    //Extern Interrupt
    MCUCR |= (1<<ISC01)|(1<<ISC00);        //INT0 auf steigende Flanke (1<<ISC01)|(1<<ISC00)
    
    // Den Pin, an den die LED angeschlossen ist, als Ausgang setzen
    ledddr = 0;
    ladeddr = 0;
    ADC_ONddr = 0;
    Relaisddr = 0;
    
    ledddr |= (1 << ledG);
    ladeddr |= (1 << ladeunterR)|(1<<ladeunterS)|(1<<ladeschlussS)|(1<<ladeschlussR); //Als Ausgang
    ADC_ONddr |= (1<<ADC_ON);
    
    RelaisPort |= (1<<ladeschlussRelais)|(1<<ladeunterRelais);  //Eingänge setzen
        
    sei();
    
    
    /*
    do                        //Ersten ADU wert einlesen
    {
        timerz=0;
        ledPort &= ~(1<<ledG);
        
        if (takt1>489)                            //takt1 wird vom zähler gezählt, d.h. warten
        {
            if (!(status1 & (1<<0)))            //wenn noch nicht in schleife
            {
                ADCSRA |= (1<<ADEN);            //Einschalten des ADU
                ADC_ONPort |= (1<<ADC_ON);        //Einschalten ADC_ON um Spannungsteiler vom ADC auf Masse zu legen
                status1 |= (1<<0);
            }
            
            if (takt1>=500 && !(status1 & (1<<1)))   //Erste AD Wandlung danach eine Zweite
            {                                        //beide werden verglichen ob sie auf bis zu
                adu1 = getADC();                    //10 stellen ähnlich sind wenn ja
                status1 |= (1<<1);                    //weiter mit arbeiten
            }
            
            if (takt1>=510)
            {
                adu2 = getADC();
                
                if ((adu1<=(adu2+5)) && (adu1 >=(adu2-5)))
                {
                    adu=adu2;
                }
                
                
                if (adu<=UladeunterLED)        //Kontrolle ob ladeunter- oder Ladeüberspannung
                {                            //erreicht wurde und dadrauf die grenzen für das
                    adupwm=0;                //blinken der LED setzen
                }
                else
                {
                    if (adu >= UladeschlussLED)
                    {
                        adupwm=100;
                    }
                    else
                    {
                        adupwm=((adu-UladeunterLED)/devidedeltaU);
                    }
                }
                
                ADCSRA &= ~(1<<ADEN);            //Auschalten des ADU
                ADC_ONPort &= ~(1<<ADC_ON);
                status1 &= ~(1<<0);
                status1 &= ~(1<<1);
            }                                        
        }        
    } while (takt1<=513);
    
    takt1=0;
    */
    while (1)                                    //Hauptschleife
    {
        if (takt1>489)                            //takt1 wird vom zähler gezählt, d.h. warten
        {
            if (!(status1 & (1<<0)))            //wenn noch nicht in schleife
            {        
                ADCSRA |= (1<<ADEN);            //Einschalten des ADU                            
                ADC_ONPort |= (1<<ADC_ON);        //Einschalten ADC_ON um Spannungsteiler vom ADC auf Masse zu legen
                status1 |= (1<<0);
            }
                        
            if (takt1>=500 && !(status1 & (1<<1)))   //Erste AD Wandlung danach eine Zweite
            {                                        //beide werden verglichen ob sie auf bis zu
                adu1 = getADC();                    //10 stellen ähnlich sind wenn ja
                status1 |= (1<<1);                    //weiter mit arbeiten
            }
            
            if (takt1>=510)
            {
                adu2 = getADC();
                
                if ((adu1<=(adu2+5)) && (adu1 >=(adu2-5)))
                {
                    adu=adu2;
                }
                                
        
                if (adu<=UladeunterLED)        //Kontrolle ob ladeunter- oder Ladeüberspannung
                {                            //erreicht wurde und dadrauf die grenzen für das
                    adupwm=0;                //blinken der LED setzen
                } 
                else
                {
                    if (adu >= UladeschlussLED)
                    {
                        adupwm=100;
                    }
                    else 
                    {
                        adupwm=((adu-UladeunterLED)/devidedeltaU);
                    }    
                }
                
                ADCSRA &= ~(1<<ADEN);            //Auschalten des ADU
                ADC_ONPort &= ~(1<<ADC_ON);    
                takt1=0;
                status1 &= ~(1<<0);    
                status1 &= ~(1<<1);    
                
                //Kontrolle ob Ladeunter- oder Ladeüberspannung erreicht wurde dann Kontrolle ob Relais
                //schon geschaltet haben sonst selber schalten
                if ((adu > Uladeschluss) && !(RelaisPins & (1<<ladeschlussRelais)))
                {
                    ladeport |= (1<<ladeschlussS);
                }else ladeport &= ~(1<<ladeschlussS);
                
                if ((adu < UladeschlussR) && (RelaisPins & (1<<ladeschlussRelais)))
                {
                    ladeport |= (1<<ladeschlussR);
                }else ladeport &= ~(1<<ladeschlussR);
                
                if ((adu < Uladeunter) && !(RelaisPins & (1<<ladeunterRelais)))
                {
                    ladeport |= (1<<ladeunterS);
                }else ladeport &= ~(1<<ladeunterS);
                
                if ((adu > UladeunterR) && (RelaisPins & (1<<ladeunterRelais)))
                {
                    ladeport |= (1<<ladeunterR);
                }else ladeport &= ~(1<<ladeunterR);                        
            }
        }
        
        takt2=0;
        
        if (!(RelaisPins & (1<<DynOn)))
        {
            do                //Nichts tun nur Timer0 läuft daher LED blinkt
            {
            } while (takt2<=2100 && !(RelaisPins & (1<<DynOn)));
            
            TCCR0 = 0;                //Timer0 aus
            TCCR1B |= (1<<CS12)|(1<<CS10); //Timer1 ein
            ledPort &= ~(1<<ledG);    //LED aus
            GICR |= (1<<INT0);        //INT0 ein
            MCUCR |= (1<<SE);        //Sleep Modus ein
        }
                                    
    }
}