-         
Seite 1 von 6 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 59

Thema: Interrupt-Abfrage >>> Routine vereinfachen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    07.06.2019
    Beiträge
    66

    Interrupt-Abfrage >>> Routine vereinfachen

    Anzeige

    Hallo.
    Für ein aktuelles Projekt möchte ich 4 Kontakte; PA2, PA3, PA4, PA5 ständig auf steigende und fallende Flanken abfragen.

    Im folgenden Bsp habe ich das mit einer Taste durchgefüht. Gibt es eine einfachere Möglichkeit als alles mal 4 zu schreiben?
    Code:
    ISR (PCINT0_vect) // Interrupt, ABFRAGE, aus Bank0, wird ausgelöst
    {
    	if ((PINA & (1<<PINA2)) != 0)	// Taster=1
    	{
    		// hier kommt eine Entprellung rein
                    ResetTaste_on();
    	}
    	if ((PINA & (1<<PINA2)) == 0) // Taster=0
    	{
    		// hier kommt eine Entprellung rein
                    ResetTaste_off();
    	}
    }
    Als Präprozessor-Makro habe ich die Kontakte folgend vereinfacht. Ich würde diese Vereinfachung irgend in die Kontakt-Abfrage einbauen - aber wie?
    Code:
    #define RESET (PINA, PA2)
    //usw...
    __________________________________________________ _____________________________
    | Sprache: C | AtmelStudio 7.x | Atmel-ICE | Favorit-uC: ATtiny84 | Status: Anfänger |

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    34
    Beiträge
    3.333
    spricht was dagegen eine

    "handleInterrupt(uint8_t src)"

    methode zu schreiben und für jeden dieser vektoren einen einfachen 3 zeiler zu schreiben um die methode entsprechend aufzurufen?!

    alternativ könntest du auch alle interrupts manuell auf die gleiche methode zeigen lassen und über das interrupt register auslesen welcher interrupt ausgelöst hat (das ist die standard methode für ARM controller, 1 interrupt handler für x interrupts)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    07.06.2019
    Beiträge
    66
    Zitat Zitat von Ceos Beitrag anzeigen
    "handleInterrupt(uint8_t src)"
    methode zu schreiben und für jeden dieser vektoren einen einfachen 3 zeiler zu schreiben um die methode entsprechend aufzurufen?!
    Meinst du einen rotierende Abfrage über einen Timer?
    Wie genau sollte die aussehen?
    Grundsätzlich bin ich froh, mit der Bank-Abfrage zurecht zu kommen. Aber für jede Vereinfachung bin ich natürlich dankbar

    Zitat Zitat von Ceos Beitrag anzeigen
    alternativ könntest du auch alle interrupts manuell auf die gleiche methode zeigen lassen und über das interrupt register auslesen welcher interrupt ausgelöst hat (das ist die standard methode für ARM controller, 1 interrupt handler für x interrupts)
    Du meinst, wie ich es geschrieben habe, für jeden Kontakt jeweils 2 if-Anweisungen?
    __________________________________________________ _____________________________
    | Sprache: C | AtmelStudio 7.x | Atmel-ICE | Favorit-uC: ATtiny84 | Status: Anfänger |

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    34
    Beiträge
    3.333
    soweit ich dich verstnaden habe ist der code ein beispiel für einen einzelnen ISR, den du aber für 4 ISRs gerne hättest

    du kannst jetzt einfach folgendes machen:

    Code:
    void handleISR(uint8_t src)
    {
       ... anhand von src einfach entscheiden was zu tun ist
    }
    
    ISR (vector1)
    {
       handleISR(1);
    }
    
    ISR (vector2)
    {
       handleISR(2);
    }
    
    usw...
    oder wenn du dich traust kannst du deine Vektortabelle einfach selber basteln und alle ISR vektoren auf die gleiche methode zeigen lassen und dann entweder aus dem Interrupt Flag REgister lesenw elcher interrupt es nun war oder einfach alle deine Taster wie im Beispiel abfragen egal welcher interrupt ausgelöst hat.

    Mein Hintergedanke hier ist die effizienz, wenn alle Vektoren auf die gleiche Methode zeigen sparst du dir eine Runde Stack Push/Pop und den MEthodenaufruf der handleISR(uint8_t src) was bei gaaaanz schnellen applikationen bedeutsam sein kann aber meistens völlig überzogen ist ^^

    bei ARM controllern gibt es meistens nicht genug vektoren für alle interrupts und dort werden i.d.R. die vektoren zusammengefast und nur ein handler aufgerufen, in welchem du dann über die interrupt flag register die quelle ausfindig machen musst
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    07.06.2019
    Beiträge
    66
    Zitat Zitat von Ceos Beitrag anzeigen
    Mein Hintergedanke hier ist die effizienz, wenn alle Vektoren auf die gleiche Methode zeigen sparst du dir eine Runde Stack Push/Pop und den MEthodenaufruf der handleISR(uint8_t src) was bei gaaaanz schnellen applikationen bedeutsam sein kann
    Tatsächlich gehts bei mir nicht um "Leben oder Tot" im us-Takt. Bei Geschwindigkeiten denke ich auf ms-Niveau.
    Mir geht es vielmehr darum, einen sicheren einfachen Code zu schreiben, den ich nach einer Monats-Pause immer noch verstehe.

    Zitat Zitat von Ceos Beitrag anzeigen
    bei ARM controllern gibt es meistens nicht genug vektoren für alle interrupts und dort werden i.d.R. die vektoren zusammengefast und nur ein handler aufgerufen, in welchem du dann über die interrupt flag register die quelle ausfindig machen muss
    Der ATtiny84 ist bei seiner Interruptvielfalt äußerst überschaubar.

    Vielleicht ist die folgenden Routine auch völlig ok und kein bischen zu aufgebläht?
    Code:
    ISR (PCINT0_vect) // Interrupt, ABFRAGE, aus Bank0, wird ausgelöst
    {
    if ((PINA & (1<<PINA2)) != 0)	// Taster "Reset" =1
    {
      // hier kommt eine Entprellung rein
       ResetTaste_on();
    }
      if ((PINA & (1<<PINA2)) == 0) // Taster "Reset" =0
      {
    // hier kommt eine Entprellung rein
    ResetTaste_off();
    }
      if ((PINA & (1<PINA3)) != 0)
      //usw.
      //bis alle 4 Taster/Kontakte nach einem Interrupt auf hi/low abgefragt sind
    
    }
    __________________________________________________ _____________________________
    | Sprache: C | AtmelStudio 7.x | Atmel-ICE | Favorit-uC: ATtiny84 | Status: Anfänger |

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    34
    Beiträge
    3.333
    Das Problem ist hier aber, dass du beim Auslösen von PC4 keinen PCINT0 bekommst und deshalb das Drücken verpasst!

    Darum sage ich ja dass du schon wie üblich alle 4 PCINT ISRs schreiben musst aber statt deine Abfrage 4 mal ähnlich zu kopieren in den ISRs jeweils einfach eine Methode aufrufst (wie im Codebeispiel) in welcher du deine PIN Register, das Interrupt Register oder eine Variable als Indikator dazu benutzt um zu erfahren, welcher Input getriggert worden ist.

    die Lösung über Makro geht natürlich auch, einfch den code als reines Makro mit Platzhalter schreiben um die richtige Pin Zuordnung und die richtige Reaktion zu bekommen.
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    07.06.2019
    Beiträge
    66
    Zitat Zitat von Ceos Beitrag anzeigen
    Das Problem ist hier aber, dass du beim Auslösen von PC4 keinen PCINT0 bekommst und deshalb das Drücken verpasst!
    Der ATtiny84 hat nur 2 Bänke; Bank0 mit 8* PAs und Bank1 mit 4* PBs. Zufällig liegen meine 4 Taster/Kontakte in Bank0.

    Zitat Zitat von Ceos Beitrag anzeigen
    Darum sage ich ja dass du schon wie üblich alle 4 PCINT ISRs schreiben musst aber statt deine Abfrage 4 mal ähnlich zu kopieren in den ISRs jeweils einfach eine Methode aufrufst (wie im Codebeispiel) in welcher du deine PIN Register, das Interrupt Register oder eine Variable als Indikator dazu benutzt um zu erfahren, welcher Input getriggert worden ist.
    Kannst du mir bitte zur Verdeutlichung einen Bsp-Code schreiben?

    Zitat Zitat von Ceos Beitrag anzeigen
    die Lösung über Makro geht natürlich auch, einfch den code als reines Makro mit Platzhalter schreiben um die richtige Pin Zuordnung und die richtige Reaktion zu bekommen.
    Kannst du mir bitte zur Verdeutlichung einen Bsp-Code schreiben?

    - - - Aktualisiert - - -

    Was hälst du von folgender Idee;

    1. direkt das ganze Register PINA auslesen und in eine Register-Variable (volatiles) speichern.
    2. sobald ein ISR(PCINT0_vect) kommt, mit der Reg-Var vergleichen.
    3. das veränderte Bit als PAx auslesen, entprellen und auf 0/1 überprüfen

    ?

    - - - Aktualisiert - - -

    DENKFEHLER!
    In dem Register sind Ein- und Ausgänge.
    Somit könnte ich zwar das ganze Register auf ein mal speichern, aber Bit-Veränderungen nur bei meinen 4 PA-Eingängen durchführen. (?)

    - - - Aktualisiert - - -

    Was hälst du von folgendem Lösungsansatz?

    Code:
    volatile uint8_t RegisterA = PINA;
    
    ISR (PCINT0_vect)					// Interrupt, ABFRAGE, aus Bank0, wird ausgelöst
    {
    	if(RegisterA & (1<<PINA2)) != 0)		// auf Zustandveränderung PA2/RESET abfragen
    	{
    		switch (Reset_Status())		// "Reset" entprellen // return 0=low, 1=high
    		{
    			case 0: RegisterA=PINA;	Reset_off();	break;  // Reset wird ausgeführt
    			case 1: RegisterA=PINA;	Reset_on();	break;  // Reset wird nicht ausgeführt
    		}
    	}
     
          // solch eine Abfrage noch für PA3, PA4, PA5 hintereinander gehangen
    }
    __________________________________________________ _____________________________
    | Sprache: C | AtmelStudio 7.x | Atmel-ICE | Favorit-uC: ATtiny84 | Status: Anfänger |

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    34
    Beiträge
    3.333
    oh okay, das sind bank interrupts, das manual was ich hatte war wohl für einen größeren Tiny, da waren das ganze einzelne pin interrupts (war ich auch von den noch größeren atmegas so gewohnt)

    sorry

    ich weis jetzt nicht genau was hinter Reset_Status steckt, aber solange ein mehrfachen aufrufen kein Probblem ist wäre das eine Lösung

    du könntest das Ergebnis in eine Variable packen und dann die Variable in den if's abfragen wenn der mehrfache Aufruf ein Problem ist
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    07.06.2019
    Beiträge
    66
    Zitat Zitat von Ceos Beitrag anzeigen
    oh okay, das sind bank interrupts, das manual was ich hatte war wohl für einen größeren Tiny, da waren das ganze einzelne pin interrupts (war ich auch von den noch größeren atmegas so gewohnt)
    Bis auf die Interrupt-Vielfalt ist der kleine ATtiny84 sehr angenehm zu verarbeiten.

    Zitat Zitat von Ceos Beitrag anzeigen
    ich weis jetzt nicht genau was hinter Reset_Status steckt, aber solange ein mehrfachen aufrufen kein Probblem ist wäre das eine Lösung
    Reset_Status() entprellt (ohne _delay_ms()) einen Kontakt und gibt als steigende Flanke eine 1 und als fallende Flanke eine 0 zurück.
    In meinem Bsp wird erst einmal das "alte" Register nach Veränderung ausgewertet und "nur" der veränderte Kontakt entprellt und verarbeitet.
    Hoffentlich bin ich hier nicht auf dem Holzweg.

    Zitat Zitat von Ceos Beitrag anzeigen
    du könntest das Ergebnis in eine Variable packen und dann die Variable in den if's abfragen wenn der mehrfache Aufruf ein Problem ist
    Klinkt nach Vereinfachung
    Kannst du mir bitte ein Bsp-Code schicken der deine Idee verdeutlicht?
    __________________________________________________ _____________________________
    | Sprache: C | AtmelStudio 7.x | Atmel-ICE | Favorit-uC: ATtiny84 | Status: Anfänger |

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    34
    Beiträge
    3.333
    Code:
    volatile uint8_t RegisterA = PINA;
    
    ISR (PCINT0_vect)					// Interrupt, ABFRAGE, aus Bank0, wird ausgelöst
    {
            uint8_t resetVal = Reset_Status();
    	if(RegisterA & (1<<PINA2)) != 0)		// auf Zustandveränderung PA2/RESET abfragen
    	{
    		switch (resetVal)		// "Reset" entprellen // return 0=low, 1=high
    		{
    			case 0: RegisterA=PINA;	Reset_off();	break;  // Reset wird ausgeführt
    			case 1: RegisterA=PINA;	Reset_on();	break;  // Reset wird nicht ausgeführt
    		}
    	}
    	if(RegisterA & (1<<PINA3)) != 0)		// auf Zustandveränderung PA3/RESET abfragen
    	{
    		switch (resetVal)		// "Reset" entprellen // return 0=low, 1=high
    		{
    			case 0: RegisterA=PINA;	Reset_off();	break;  // Reset wird ausgeführt
    			case 1: RegisterA=PINA;	Reset_on();	break;  // Reset wird nicht ausgeführt
    		}
    	}
     
          // solch eine Abfrage noch für PA4, PA5 hintereinander gehangen
    }
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

Seite 1 von 6 123 ... LetzteLetzte

Ähnliche Themen

  1. [ERLEDIGT] Interrupt Routine
    Von Saturas077 im Forum Assembler-Programmierung
    Antworten: 8
    Letzter Beitrag: 23.04.2014, 12:46
  2. Codebeispiel für Lesen von RC5 Code mit Interrupt-Routine
    Von -tomas- im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 19
    Letzter Beitrag: 25.05.2011, 12:54
  3. Interrupt Routine
    Von luvat im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 4
    Letzter Beitrag: 16.03.2008, 20:54
  4. Interrupt in ISR-Routine freigeben
    Von dj5am im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 10.08.2007, 08:44
  5. uart interrupt routine
    Von Computerkora im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 25.11.2006, 13:45

Berechtigungen

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