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; }
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
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
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.