www.mikrocontroller.net

Forum: Compiler & IDEs Zusammenfassen von 3 externen Interrupts?


Autor: H. G. (ledi)
Datum:
Angehängte Dateien:
  • preview image for C0.PNG
    C0.PNG
    2,94 KB, 133 Downloads
  • preview image for C1.PNG
    C1.PNG
    7,64 KB, 164 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich programmiere gerade eine Anwendung, bei der ich eine 
3x4-Tastenmatrix auf wert = 1 bis 12 abfrage.

Im Hauptprogramm stehen die Initialisierungen und die Endlosschleife.

Sobald eine Taste gedrückt wird soll der Prozessor aufwachen, die Taste 
die gedrückt wurde feststellen und dann entsprechend eine Aktion 
ausführen.

Da ich jede Spalte der Tastenmatrix auf einen ext. Interruptpin des 
Prozessors (ATMEL 90PWM316) hänge, möchte ich den Programmteil der 
Abfrage usw. nur einmal verwenden.

Meine Frage:
Geht das? Kann ich die Interrupts vor Beginn der Tastenabfrage 
zusammenfassen, oder muss ich das gleiche Programm in jede einzelne 
Interruptroutine einbinden?

Oder gibt es hier vielleicht generell eine bessere Lösung?

Im Anhang das Struktogramm des Hauptprogrammes sowie der Interrupts.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heimo G. schrieb:

> Sobald eine Taste gedrückt wird soll der Prozessor aufwachen, die Taste
> die gedrückt wurde feststellen und dann entsprechend eine Aktion
> ausführen.
>
> Da ich jede Spalte der Tastenmatrix auf einen ext. Interruptpin des
> Prozessors (ATMEL 90PWM316) hänge, möchte ich den Programmteil der
> Abfrage usw. nur einmal verwenden.

Keine gute Idee.
Tasten wertet man grundsätzlich nicht mittels Interrupt aus, sondern 
indem man die Tasten ein paar mal pollt. Damit wird man dann auch das 
Tastenprellen los.

Wenn der Prozessor durch Tastendruck aufwachen soll, dann hängt man die 
Tasten elektrisch auf einen einzigen INterrupteingang. Kommt dort ein 
Interrupt wacht der Prozessor auf und beginnt damit die Tastatur mittels 
Pollen abzuscannen.

> Meine Frage:
> Geht das? Kann ich die Interrupts vor Beginn der Tastenabfrage
> zusammenfassen, oder muss ich das gleiche Programm in jede einzelne
> Interruptroutine einbinden?

Es steht dir natürlich frei aus einer ISR eine Funktion aufzurufen.
Das kann natürlich aus 3 verschiedenen ISR immer dieselbe Funktion sein.

Allerdings erhebt sich die Frage, warum du dann nicht gleich elektrisch 
dafür sorgst, dass bei jeglichem Tastendruck immer derselbe INterrupt 
ausgelöst wird und daher von Haus aus nur 1 ISR notwendig ist.

Autor: Hauke C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich mich recht erinner gibts bei manchen anderen µC's von Atmel 
auch die Option "Pin Change Interrupt", der wird dann bei auslösen von 
einem der betroffenen Eingänge ausgelöst. Ansonsten: In den Routinen 
eine Bearbeitungsroutine aufrufen.

Mfg Hauke

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn der Prozessor durch Tastendruck aufwachen soll, dann hängt man die
> Tasten elektrisch auf einen einzigen INterrupteingang. Kommt dort ein
> Interrupt wacht der Prozessor auf und beginnt damit die Tastatur mittels
> Pollen abzuscannen.

Wie hänge ich die Tasten el. auf einen Interrupt?

Wenn ich z.B. ein Oder-Gatter verwende, kann ich ja die Tasten nicht 
mehr abfragen. Oder?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heimo G. schrieb:
> Meine Frage:
> Geht das? Kann ich die Interrupts vor Beginn der Tastenabfrage
> zusammenfassen, oder muss ich das gleiche Programm in jede einzelne
> Interruptroutine einbinden?

Unabhängig davon, ob das für deine Anwendung sinnvoll ist, geht das.

Sofern du avr-gcc benutzt:

http://www.nongnu.org/avr-libc/user-manual/group__...

Oliver

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Heimo G. schrieb:
>> Meine Frage:
>> Geht das? Kann ich die Interrupts vor Beginn der Tastenabfrage
>> zusammenfassen, oder muss ich das gleiche Programm in jede einzelne
>> Interruptroutine einbinden?
>
> Unabhängig davon, ob das für deine Anwendung sinnvoll ist, geht das.
>
> Sofern du avr-gcc benutzt:
>
> 
http://www.nongnu.org/avr-libc/user-manual/group__...
>
> Oliver

Kannst u mir hier ein Codebeispiel geben?
Z.B. mit 2 Interrupts?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Allerdings erhebt sich die Frage, warum du dann nicht gleich elektrisch
> dafür sorgst, dass bei jeglichem Tastendruck immer derselbe INterrupt
> ausgelöst wird und daher von Haus aus nur 1 ISR notwendig ist.

Wozu unnütz Hardware verschwenden?

Da dieser AVR keinen Pin-Change-Int hat, muß man die 3 externen Ints zum 
Aufwachen nehmen.
Und mit ISR_ALIASOF() kann man mehrere Vektoren auf denselben Handler 
hinbiegen.

Ich würds allerdings so machen, daß nur eine Taste (ON/OFF) zum 
Aufwachen freigegeben ist. Dann kann man nicht versehentlich ne 
Betätigung auslösen.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.:

Wenn ich das Bild richtig verstehe, handelt es sich nicht um 
Batteriebetrieb und es muß eine PWM aktiv sein.
D.h. Tiefschlaf ist weder nötig noch möglich.

Damit ist Idle-Mode und Abfrage im Timerinterrupt (~10ms) die einfachste 
und sicherste Lösung.


Peter

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heimo G. schrieb:
> Kannst u mir hier ein Codebeispiel geben?
> Z.B. mit 2 Interrupts?

Selber link, weiter oben.

Oliver

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Heimo G. schrieb:
>> Kannst u mir hier ein Codebeispiel geben?
>> Z.B. mit 2 Interrupts?
>
> Selber link, weiter oben.
>
> Oliver

Danke!

Ich hab das jetzt versucht.
Fehlermeldung erhalte ich keine, aber ich erkenne keinen Unterschied zu 
vorher!

Anbei der C-Code:
/****************************************************************
* TASTATURMATRIX - Interrupt                  *
* Funktion:    Auslösen eines Interrupts (Int.0,1,2) über eine *
*        3x4 Tastenmatrix und toggeln einer LED am PORTC *
* Portanschlüsse der Tastenmatrix:                *
*         Spalten:  PD6, PB2, PB5            *
*         Zeilen:    PB4, PB3, PB1, PB0          *
* Controller:   ATMEL 90PWM316, Oszillator intern 8MHz      *
****************************************************************/

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define ISR_ALIAS(INT1_vect, INT0_vect)

int main (void)
{
  DDRC    =   0x0F;          // PORTC = Ausgang
  DDRB   =  0xFF;          // PORTB = Ausgang
  PORTB   =  0x00;          // PORTB = low
  DDRB   &=   ~((1<<PB2)|(1<<PB5));  // PB2, PB5 = input
  PORTB   |=    (1<<PB2)|(1<<PB5);  // PB2, PB5 = pull up
  DDRD   &=  ~ (1<<PD6);        // PD6 = input
  PORTD   |=    (1<<PD6);        // PD6 = pull up

  //***** Init Interrupts *****  
  EIMSK |=  (1<<INT0) |  (1<<INT1) |  (1<<INT2);    // Enable Int.0-2
  EICRA |=  (1<<ISC01) | (1<<ISC11) |(1<<ISC21);  // Set Int.0-2 on falling edge
  sei();                        // Enable all Interrupts
      
  while(1)
  {
  }
}

ISR(INT2_vect)          // INT2 on PB5
{    
  PORTC ^=  0x04;           
  _delay_ms(500);  
  EIFR |=  (1<<INTF2);      // Clear Int.-Flag
}

ISR(INT1_vect)          // INT1 on PB2
{
  PORTC ^=  0x02;           
  _delay_ms(500);  
  EIFR |=  (1<<INTF1);      // Clear Int.-Flag  
}

ISR(INT0_vect)          // INT2 on PB5
{
  PORTC ^=  0x01;           
  _delay_ms(500);  
  EIFR |=  (1<<INTF0);      // Clear Int.-Flag
}

ISR_ALIAS (INT1_vect, INT0_vect);











Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schmeiß das define raus, das ist falsch!
Und dann:
ISR(INT0_vect)
{
  PORTC ^=  0x01;
}

ISR( INT1_vect, ISR_ALIASOF(INT0_vect));
ISR( INT2_vect, ISR_ALIASOF(INT0_vect));


Peter

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert PERFEKT!!!

Danke!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.