-         

Ergebnis 1 bis 6 von 6

Thema: Interrupt von PWM-Signal

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    24.06.2004
    Ort
    Berlin
    Beiträge
    52

    Interrupt von PWM-Signal

    Anzeige

    Hallo,
    ich möchte einen 40kHz Burst erzeugen. Dazu stelle ich den Oszillator auf ca. 40 kHz und erzeuge einen Interrupt, der dann bis ca. 16 (Perioden) zählt und dann den Oszillator stoppt. Aber irgendwie funzt wieder mal gar nichts.
    Hier ist mein Code:
    Code:
    void _40khz_init (void) {
      DDRB = 0xFF;
      OCR1A = 12; // PWM einstellen, bevor der Timer startet
      OCR1B = 800;
      ICR1 = 25;  // TOP-wert
    
      TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM11); 
      TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS10); 
    }
    SIGNAL (TIM1_OVF) {
      send ("0");
    }
    
    SIGNAL (TIM1_COMPA) {
      send ("1");
    }
    SIGNAL (TIM0_OVF) {
      send  ("2");
    }
    SIGNAL (TIM1_COMPB) {
      send ("3");
    }
    
    int main(){
    
    	_40khz_init();
    	uart_init();
    
    	/*Timer-Interrupt*/
    	TIMSK |= (1 << TOIE0) ;
    
    	sei();//enable Interrupts
      
         for(;;);
    
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.897
    Welcher Controller? Wo ist die Interrupt Routine die den 40kHz Generator stoppt ? Schon über AVR Studio simuliert und debuggt ?

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    24.06.2004
    Ort
    Berlin
    Beiträge
    52
    Also mein Controller ist ein Atmega8.
    Ich habe jetzt versucht innerhalb des Interrupts den Counter auszuschalten und den Interrupt zu löschen:
    Code:
    	TIMSK &= ~(1 << TOIE0);
    	TIMSK &= ~(1 << OCIE1A);
    	TIMSK &= ~(1 << TOIE1);
    	TCCR1A &= ~(1<<COM1A1);
    	TCCR1A &= ~(1<<COM1B1);
    Aber leider funktioniert es nicht.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.897
    @kautz
    Wenn Du den Interrupt nicht löscht, werden dann die 40 kHz dauernd erzeugt ?
    Wird die Interruptroutine tatsächlich angesprungen ?

    Probier das doch mal im AVR Studio 4 aus, dafür ist der Debugger da.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    24.06.2004
    Ort
    Berlin
    Beiträge
    52
    Ja, danke. Ich habe jetzt AVRStudio installiert und debuggt.
    Er springt nicht in den Handler. Der Compiler zeigt mir auch an, dass das Signal "misspelled" ist.
    Aber ich finde keine Konstanten im Interrupt.h. Und wenn ich dort 0x08 reinschreibe, kompiliert er es nicht. Irgendwie schein ich da was nicht zu verstehen.

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    //#include <stdint.h> 
    
    #define F_CPU 1000000
    
    int schalter=0;
    
    void _40khz_init (void) {
    
      DDRB = 0xFF;
    
      OCR1A = 12; // PWM einstellen, bevor der Timer startet
      OCR1B = 800;
      ICR1 = 25;  // TOP-wert
    	// 2-Kanal "non-inverting"
    	// 10-Bit = 2^10 = 1024
      TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM11); // 2-Kanal "non-inverting"
      TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS10); //Fastpwm, mit ICR1 als TOP
    }
    
    SIGNAL (TIMER0_COMPB_vect){
    
    	TIMSK &= ~(1 << TOIE0);
    	TIMSK &= ~(1 << OCIE1A);
    	TIMSK &= ~(1 << TOIE1);
    	TCCR1A &= ~(1<<COM1A1);
    	TCCR1A &= ~(1<<COM1B1); 
    	schalter = 1;
    	
    }
    
    SIGNAL (TIMER0_COMPA_vect){
    	TIMSK &= ~(1 << TOIE0);
    	TIMSK &= ~(1 << OCIE1A);
    	TIMSK &= ~(1 << TOIE1);
    	TCCR1A &= ~(1<<COM1A1);
    	TCCR1A &= ~(1<<COM1B1);
      	schalter = 1;
    }
    
    int main(void)
    {
    	_40khz_init();
    	TIMSK |= (1 << OCIE1B); //|(1<<OCIE1A)|(1<<TOIE1);
    	sei();//enable Interrupts
    	while(1){};
    
    
    }

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.897
    Das Problem ist also, das die Interruptroutine nicht angesprungen wird.
    Ich vermute mal, das Du AVR GCC benutzt.

    Ich hab leider Codevision und da geht die Interruptabarbeitung ein wenig anders.

    Schau mal in die Hilfe deines Compilers unter der Rubrik Interrupts.
    Bei den Meisten Compilern mus eine Interruptroutine mit bestimmten Schlüsselwörtern z.B. "Interrupt Service Routine" oder "_isr..." belegt werden, damit Sie der Compiler auch als Interruptroutinen erkennt und einrichtet.

    Am Schluß muss im Assemblercode, in den entsprechenden Adressen deines Controllers der Einsprungpunkt zum Interrupthandler hinterlegt sein.

    Dann sollte das auch funzen.

    Schau mal diesen Threat http://www.roboternetz.de/phpBB2/viewtopic.php?t=33571
    ( Beispielcode ) Eventuell hilft Dir das dein Problem zu finden.

Berechtigungen

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