- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 5 von 5

Thema: ISR Fehlerhaft

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    30.09.2013
    Beiträge
    6

    ISR Fehlerhaft

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusamen,

    ich habe ein Problem mit meiner ISR.
    Ich habe im Wesentlichen ein Programm geschrieben, welches bei Auslösen von Int0 eine Variable incrementiert und bei Auslösen von Int1 diese decrimentiert. Soweit läuft es auch einwandfrei.
    Nun habe ich allerdings den Fehler, dass hin und wieder bei Betätigung von einem der Interrupts anstatt "1" hinzu bzw abgezogen gleich "2" hinzu bzw abgezogen wird.
    In den ISR habe ich bewusst nun eine delaytime von 10000ms eingetragen. Betätige ich den Schließenkontakt nun z.B 5x innerhalb der delaytime, so wird die Variable gleich um "5" verändert. Das möchte ich so natürlich nicht

    Daher meine Frage: Wie kann ich es verhindern, dass die ISR von z.B Int0 wärend Sie ausgeführt wird sich die weiteren Interrupts NICHT merkt und mit verarbeitet?

    P.S.: cli() steht in jeder ISR direkt am Anfang.

    Hier mein Code

    /*
    * Drehkreuz.c
    *
    * Created: 06.01.2014 15:53:43
    * Author: Zille
    */


    #include <avr/io.h>
    #include <avr/interrupt.h> // Einbindungen
    #include <avr/delay.h>
    #include "lcd-routines.h"

    #define F_CPU 8000000 // 8MHz Takt

    volatile float Besucher_gesamt=0; // Speicher kostet ja nichts
    volatile float Besucher_aktuell=0;
    char Ausgabe_aktuell[4]; // Für Ascii umwandlung
    char Ausgabe_gesamt[4];


    int main(void)
    {
    DDRD = 0b00100011; // PD0,1,5-->LEDs PD2,3,4--> Schließerkontakte,tastend

    MCUCR |= 0b00001010; // Flankenauswahl fallende Flanke
    GICR |= 0b11000000; // Int0 und Int1 freischalten
    lcd_init(); // Display initialisieren
    sei(); // Interrupts erlauben


    while(1)
    {

    lcd_clear(); // Display löschen
    dtostrf(Besucher_aktuell,4,0,Ausgabe_aktuell); // Double to String umwandeln --> fürs Display
    lcd_string(Ausgabe_aktuell); // Ausgabe Inhalt Variable
    lcd_string("Besucher");
    lcd_setcursor(0,2); // Eine Zeiler tiefer im LCD springen
    dtostrf(Besucher_gesamt,4,0,Ausgabe_gesamt);
    lcd_string(Ausgabe_gesamt);
    lcd_string("Insgesamt");

    if (bit_is_set(PIND,4)) // Reset Taster

    {
    Besucher_aktuell=0;
    Besucher_gesamt=0;
    }
    _delay_ms(100); // Verzug

    }
    }
    ISR(INT0_vect) //Schaltkontakt für eingehende Besucher
    {
    cli();
    Besucher_aktuell++;
    Besucher_gesamt++;
    PORTD |= (1<<PD5);
    _delay_ms(10000); // Verzugzeit bewusst hoch gewählt um Problem besser darstellen zu können
    PORTD &= ~(1<<PD5);
    sei();
    }

    ISR(INT1_vect) // Schaltkontakt für ausgehende Besucher
    {
    Besucher_aktuell--;
    if (Besucher_aktuell<0)
    {
    Besucher_aktuell=0;
    }

    PORTD |= (1<<PD1);
    _delay_ms(10000); // Verzugzeit bewusst hoch gewählt um Problem besser darstellen zu können
    PORTD &= ~(1<<PD1);
    }
    Danke im Vorraus

    Gruß Zille

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    also zunächst mal würde ich Besucher_aktuell & Besucher_gesamt nicht als float deklarieren. Außerdem würde ich anstatt Besucher_aktuell++; Besucher_aktuell += 1; schreiben.
    Cli() & Sei() kannst du weg lassen, Interrupts werden automatisch in der ISR gesperrt. Hast du die Taster entprellt?
    Du kannst am Ende der ISR das INTX-Flag löschen, so wird kein zweiter Interrupt ausgeführt.

    Gruß
    Chris

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    30.09.2013
    Beiträge
    6
    Hi,

    die taster dürften doch entprellt sein, da die Interrupts bei fallender Flanke ausgelöst werden,oder?
    Das mit dem INTX-Flag werde ich gleich mal ausprobieren.

    Danke für deine Antwort.

    Gruß Zille

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    716
    Hallo Zille,

    die fallende Flanke hat nichts mit entprellen zu tun. Ich denke hier ist dein Problem. Entweder entprellst du per Hardware (z.B. mit Kondensator + Schmitt-Trigger), oder per Software. (z.B. den Interrupt nach Aufruf sperren bis der Eingang xx ms auf high war). Es gibt viele Wege zum entprellen. Ich denke Google wird dich da mit genügend Informationen füttern.

    Das löschen des INTX-Flags in der ISR führt meiner Meinung nach NICHT zum Ziel. So ein Taster prellt üblicherweise öfter als 2x.

    Viele Grüße
    Andreas

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Das Löschen des Flags funktioniert natürlich nur, wenn nachher kein Prellen mehr stattfindet, sonst ist es umsonst.

    Gruß
    Chris

Ähnliche Themen

  1. Spannungsmessung an PortA Fehlerhaft
    Von WDragon91 im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 7
    Letzter Beitrag: 05.01.2011, 19:10
  2. Bascom Download fehlerhaft?
    Von ikarus_177 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 10.10.2008, 13:49
  3. Schaltung fehlerhaft
    Von Atmelbeginne im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 12.09.2008, 17:56
  4. ATMEGA32-Board Fehlerhaft?
    Von Borki90 im Forum AVR Hardwarethemen
    Antworten: 6
    Letzter Beitrag: 30.05.2008, 13:56
  5. Uartausgabe Fehlerhaft
    Von Picht im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 19.02.2007, 17:45

Berechtigungen

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

LiFePO4 Speicher Test