Forum: Mikrocontroller und Digitale Elektronik Keyboard Interrupt wird nicht richtig erkannt


von Peter M. (allforone)


Lesenswert?

Hallo,
Gleich kommt ein Codebeispiel.
Ich habe einen BCD Schalter, immer wenn dieser getätigt bzw. gedreht 
wird, soll ein Interrupt ausgelöst werden.
Ich habe noch keine Hardware hier, daher teste ich es mit einem 
True-Time Simulator aus der IDE von freescale.

Hardware: S08AW60
Prozessorfamilie: HCS08
1
void main(void) {
2
3
  PeriphInit();
4
  for(;;) {
5
    __RESET_WATCHDOG(); /* feeds the dog */
6
  }
7
}
8
9
10
interrupt VectorNumber_Vkeyboard1 void  KBI_ISR (void) {    // Noch unsicher, ob der Syntax richtig ist
11
   
12
  KBI1SC_KBACK = 1;   //Interrupt bestätigen und Flag rücksetzen
13
  PTAD_PTAD0   = 1;
14
  PTAD_PTAD1   = 1;
15
16
  
17
    //BCD-Schalter abfragen
18
    //LED blinken lassen
19
  
20
  }
und:
1
void PeriphInit(void) {
2
3
  //LEDs initialisieren
4
  PTADD_PTADD0 = 1;
5
  PTADD_PTADD1 = 1;
6
  PTAD = 0;
7
  
8
  //Keyboard initialisieren + Interrupts aktivieren
9
  
10
  KBI1SC_KBACK = 1;     //Interruptflag clearen
11
  KBI1SC_KBIE = 1;      //keyboard auf Interrupt einstellen n
12
  KBI1PE = 0xff;        //Für alle Pins Interrupts aktivieren
13
  KBI1SC_KBIMOD = 0; 
14
  KBI1SC_KBEDG = 0; 
15
16
  
17
  //Interrupts aktivieren
18
  EnableInterrupts;   //Global Interrupt Enable
19
20
21
}

Wenn ich jetzt den BCD-Schalter in der Simulation verändere, dass von 
Bits von 1 auf 0 geändert werden -> Interrupt
Wenn Bits von 0 auf 1 geändert werden -> kein Interrupt

Hat jemand eine Idee?

von Hmm (Gast)


Lesenswert?

Ich kenne den Prozessor nicht, aber kann es sein, das er nur auf eine 
Flanke reagiert, nicht auf beide? Schau mal in das Datenblatt.

von Peter M. (allforone)


Lesenswert?

Ja das stimmt, die Flanke kann bzw. muss ich einstellen.
1
KBI1SC_KBIMOD = 0; 
2
KBI1SC_KBEDG = 0

Wird hier gemacht. Auf Seite 161 steht es.
http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08AW60.pdf

Jetzt stellt sich die Frage, gibt es schöne Lösungen bzw. passende 
Lösungen, um es zu realisieren, dass auch ein Interrupt von Low auf High 
registriert wird?

von Peter II (Gast)


Lesenswert?

Jan R. schrieb:
> Jetzt stellt sich die Frage, gibt es schöne Lösungen bzw. passende
> Lösungen, um es zu realisieren, dass auch ein Interrupt von Low auf High
> registriert wird?

warum muss es denn überhaupt im interupt sein? Warum nicht in der main 
schleife einfach schalter abfragen?

Beim umschalten wirst du sowieso viel zu viele Interupts bekommen.

von Peter M. (allforone)


Lesenswert?

Die ISR würde ich ganz kurz halten, nur Status abfragen.

Du meinst zu viele Interrupts, weil man den Schlater dreht und daher auf 
dem Weg zur eigentlich gewünschten Stellung die ganze Zeit Interrupts 
auslöst?

Ja könnte man auch in der main-Methode abfragen, wollte nur eigentlich 
Interrupts machen.

von Peter II (Gast)


Lesenswert?

Jan R. schrieb:
> Die ISR würde ich ganz kurz halten, nur Status abfragen.

Kommt aufs Programm an, wenn man an mehre stellen die BCD status braucht 
und dieser ändert sich mitten drin, kann das auch schlecht sein.

if ( bcd == 2 ) {
  mach was
}

if ( bcd == 3 ) {
  noch was
}

wen du jetzt im Interupt bcd neu setzt, dann wird eventuell keine der 
beiden funktionen aufgefufen.
Wenn man es in der main ändert, dann weiss man das es für die aktuellen 
durchlauf immer gleich ist.

von Peter M. (allforone)


Lesenswert?

hm, da ich keine passende Lösung für das Flankenproblem sehe, werde ich 
es wohl in der main Methode machen müssen.

von Hmm (Gast)


Lesenswert?

>... da ich keine passende Lösung für das Flankenproblem sehe ...
Huch? Das verblüfft mich.

Du hast doch die Lösung schon selbst hingeschrieben.

>KBI1SC_KBIMOD = 0;
>KBI1SC_KBEDG = 0

und

http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08AW60.pdf

Warum machst Du es nicht entsprechend?

von Peter M. (allforone)


Lesenswert?

Das hat so nicht funktioniert. Ok, wenn du meinst, dass es aber so 
möglich ist, werde ich noch weiterforschen.

von Hmm (Gast)


Lesenswert?

>Das hat so nicht funktioniert.
Zeig doch mal genau, was Du probiert hast.
Ich erwarte, das Du im Interrupt die sensitive Flanke umstellst.

Du kannst das natürlich machen wie Du willst, aber es hat wenig Sinn 
irgendwas rumzuprobieren und wenn es nicht funktioniert irgendwas 
anderes herumzuprobieren.

Und:
Das "funktioniert nicht" ist auch nicht gerade zielführend. Analytischer 
wäre: Es passiert dies und jenes wenn ich das und dies tue.

von Hmm (Gast)


Lesenswert?

>..wenn du meinst...
Was hat das mit mir zu tun?

Es ist Deine Entscheidung: Willst Du herumraten bis es irgendwann geht 
oder auch nicht geht oder lernen und gezielt und analytisch vorgehen um 
kompetent zu werden bzw. zu sein?

von Peter M. (allforone)


Lesenswert?

Das ist ja eine rhetorische Frage ;)
Nur wenn es gar nicht möglich ist, dann brauche ich gar nicht erst 
loslegen.
Wir bleiben dabei, es ist möglich und ich kann jetzt per Datenblatt 
versuchen, die Register mit den richtigen Werten zu versehen bzw. wird 
eventuell noch ein paar zeilen von Nöten sein.

von Hmm (Gast)


Lesenswert?

>Das ist ja eine rhetorische Frage ;)
Nicht wirklich.

>Wir bleiben dabei, es ist möglich und ich kann jetzt per Datenblatt
>versuchen, die Register mit den richtigen Werten zu versehen bzw. wird
>eventuell noch ein paar zeilen von Nöten sein.

Nicht "wir". Ich schrieb schon, dass ich den Prozessor nicht kenne.
Die mindeste Voraussetzung war, dass sich die Flanke umstellen läßt. Das 
hast Du nachgesehen und hier berichtet.

Schau für den Rest wieder in's Datenblatt und übernimm für mögliche 
Fehlschläge die Verantwortung.

von Karl H. (kbuchegg)


Lesenswert?

Jan R. schrieb:
> Die ISR würde ich ganz kurz halten, nur Status abfragen.

Darum gehts nicht.

> Du meinst zu viele Interrupts, weil man den Schlater dreht und daher auf
> dem Weg zur eigentlich gewünschten Stellung die ganze Zeit Interrupts
> auslöst?

Nein, zu viele Interrupts weil das ein mechanischer Schalter ist und die 
notorisch prellen.

> Ja könnte man auch in der main-Methode abfragen, wollte nur eigentlich
> Interrupts machen.

Schalter, Taster und dergleichen sind eher unsinnig mit externen 
Interrupts zu behandeln. Alleine das Tastenprellen wegzubekommen kostet 
soviel Code, dass du mit Polling 100 mal besser drann bist.

Zumal du bei deinem µC diesen Interrupt nicht auf beide Flanken 
einstellen kannst. D.h. du müsstest im Programm Buch führen, welches die 
letzte Flanke war und dann je nachdem im Interrupt ständig die 
Flankenrichtung umstellen.

Viel zu viel Arbeit für etwas, was du in der Hauptschleife oder in einem 
Timerinterrupt (so macht man das normal) mit einem Bruchteil des 
Aufwands erreichen kannst.

von Hmm (Gast)


Lesenswert?

>Zumal du bei deinem µC diesen Interrupt nicht auf beide Flanken
>einstellen kannst. D.h. du müsstest im Programm Buch führen, welches die
>letzte Flanke war und dann je nachdem im Interrupt ständig die
>Flankenrichtung umstellen.

Genau so dachte ich mir das. (Das entsprechende Bit ist dabei das Buch).

Abgesehen davon meine ich nicht, das man Interrupts zur Eingabe von 
einem BCD-Codierschalter so grundsätzlich scheuen muss wie es hier (im 
Forum) vertreten wird.
Nochmals abgesehen von anderen Umständen, ist ein Codierschalter nicht 
auf die gleiche Weise zu behandeln wie ein Taster.

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.