- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 8 von 8

Thema: Interrupt löst nicht zuverlässig aus

  1. #1
    Kagerer
    Gast

    Interrupt löst nicht zuverlässig aus

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,
    ich hab ein Problem mit dem Interrupt an einem ATMega16. Und zwar hab ich einen Taster an Int0 angeschlossen. Der Controller löst aber nicht zuverlässig die Interrupt-Routine aus, wenn ich den Taster betätige.
    Hier mal der Code:
    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h> 
    
    // Ports initialisieren
    void port_init()
    {
    	// Alle Pins  bis auf PD2 & PD3 als Ausgang schalten
    	DDRA = 0xff;
    	DDRB = 0xff;
    	DDRC = 0xff;
    	DDRD = 0b11110011;
    	
    	//Pullup-Widerstand von PD2 aktivieren
    	PORTD |= (1<<PD2);
    	
    	// Interrupt vorbereiten
    	MCUCR |= (1 << ISC01); // INT0 läst bei fallender Flanke aus
    	GICR |= (1 << INT0); // INT0 aktivieren
    }
    
    // Funktion zum Einschalten der LEDs
    void led_on(uint8_t led)
    {
    	if(led == 1) PORTA |= (1 << PA3);
    	if(led == 2) PORTB |= (1 << PB4);
    	if(led == 3) PORTA |= (1 << PA2);
    	if(led == 4) PORTD |= (1 << PD0);
    	if(led == 5) PORTC |= (1 << PC5);
    	if(led == 6) PORTB |= (1 << PB7);
    	if(led == 7) PORTC |= (1 << PC6);
    	if(led == 8) PORTB |= (1 << PB6);
    	if(led == 9) PORTC |= (1 << PC7);
    	if(led == 10) PORTB |= (1 << PB5);
    	if(led == 11) PORTA |= (1 << PA5);
    	if(led == 12) PORTA |= (1 << PA4);
    	if(led == 13) PORTB |= (1 << PB3);
    	if(led == 14) PORTA |= (1 << PA1);
    	if(led == 15) PORTB |= (1 << PB2);
    	if(led == 16) PORTA |= (1 << PA7);
    	if(led == 17) PORTB |= (1 << PB1);
    	if(led == 18) PORTA |= (1 << PA6);
    	if(led == 19) PORTB |= (1 << PB0);
    	if(led == 20) PORTA |= (1 << PA0);
    	if(led == 21) PORTD |= (1 << PD6);
    	if(led == 22) PORTC |= (1 << PC0);
    	if(led == 23) PORTD |= (1 << PD7);
    	if(led == 24) PORTC |= (1 << PC4);
    	if(led == 25) PORTD |= (1 << PD1);
    	if(led == 26) PORTC |= (1 << PC3);
    	if(led == 27) PORTD |= (1 << PD4);
    	if(led == 28) PORTC |= (1 << PC2);
    	if(led == 29) PORTD |= (1 << PD5);
    	if(led == 30) PORTC |= (1 << PC1);
    }
    
    // Funktion zum Ausschalten der LEDs
    void led_off(uint8_t led)
    {
    	if(led == 1) PORTA &= ~(1 << PA3);
    	if(led == 2) PORTB &= ~(1 << PB4);
    	if(led == 3) PORTA &= ~(1 << PA2);
    	if(led == 4) PORTD &= ~(1 << PD0);
    	if(led == 5) PORTC &= ~(1 << PC5);
    	if(led == 6) PORTB &= ~(1 << PB7);
    	if(led == 7) PORTC &= ~(1 << PC6);
    	if(led == 8) PORTB &= ~(1 << PB6);
    	if(led == 9) PORTC &= ~(1 << PC7);
    	if(led == 10) PORTB &= ~(1 << PB5);
    	if(led == 11) PORTA &= ~(1 << PA5);
    	if(led == 12) PORTA &= ~(1 << PA4);
    	if(led == 13) PORTB &= ~(1 << PB3);
    	if(led == 14) PORTA &= ~(1 << PA1);
    	if(led == 15) PORTB &= ~(1 << PB2);
    	if(led == 16) PORTA &= ~(1 << PA7);
    	if(led == 17) PORTB &= ~(1 << PB1);
    	if(led == 18) PORTA &= ~(1 << PA6);
    	if(led == 19) PORTB &= ~(1 << PB0);
    	if(led == 20) PORTA &= ~(1 << PA0);
    	if(led == 21) PORTD &= ~(1 << PD6);
    	if(led == 22) PORTC &= ~(1 << PC0);
    	if(led == 23) PORTD &= ~(1 << PD7);
    	if(led == 24) PORTC &= ~(1 << PC4);
    	if(led == 25) PORTD &= ~(1 << PD1);
    	if(led == 26) PORTC &= ~(1 << PC3);
    	if(led == 27) PORTD &= ~(1 << PD4);
    	if(led == 28) PORTC &= ~(1 << PC2);
    	if(led == 29) PORTD &= ~(1 << PD5);
    	if(led == 30) PORTC &= ~(1 << PC1);
    }
    
    // Programmcounter
    volatile uint8_t progcounter = 0;
    
    // INT0
    ISR(INT0_vect) {
        if(progcounter < 3) progcounter++;
    	else progcounter = 1;
    }
    
    // Hauptprogramm
    int main()
    {
    	// Ports initialisieren
    	port_init();
    	
    	// Interrupts global aktivieren
    	sei();
    	
    	// Endlosschleife
    	while(1){
    	if(progcounter == 1) led_on(30);
    	if(progcounter == 2) led_off(30);
    	}
    return(0);
    }
    Ich hoffe, dass mir jemand bei meinem Problem weiterhelfen kann.

    MfG
    Christian

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    Der Controller löst aber nicht zuverlässig die Interrupt-Routine
    meinst du, das er manchmal reagiert und manchmal nicht ?

    ein taster prellt meist, kann doch sein das du 2, 4, 6, 8 oder ein höheres vielfaches von 2 lowflanken hast während du auf den taster drückst.

    versuche mal statt auf eine flanke zu warten auf ein level zu warten, das könnte ETWAS stabiler sein, ansonsten den taster entprellen

    EDIT: wenn du 2 - 8 Flanken hast musst du nicht unbedingt das superkurze flackern der LED bemerken, dazu ist der sehsinn meist zu langsam

    EDITEDIT inkrementier bei jedem interrupt doch ... kA das PORTA Register

    also

    Code:
    ISR()
    {
      PORTA++;
    }
    dann kannst du mitzählen wie oft die ISR aufgerufen wird bis zu 255 mal ^^

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Vermutlich gehen die IRQs, aber wegen fehlender Entprellung des Tasters werden mehr als 1 Flanke pro Druck ausgelöst.

    Zudem fehlt ein Teil der Initialisierung, weil du zB mit
    Code:
    MCUCR |= (1 << ISC01);
    nur 1 Bit auf 1 setzt (es muss noch ein Bit auf 0 gesetzt werden). Weiß jetzt net, wie das SFR beim Reset initialisiert wird, aber sauber ist sowas net.
    Disclaimer: none. Sue me.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    statt zu ODERN würd ich auch an deiner stelle das gesammte register in einem zug programmieren, sonst löst dein ISR eventuell zu früh aus wenn du mehrere operationen hintereinander ausführst, dann musst du das ISC00 nicht nachträglich auf 0 schreiben, da muss ich sprinter zustimmen

  5. #5
    Kagerer
    Gast
    Erst mal danke für eure schnellen Antworten.

    Zitat Zitat von Ceos
    meinst du, das er manchmal reagiert und manchmal nicht ?
    Ja genau.


    Zitat Zitat von Ceos
    ein taster prellt meist
    Ich hab parallel zum Taster einen 47nF Kondensator geschalten der sollte doch eigenltich reichen um das Prellen zu verhindern. Hab ich nur vergessen zum schreiben.


    Zitat Zitat von SprinterSB
    Zudem fehlt ein Teil der Initialisierung
    Werd ich dann gleich mal auf "MCUCR = 0b00000010;" ausbessern.

  6. #6
    Kagerer
    Gast
    Also ich hab es jetzt mit den Interrupts aufgegeben. Ich frag den Taster nun mittels Polling ab und das funktioniert wie gewünscht.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    interrupts kann man doch auch auf PEGEL einstellen also nicht reagieren auf flanke sonder wenn ein bestimmter PEGEL anliegt, versuchs damit mal!

  8. #8
    Kagerer
    Gast
    Habe ich schon versucht. Brachte aber keine Verbesserung.

Berechtigungen

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

Solar Speicher und Akkus Tests