www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupts funktionieren nicht.


Autor: Stefan G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich programmiere gerade eine PI Regelung, bei der innerhalb der 
Interrupt Service Routine die Regelroutine abgearbeitet werden soll. Da 
das ganze bisher noch garnicht funktioniert, habe ich einfach mal zu 
Beginn der ISR versucht, die LED´s meines STK500 Boards aufleuchten zu 
lassen, um zu sehen ob überhaupt Interupts ausgelöst werden. Dabei habe 
ich festgestellt, daß dies offenbar nicht der Fall ist. Ich werde hier 
gleich mal den (etwas langen - sorry) Programmcode posten. Das Register 
TCCR0 (verantwortlich für Clock value) ist zuerst auf x00 gesetzt, d.h. 
der Timer ist aus. Erst nachdem ein Zeichen über den Terminal gelesen 
wurde, wird das Register auf x06 gesetzt, was dann einer Frequenz von 
14,4 kHz entspricht. Hat jemand von euch eine Idee, warum garkeine 
Interrupts ausgelöst werden? Ich benutze einen ATmega323 und 
CodevisionAVR.

Hier der Code:

#include <mega323.h>

// Standard Input/Output functions
#include <stdio.h>
#include <stdlib.h>


#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSR|=0x40;
// Wait for the AD conversion to complete
while ((ADCSR & 0x10)==0);
ADCSR|=0x10;
return ADCW;
}

float v_ist;
float e_k;    // Regeldifferenz
float e_k_alt;
float k_p = 1.446;  // Verstärkungsfaktor
float t_i = 0.007343;  // Verzugszeit
float t_0 = 0.017708;  // Abtastzeit
float u_k;        // Stellgröße
float u_k_alt;
int v_soll;
int stell;


// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  // Falls Interrupt ausgelöst wird, LED´s (-> PORTC) anschalten:
  PORTC = 1;

  // aktuelle Spannung berechnen:
  v_ist = (5.0/1023)*read_adc(0);

  // Regelabweichung e_k berechnen:
   e_k = v_soll - v_ist;

    // Stellgröße u_k berechnen:
     u_k = u_k_alt + k_p*(e_k*(1+t_0/t_i)-e_k_alt);

      // Stellgrößenbegrenzung:
       if (u_k > 5.0) u_k = 5.0;
       else if (u_k < 0.0) u_k = 0.0;

       // Stellgröße in entsprechenden PWM Wert umrechnen:
       stell = (int) (u_k*255/5.0);

       // Pulsbreite setzen:
       OCR0 = stell;

       u_k_alt = u_k;
       e_k_alt = e_k;
}


void main(void)
{


// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In 
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T 
State7=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func0=In Func1=In Func2=In Func3=Out Func4=In Func5=In Func6=In 
Func7=In
// State0=T State1=T State2=T State3=1 State4=T State5=T State6=T 
State7=T
PORTB=0x08;
DDRB=0x08;

// Port C initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out 
Func7=Out
// State0=1 State1=1 State2=1 State3=1 State4=1 State5=1 State6=1 
State7=1
PORTC=0xFF;
DDRC=0xFF;

// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In 
Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T 
State7=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 460,800 kHz
// Mode: Phase correct PWM top=FFh
// OC0 output: Non-Inverted PWM
TCCR0=0x62;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: TCCR2=0x07: 3600 Hz  -> t_0 = 1/(3600/255) = 70.83 ms
//    TCCR2=0x06; 14400 Hz -> t_0 = 1/(14400/255) = 17,708 ms
//    TCCR2=0x05; 28800 Hz -> t_0 = 1/(28800/255) = 8,85 ms
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 115200
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 115,200 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSR=0x85;

// Global enable interrupts
#asm("sei")


// Sollspannung über Terminal einlesen:
v_soll = (int) getchar()-48;

// Timer loslaufen lassen:
TCCR2=0x06;
}

Autor: Gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

ich hab zwar noch nicht soviel Ahnung und programmiere auch in Assembler 
aber hast du Global Interrupt enable ausgeführt.
Andernfalls passiert nichts bei einem Interrupt.

Grüße Gerd

Autor: Clemens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wie ich sehe hast du das mit Codevision programmiert. Du hast aber 
einen fehler bei der

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

gemacht.

das müsste denke ich mal

TIMSK=0x40;

heißen.

Mfg Clemens

Autor: Stefan G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gerd und Colemens,
verdammt, es lag tatsächlich an dem TIMSK bzw. dem TOIE2 (Timer/Counter2 
Overflow Interrupt Enable) Register. Tausend Dank, nun weiß ich 
zumindest daß die Interrupts funktionieren und kann mich wieder dem 
eigentlichen Problem, der PI-Regelung widmen :-)

Grüße und nochmals Danke,
Stefan

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.