Forum: Mikrocontroller und Digitale Elektronik Interrupts mit AT2560 für Tastendruck


von Jochen (Gast)


Lesenswert?

Guten Abend,
eins vorweg: ich habe das Forum ausgiebig nach dem Problem durchsucht. 
Hierbei konnte ich nützliche Tipps zum Abfragen von Interrupts über 
Taster gewinnen. An diesen habe ich auch meinen Code (s.u) orientiert.
Ich benutze das myAVRBoardMK3 mit einem Joystick an PortK (bei 
Betätigung auf Masse) und Port L als Ausgang mit angeschlossenen LEDS. 
Der Controller ist der At2560.
Mit Interrupts versuche ich auf Reaktionen des Joysticks zu reagierten 
und  dann eine LED einzuschalten. Leider ist die Reaktion gleich 0. Was 
ist falsch?
Vielen Dank!
Schöne Grüße, jo
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
int main (void)
5
{
6
  DDRL  |= (1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0);       //Port L Ausgang
7
  DDRK  |= (0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);       //Port K Eingang       
8
   PORTK= 0xFF; // alle Pull-Up Widerstände aktivieren
9
 //Int0 wird bei  fallender Flanke ausgelöst  
10
  MCUCR |=  (1 << ISC01);    
11
   MCUCR &= ~((1 <<ISC00));       
12
 
13
 
14
  sei();
15
while(1)
16
{
17
  
18
 }
19
20
21
22
}
23
ISR(INT0_vect)        
24
{
25
26
    PORTL |= (1<<0);       //PortC.0=1 setzten
27
}

von Peter D. (peda)


Lesenswert?

Jochen schrieb:
> ich habe das Forum ausgiebig nach dem Problem durchsucht.
> Hierbei konnte ich nützliche Tipps zum Abfragen von Interrupts über
> Taster gewinnen.

Dann wundert mich aber sehr, warum Dein Code nicht den dafür üblichen 
Timerinterrupt benutzt.
Oder wolltest Du uns nur zeigen, wie man es nicht machen soll?


Peter

von Jochen (Gast)


Lesenswert?

Hallo Peter,
danke für Deine Antwort. Eine Möglichkeit wurde auf

Beitrag "Interrupt mit atmega8"
diskutiert. An den letzten Post habe ich mein Beispiel angepasst un es 
ist m.E. identisch, funktioniert aber nicht. Was ist daran falsch?

Timerinterrupt? Wird es alles grundsätzlich anders gemacht? Ich kann 
leider kein passendes Bsp. finden, kannst du Stichworte nennen oder kurz 
sagen, was ich anpassen muss?

Schöne Grüße,
jo

von Jochen (Gast)


Lesenswert?

Mit dem Timerrinterrupt schaut man dann alle 2 ms ob eine Taste gedrückt 
wurde? OK ich versuche mich daran, nur warum ist die Lösung oben nicht 
besser, bei der nur etwas getan wird, wenn wirklich ein Tastendruck 
erfolgt? Warum funktioniert sie nicht?

von Uwe (de0508)


Lesenswert?

Die einfachte Antwort ist: Taster prellen!

So bleibt nur eine der beiden Möglichkeiten:

Beitrag "Re: Vorschlag: C-Funktion für Taster-Entprellung"

von Jochen (Gast)


Lesenswert?

Auch bei entprellten Tastern funktioniert es nicht:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define TASTERPORT PINK
4
#define TASTERBIT 0b01000000
5
int zustand=0;
6
int main (void)
7
{
8
  DDRL  |= (1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0);       //Port L Ausgang
9
  DDRK  |= (0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);       //Port K Eingang       
10
   PORTK= 0xFF; // alle Pull-Up Widerstände aktivieren
11
 //Int0 wird bei  fallender Flanke ausgelöst  
12
  MCUCR |=  (1 << ISC01);    
13
   MCUCR &= ~((1 <<ISC00));       
14
15
  sei();
16
while(1)
17
{
18
19
 }
20
21
22
23
}
24
ISR(INT0_vect)        
25
{
26
  
27
  if(zustand == 0 && !(TASTERPORT & (1<<TASTERBIT)))   //Taster wird gedrueckt (steigende Flanke)
28
    {
29
        zustand = 1;
30
            PORTL |= (1<<0);       //PortC.0=1 setzten
31
    }
32
    else if (zustand == 1 && !(TASTERPORT & (1<<TASTERBIT)))   //Taster wird gehalten
33
    {
34
         zustand = 2;
35
          
36
    }
37
    else if (zustand == 2 && (TASTERPORT & (1<<TASTERBIT)))   //Taster wird losgelassen (fallende Flanke)
38
    {
39
        zustand = 3;
40
        
41
    }
42
    else if (zustand == 3 && (TASTERPORT & (1<<TASTERBIT)))   //Taster losgelassen
43
    {
44
        zustand = 0;
45
        
46
    }
47
48
49
}

Die LED leuchtet beim Drücken des Tasters nicht, bzw [c]PORTL |= (1<<0); 
/[c] wird nicht ausgeführt. Habt ihr noch eine Idee?

von Jochen (Gast)


Lesenswert?

Die Zeile
 GICR  = 0b01000000;        //Int0 aktivieren

habe ich ausgelassen, weil GICR nicht gefunden werden konnte. 
Möglicherweise liegt es daran?

von Thomas E. (thomase)


Lesenswert?

Jochen schrieb:
> Was ist daran falsch?
Alles.

INT0 ist ein einziger Pin am Controller und zwar PD0. Wenn man an dem 
wackelt, kann man, entsprechende richtige Einstellungen vorausgesetzt, 
den INT0-Interrupt auslösen. Wenn du Port K abfragen willst, kannst du 
mit INT0 nichts anfangen.

Jochen schrieb:
> Habt ihr noch eine Idee?
Alles markieren und Strg + c.

Guck dir an, wie man mit einem Timer zyklisch einen Interrupt ausführt. 
Und zwar einen Timerinterrupt. In dessen ISR werden die Taster dann 
abgefragt.

mfg.

von Uwe (de0508)


Lesenswert?

Jochen schrieb:
> DDRK  |= (0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);       //Port K Eingang

damit werden die Bits nicht auf 0 gesetzt!

Die Syntax ist eine andere:
1
DDRK  &= ~((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0));

von Uwe (de0508)


Lesenswert?

Jochen schrieb:
> #define TASTERBIT 0b01000000

In deinem gesamten Code verwendest Du TASTERBIT als Bitnummer und nicht 
als Bitmaske !

Die Bitnummer wäre 6 und die Bitmaske 0b01000000.

von Thomas E. (thomase)


Lesenswert?

Thomas Eckmann schrieb:
> Alles markieren und Strg + c.
nicht Strg + c sondern Strg + x oder Entf

mfg.

von Jochen (Gast)


Lesenswert?

danke für dei Tipps!
Strg+A
ENTF

und ich informiere mich über Timerinterrupts :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.