Interrupts funktionieren nicht.

Gast #32667
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;
}
Gast #32668
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
Gast #32669
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
Gast #32670
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

Eine eigene Frage? Dieser Thread ist über 23 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.