-         

Ergebnis 1 bis 2 von 2

Thema: AC löst keinen Interrupt aus

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544

    AC löst keinen Interrupt aus

    Anzeige

    Hi,

    ich habe ein Problem mit einem AtXMega32A4 bzw. AtXMega16A4. Ich habe den AC so konfiguriert, dass er bei steigender bzw. fallender Flanke (wird im Programm ständig geändert) einen Interrupt auslösen soll und in der ISR dann eine LED toggeln. Das ganze hat auch schonmal funktioniert, tuts aber komischerweise jetzt nicht mehr...
    Die bieden versch. µCs hab ich angegeben, weil ich erst dachte, der AC Des XM16A4 sei kaputt und hab deshalb die Chips getauscht, jedoch gleiches Verhalten.
    Hab dann probeweise mal den DAC als neg. Quelle benutzt und langsam hochzählen lassen, da hats dann auch funktioniert. Mit der selben Hardware und gleichen Routinen (bis auf den DAC) läufts aber nicht. Die anliegenden Signale hab ich auf dem Oszi, deren Amplituden unterscheiden sich max. ca. 200mV (was ja locker für den AC reichen sollte).
    Hier mal der Code:
    Code:
    /*
     * BlControlV10.c
     *
     * Created: 21.01.2014 23:50:02
     *  Author: Chris
     */ 
    
    
    #define F_CPU 32000000UL
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <string.h>
    #include <util/twi.h>
    #include <math.h>
    #include <avr/eeprom.h>
    
    
    
    //ADC Defines
    #define VoltagePinConfig (PORTA.DIRCLR = 0x10) //PORTA.4
    #define CurrentPinConfig (PORTA.DIRCLR = 0x40) //PORTA.6
    #define CurrentNegPinConfig (PORTA.DIRCLR = 0x80) //PORTA.7
    
    
    //RpmTimer Defines
    #define RpmTimer (TCE0)    
    #define RpmTimerOvfVect (TCE0_OVF_vect)
    
    
    //Global Defines
    /*
    #define TimerPer (2000)
    
    #define MinPwm (200)
    #define MaxPwm (1800)
    #define AnlaufPwm (200)
    */
    
    #define TimerPer (1000)
    
    #define MinPwm (100)
    #define MaxPwm (900)
    #define AnlaufPwm (100)
    
    
    //Pwm Input Capture Defines
    #define PwmInputTimer (TCD0)
    #define PwmInputPinConfig (PORTD.DIRCLR = 0x04) //PORTD.2
    
    #define PwmInput (TCD0.CCC)
    
    
    //PC UART Defines
    #define PCUartPinConfig (PORTD.DIRSET = 0x80)
    #define PCUartPort (USARTD1)
    
    
    //SD Pin Defines
    #define PhaseASdConfigPin (PORTB.DIRSET = 0x02) //PORTB.1
    #define PhaseASdOn (PORTB.OUTSET = 0x02)
    #define PhaseASdOff (PORTB.OUTCLR = 0x02)
    #define PhaseASdStatus (PORTB.IN & 0x02)
    
    #define PhaseBSdConfigPin (PORTB.DIRSET = 0x04) //PORTB.2
    #define PhaseBSdOn (PORTB.OUTSET = 0x04)
    #define PhaseBSdOff (PORTB.OUTCLR = 0x04)
    #define PhaseBSdStatus (PORTB.IN & 0x04)
    
    #define PhaseCSdConfigPin (PORTB.DIRSET = 0x08) //PORTB.3
    #define PhaseCSdOn (PORTB.OUTSET = 0x08)
    #define PhaseCSdOff (PORTB.OUTCLR = 0x08)
    #define PhaseCSdStatus (PORTB.IN & 0x08)
    
    
    //PWM Defines
    #define PwmPortPinConfig (PORTC.DIRSET = 0x07)
    #define PwmTimer (TCC0)
    
    #define PhaseAPwmConfigPin (PORTC.DIRSET = 0x04) //PORTC.2
    #define PhaseAPwm (TCC0.CCC)
    #define PhaseAGnd (TCC0.CCC = 0)
    #define PhaseAVcc (TCC0.CCC = MaxPwm) 
    
    #define PhaseBPwmConfigPin (PORTC.DIRSET = 0x02) //PORTC.1
    #define PhaseBPwm (TCC0.CCB)
    #define PhaseBGnd (TCC0.CCB = 0)
    #define PhaseBVcc (TCC0.CCB = MaxPwm)
    
    #define PhaseCPwmConfigPin (PORTC.DIRSET = 0x01) //PORTC.0
    #define PhaseCPwm (TCC0.CCA)
    #define PhaseCGnd (TCC0.CCA = 0)
    #define PhaseCVcc (TCC0.CCA = MaxPwm)
    
    
    //AnalogComperator Defines
    #define DisableAc (ACA.AC0CTRL = 0x00)
    
    #define NoHysteris (0x00)
    #define SmallHysteris (0x02)
    #define LargeHysteris (0x04)
    
    #define Hysteris (NoHysteris) //LargeHysteris
    
    #define ClearAcIntFlag (ACA.STATUS |= 0x01)
    
    #define AcRising (ACA.AC0CTRL = 0xF9) //(ACA.AC0CTRL = 0xF9 | Hysteris)
    #define AcFalling (ACA.AC0CTRL = 0xB9) //(ACA.AC0CTRL = 0xB9 | Hysteris)
    //#define AcRising (ACA.AC0CTRL = 0x39)
    //#define AcFalling (ACA.AC0CTRL = 0x39)
    
    #define MittelACConfigPin (PORTA.DIRCLR = 0x08) //PORTA.3
    
    #define PhaseAACConfigPin (PORTA.DIRCLR = 0x20) //PORTA.5
    #define PhaseAAcUse (ACA.AC0MUXCTRL = 0x1B)
    
    #define PhaseBACConfigPin (PORTA.DIRCLR = 0x02) //PORTA.1
    #define PhaseBAcUse (ACA.AC0MUXCTRL = 0x19)
    
    #define PhaseCACConfigPin (PORTA.DIRCLR = 0x01) //PORTA.0
    #define PhaseCAcUse (ACA.AC0MUXCTRL = 0x18)
    
    #define PhaseAACConfigPin (PORTA.DIRCLR = 0x20) //PORTA.5
    #define PhaseBACConfigPin (PORTA.DIRCLR = 0x02) //PORTA.1
    #define PHaseCACConfigPin (PORTA.DIRCLR = 0x01) //PORTA.0
    #define PhaseMittelConfigPin (PORTA.DIRCLR = 0x08) //PORTA.3
    
    
    //Led Defines
    #define LedRedConfigPin (PORTC.DIRSET = 0x10) //PORTC.4
    #define LedRedOn (PORTC.OUTSET = 0x10)
    #define LedRedOff (PORTC.OUTCLR = 0x10)
    #define LedRedTgl (PORTC.OUTTGL = 0x10)
    
    #define LedGreenConfigPin (PORTC.DIRSET = 0x08) //PORTC.3
    #define LedGreenOn (PORTC.OUTSET = 0x08)
    #define LedGreenOff (PORTC.OUTCLR = 0x08)
    #define LedGreenTgl (PORTC.OUTTGL = 0x08)
    
    
    //Shunt ADC Defines
    #define ShuntAdcConfigPin (PORTA.DIRCLR = 0x40) //PORTA.6
    
    
    //UBat ADC Defines
    #define UBatAdcConfigPin (PORTA.DIRCLR = 0x10) //PORTA.4
    
    
    //KommutierungsPin Defines
    #define KommPinConfig (PORTD.DIRSET = 0x04)
    #define KommPinTgl (PORTD.OUTTGL = 0x04)
    
    
    
    //Routine Defines
    void InitClock(void);
    void InitInterrupt(void);
    void InitPCUart(void);
    void InitPwmTimer(void);
    void InitRpmTimer(void);
    void InitPwmInputTimer(void);
    void InitAc(void);
    void InitAdc(void);
    
    int main(void);
    
    void ReadVoltage(void);
    void ReadCurrent(void);
    
    void Wait(uint16_t s);
    void WaitMs(uint16_t ms);
    void WaitUs(uint16_t us);
    
    void SendPCUart(char data[], uint8_t crlf);
    
    void Anlauf(void);
    
    void ZustandStateMachine(void);
    
    
    
    //Voltage ADC
    int32_t VoltageLp;
    int32_t VoltageV;
    
    
    //Current ADC
    int32_t CurrentLp;
    int32_t CurrentA;
    
    
    //Zustand
    volatile uint8_t Zustand = 1;
    
    
    volatile char debug1[20];
    volatile char debug2[20];
    volatile char debug3[20];
    
    
    volatile uint16_t AcTimerDelay;
    
    
    volatile int16_t PwmIn;
    
    volatile int32_t SetPwm;
    
    
    int32_t SollDrehzahl;
    int32_t DrehzahlTmp;
    int32_t DrehzahlLp;
    
    int32_t DrehzahlOld;
    
    
    //This parameters have to be adapted according to the actual motor!
    int32_t kV = 1100;
    int32_t NumberOfMagnets = 10;
    
    int32_t PSet = 0;
    int32_t DSet = 0;
    
    
    int main(void)
    {
        
        InitClock();
        InitPCUart();
        
        InitPwmTimer();
        
        //InitPwmInputTimer();
        
        InitAc();
        
        InitAdc();
        
        //Init Pins
        LedRedConfigPin;
        LedGreenConfigPin;
        
        PhaseASdConfigPin;
        PhaseBSdConfigPin;
        PhaseCSdConfigPin;
        PhaseAPwmConfigPin;
        PhaseBPwmConfigPin;
        PhaseCPwmConfigPin;
        
        PhaseAGnd;
        PhaseBGnd;
        PhaseCGnd;
        
        LedRedOff;
        
        //cut off MosFets
        PhaseASdOff;
        PhaseBSdOff;
        PhaseCSdOff;
        
        
        KommPinConfig;
        
    
        //make sure to allways be able to programm the AVR
        Wait(2);
    
        SendPCUart("Start",1);
    
        WaitMs(500);
        
        InitRpmTimer();
        
        LedRedOn;
        LedGreenOn;
        WaitMs(500);
        LedGreenOff;
        
    
        Anlauf();
        InitInterrupt();
        while(1)
        {
            Zustand++;
            if(Zustand>=7) 
            { 
                Zustand = 1; 
            }
            ZustandStateMachine();
            WaitUs((uint16_t)1000);        
        }
    
    }
    
    void InitAdc(void)
    {    
        VoltagePinConfig;
        CurrentPinConfig;
        CurrentNegPinConfig;
        
        ADCA.CTRLB = 0x18;
        ADCA.REFCTRL = 0x11;
        ADCA.EVCTRL = 0x40;
        ADCA.PRESCALER = 0x03;
        
        ADCA.CH0.CTRL = 0x01;
        ADCA.CH0.MUXCTRL = 0x20;
        ADCA.CH0.CTRL |= ADC_CH_START_bm;
        
        ADCA.CH1.CTRL = 0b00001111;
        ADCA.CH1.MUXCTRL = 0x30 | 0x03;
        ADCA.CH1.CTRL |= ADC_CH_START_bm;
        
        ADCA.CTRLA = 0x01;
    }
    
    void InitPwmInputTimer(void)
    {
        PwmInputPinConfig;
        
        PwmInputTimer.CTRLA = 0x01; //Prescaler = 1
        PwmInputTimer.CTRLB = 0x40; //CC C enabled , normal mode
        PwmInputTimer.CTRLD = 0x20; //Event = input capture
    }
    
    void Anlauf(void)
    {
        SetPwm = AnlaufPwm;
    
        for(uint16_t i=0;i<2000;i+=15) //2000
        {
            Zustand++;
            if(Zustand>=7) { Zustand = 1; }
            ZustandStateMachine();
            WaitUs((uint16_t)3000-i);        
        }
    }
    
    void ZustandStateMachine(void)
    {
        if(SetPwm<MinPwm) { SetPwm = MinPwm; }
        if(SetPwm>MaxPwm) { SetPwm = MaxPwm; }
            
        if(Zustand==1)
        {
            PhaseASdOn;
            PhaseBSdOff;
            PhaseCSdOn;
            
            PhaseAPwm = (uint16_t)SetPwm;
            PhaseCGnd;
            
            AcFalling;
            PhaseBAcUse;
        }else if(Zustand==2)
        {
            PhaseASdOff;
            PhaseBSdOn;
            PhaseCSdOn;
            
            PhaseBPwm = (uint16_t)SetPwm;
            PhaseCGnd;
            
            AcRising;
            PhaseAAcUse;
        }else if(Zustand==3)
        {
            PhaseASdOn;
            PhaseBSdOn;
            PhaseCSdOff;
            
            PhaseBPwm = (uint16_t)SetPwm;
            PhaseAGnd;
            
            AcFalling;
            PhaseCAcUse;
        }else if(Zustand==4)
        {
            PhaseASdOn;
            PhaseBSdOff;
            PhaseCSdOn;
            
            PhaseCPwm = (uint16_t)SetPwm;
            PhaseAGnd;
            
            AcRising;
            PhaseBAcUse;
        }else if(Zustand==5)
        {
            PhaseASdOff;
            PhaseBSdOn;
            PhaseCSdOn;
            
            PhaseCPwm = (uint16_t)SetPwm;
            PhaseBGnd;
            
            AcFalling;
            PhaseAAcUse;
        }else if(Zustand==6)
        {
            PhaseASdOn;
            PhaseBSdOn;
            PhaseCSdOff;
            
            PhaseAPwm = (uint16_t)SetPwm;
            PhaseBGnd;
            
            AcRising;
            PhaseCAcUse;
        }
    }
    
    void InitAc(void)
    {        
        PhaseAACConfigPin;
        PhaseBACConfigPin;
        PhaseCACConfigPin;
        PhaseMittelConfigPin;
        
        AcFalling;
        Zustand = 1;
        PhaseAAcUse;
    }
    
    void InitPwmTimer(void)
    {
        PwmPortPinConfig;
        
        PwmTimer.CTRLA = 0x01; //Prescaler = 1
        PwmTimer.CTRLB = 0x73; //CCA CCB CCC enabled , Single-Slop Pwm
        PwmTimer.CTRLC = 0x00;
        PwmTimer.CTRLD = 0x00;
        PwmTimer.CTRLE = 0x00;
        
        PwmTimer.PER = TimerPer;
        PhaseAGnd;
        PhaseBGnd;
        PhaseCGnd;    
    }
    
    void InitRpmTimer(void)
    {
        RpmTimer.CTRLA = 0x01; //Prescaler = 8 (0x04)
        RpmTimer.INTCTRLA = 0x03;
    }
    
    void Wait(uint16_t s)
    {
        s*=1000;
        for(s;s>=1;s--)
        {
            _delay_ms(1);
        }
    }
    
    void WaitMs(uint16_t ms)
    {
        for(ms;ms>=1;ms--)
        {
            _delay_ms(1);
        }
    }
    
    void WaitUs(uint16_t us)
    {
        for(us;us>=1;us--)
        {
            _delay_us(1);
        }
    }
    
    void ReadVoltage(void)
    {
        uint16_t VoltageRead;    
        VoltageRead = ADCA.CH0.RES;
        VoltageLp = (VoltageLp*31 + VoltageRead)>>5;
        VoltageV = (VoltageLp * 1165) / 10000;
    }
    
    void ReadCurrent(void)
    {
        uint16_t CurrentRead;
        CurrentRead = ADCA.CH1.RES;
        CurrentLp = (CurrentLp* 31 + CurrentRead)>>5;
        CurrentA = (CurrentLp);
    }
    
    void SendPCUart(char data[], uint8_t crlf)
    {
        char Counter = 0x00;
        char lenght = 0x00;
    
        lenght = strlen(data);
    
        while(Counter < lenght)
        {
            while (!(PCUartPort.STATUS & USART_DREIF_bm));
            PCUartPort.DATA = data[Counter];
            Counter++;
        }
    
        Counter = 0x00;
        if(crlf==1)
        {
            while (!( PCUartPort.STATUS & USART_DREIF_bm));
            PCUartPort.DATA = 0x0D;
            while (!( PCUartPort.STATUS & USART_DREIF_bm));
            PCUartPort.DATA = 0x0A;
        }
    }
    
    void InitClock(void)
    {
        OSC.CTRL |= OSC_RC32MEN_bm;
        while(!(OSC.STATUS & OSC_RC32MRDY_bm));
        CCP = CCP_IOREG_gc;
        CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
    }
    
    void InitPCUart(void)
    {    
        PCUartPinConfig;
        PCUartPort.BAUDCTRLB = 0;
        PCUartPort.BAUDCTRLA = 0x11;
        PCUartPort.CTRLB = USART_TXEN_bm | USART_RXEN_bm;
        PCUartPort.CTRLC = 0x03;
        PCUartPort.CTRLA = 0;
    }
    
    void InitInterrupt(void)
    {
        PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
        sei();
    }
    
    ISR(ACA_AC0_vect)
    {
        //SetPwm = PwmIn;
        KommPinTgl;
        LedGreenTgl;
        //Zustand++;
        //if(Zustand>=7) { Zustand = 1; }
        //ZustandStateMachine();
        //ClearAcIntFlag; 
        WaitMs(100);
    }
    Wenn jemand ne Idee hat, was man testen könnte, wäre ich sehr dankbar!

    Gruß
    Chris

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    Hi,

    also ich den "Fehler" wohl jetzt gefunden:
    Es ist das Fehlen / Auskommentiertsein der Timer-ISR?! Sobald diese im Programm steht (aber auch leer!), funktioniert der Komperator.
    Kann mir das jemand erklären? Hab ich was verpasst?

    Gruß
    Chris

    EDIT:
    Vielen Dank an einen freundlichen User, er hat mir die Lösung per PN zukommen lassen. Es ist wohl in der Tat so, dass ein konfigurierter Timer ohne entsprechend definierte ISR einen Reset auslösen kann / wird.
    Geändert von Che Guevara (06.02.2014 um 17:56 Uhr)

Ähnliche Themen

  1. Software UART Interrupt löst immer zweimal aus
    Von sledge77 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 25.05.2012, 23:30
  2. Interrupt löst Reset aus
    Von max! im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 19.09.2010, 19:30
  3. Interrupt löst nicht zuverlässig aus
    Von Kagerer im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 26.05.2008, 14:06
  4. Ext. Interrupt löst nur unregelmässig aus
    Von Murus im Forum AVR Hardwarethemen
    Antworten: 27
    Letzter Beitrag: 08.01.2007, 18:34
  5. Timer0 Overflow Interrupt löst nicht aus (ATmega16)
    Von schamp im Forum C - Programmierung (GCC u.a.)
    Antworten: 149
    Letzter Beitrag: 06.06.2005, 12:46

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •