Hi Leute,
sitze nun schon Tage daran mit meinen nicht entprellten Tastern klar zu
kommen und Stunden über Interrupts. Bin ziemlicher newbie was LPC angeht
also bitte nicht gleich steinigen falls ich hier was unqualifiziertes
ablasse.
Ich möchte einfach nur einen Taster an P2(3) abfragen, doch mit meinem
code ist der mc nur mit der ISR beschäftigt und nicht mit meinem
main-code.
Habe schon so viel ausprobiert, finde den Fehler aber leider nicht.
Benutze ein LPC1769 mit folgendem c-code
1
#ifdef __USE_CMSIS
2
#include"LPC17xx.h"
3
#endif
4
5
voidEINT3_IRQHandler(void){
6
if(LPC_GPIOINT->IO2IntStatF&(1<<3)){
7
LPC_GPIOINT->IO2IntClr=(1<<3);
8
}
9
LPC_GPIOINT->IO2IntClr=(1<<3);
10
}
11
12
intmain(void){
13
volatilestaticinti=0;
14
printf("GPIO_Interrupt Sample\n");
15
//Enable interrupt
16
// Set PINSEL4 [7:6] = 00 for P2.3 as GPIO
17
LPC_PINCON->PINSEL4&=~(0x11<<6);
18
LPC_PINCON->PINMODE4&=~(0x3<<6);// Pull-Down Widerstand für Pin P2[3]
Na ja, den Handler verstehe ich jetzt von der Logik her noch nicht so
ganz. Egal ob das Flag gesetzt ist, soll der Interrupt gelöscht
werden?
Also Taster gegen VCC (da pull-down)?
Das Thema Entprellen hast du ja schon richtig benannt; da kann man
vortrefflich hier Code und Strategien finden.
Als erstes würde ich im Handler prüfen, ob es auch mein Interrupt ist.
Wenn ja, würde ich ihn im NVIC sperren und ein Flag setzen. Nun kann der
Interrupt für eine von dir festgelegte Zeit nicht mehr auslösen
(üblicherweise die Prellzeit des Tasters).
Das Flag wird in der main bearbeitet (was auch immer passieren soll).
Und nach Ablauf der Entprellzeit wird der Interrupt im NVIC wieder
aktiviert.
LPC_newbie schrieb:> Habe schon so viel ausprobiert, finde den Fehler aber leider nicht.
Hast du mal über die Alternative nachgedacht, den Taster in einer
Time-ISR, z.B. alle paar ms, abzufragen?
Nur so als Denkanstoss, konkreter möchte ich nicht drauf eingehen, alles
was mit Entprellen zu tun hat führt hier im Forum zu endlosen
Diskussionen ohne jedes Ergebnis.
Georg
Georg schrieb:> Nur so als Denkanstoss, konkreter möchte ich nicht drauf eingehen, alles> was mit Entprellen zu tun hat führt hier im Forum zu endlosen> Diskussionen ohne jedes Ergebnis.
das führt unweigerlich zu diesen Beitrag:
Beitrag "Universelle Tastenabfrage"
Dieser Code funktioniert vom Atmega bis zum ARM.. 100 prozentig!
Gruß G.G.
Lutz schrieb:> Na ja, den Handler verstehe ich jetzt von der Logik her noch nicht so> ganz. Egal ob das Flag gesetzt ist, soll der Interrupt gelöscht> werden?
Wenn der Handler aufgerufen wird ist doch mindestens 1 Flag gesetzt und
somit kann das löschen doch nicht schaden.. oder?
Lutz schrieb:> Also Taster gegen VCC (da pull-down)?
Nein, das ist ein Fehler von mir, der Taster ist Low-aktiv. Meine
Korrektur:
1
LPC_PINCON->PINMODE4&=~(0x00<<6);// Pull-Up Widerstand für Pin P2[3]
..bringt aber auch nicht den erwünschten Erfolg.
Lutz schrieb:> Als erstes würde ich im Handler prüfen, ob es auch mein Interrupt ist.> Wenn ja, würde ich ihn im NVIC sperren und ein Flag setzen.
Hier reicht mein Wissen zum mitreden leider noch nicht aus. Wie prüfe
ich auf "meinen" Interrupt und sperre ihn dann??
Georg schrieb:> Hast du mal über die Alternative nachgedacht, den Taster in einer> Time-ISR, z.B. alle paar ms, abzufragen?
Habe ich noch nicht drüber nachgedacht, kenne mich mit Time-ISR nicht
aus und das wäre somit das mittlerweile dritte Themengebiet in das ich
mich einarbeiten müsste, bevor ich endlich an meinem eigentlichen
Projekt weiter arbeiten kann :-(
Gerhard G. schrieb:> Beitrag "Universelle Tastenabfrage"
Habe ich schon vorher entdeckt aber dort wird ohne ISR gearbeitet,
außerdem wäre auch dies eine weitere Möglichkeit in die ich mich erstmal
einarbeiten muss- wohl aber die nächstgelegene falls ich meinen Ansatz
nicht zum laufen bekomme.
Was ich leider auch überhaupt nicht verstehe ist, warum mir dieses
Programm ständig in die Interrupt-Routine springt, also egal ob ich den
Taster betätige oder nicht.
Normalerweise sollte der Interrupt doch nur "anspringen" wenn eine
fallende Flanke am Pin erkannt wird, bei mir kommt er nur ab und zu aus
dem Interrupt raus um mal die main abzuarbeiten. Das bereitet mir echt
Kopfzerbrechen.
LPC_newbie schrieb:> warum mir dieses> Programm ständig in die Interrupt-Routine springt
So einem sauschnellem Boliden reichen nur wenige ns Störimpulse zum
Triggern aus. Das geht z.B. durch Reibungselektrizität (auf dem Stuhl
rutschen und in die Nähe der Taste kommen).
Und deshalb nimmt man für Tasten keinen Interruptpin.
Peter D. schrieb:> Und deshalb nimmt man für Tasten keinen Interruptpin.
Okay das klingt Plausibel!
Mein Problem, weshalb ich überhaupt auf Interrupts zum Taster einlesen
gekommen bin, ist das ich LED's mit Verzögerung betreiben möchte.
Während das Programm mit der Verzögerung beschäftigt ist kann ich ja
keine Tasten einlesen und bekomme deshalb Probleme.
Lässt sich dieses Problem mit der "Universellen Tastenabfrage" beheben
und gibt es evtl. einen LPC-freundlichen Code dazu?
LPC_newbie schrieb:> Lässt sich dieses Problem mit der "Universellen Tastenabfrage" beheben> und gibt es evtl. einen LPC-freundlichen Code dazu?
Es läßt sich mit eigenem Nachdenken beheben. Abgesehen davon läßt es
sich mit dem Angucken einiger Teile der "Lernbetty" (Gebetsmühle..) hier
im Forum beheben. Ich habe dort die gesamte Tastenmatrix der
Betty-Fernbedienung im Systemtick abgefragt, entprellt, Tastenereignisse
zur Weiterverarbeitung erzeugt und das Repetieren geregelt (1.
Repetierzeit lang, danach kurz).
Im Grunde ist das Prinzip recht simpel:
- in der Systemtick-ISR testet man, ob ein neuer Tastendruck vorliegt
oder bei stets gedrückter Taste die Zeit für ein Repetieren reif ist,
oder ob die Taste entprellt ist - also lang genug am Stück "aus" ist.
Bei neuem Tastendruck oder Repetieren erzeugt man einen Tasten-Event,
also man stellt einen entsprechenden Code in einen Ereignispuffer ein.
Dieser kann dann an anderer Stelle abgearbeitet werden.
Es ist im übrigen für die Prinzipien der Tastenabfrage völlig egal, was
für einen µC man gerade hat.
Tasten sind was anderes als Drehgeber, denn erstens haben Tasten keine
Richtungsinformation, die man zeitnah zum Ereignis abfragen muß und
zweitens ist die Ereignisfrequenz bei Tasten sehr viel geringer als bei
Drehgebern. Deshalb ist es durchaus sinnvoll, Tasten im
Interruptprogramm des System-Timers abzufragen.
So einen System-Timer-Tick sollte man sich eigentlich fast immer
einrichten, alle 10 ms reicht - und das belastet auch den µC nicht sehr.
In der Lernbetty habe ich auch das Prinzip von verzögerten Ereignissen
gezeigt: Der Systemtick führt eine kleine Liste von Einträgen, wo
Uhrzeit und Ereigniscode vermerkt sind. Zu jedem Timertick testet die
ISR, ob einer der Einträge abgelaufen ist. Wenn ja, dann wird dieser
Eintrag gelöscht und sein Ereigniscode in den Ereignispuffer
eingetragen. Von dort aus wird es dann an anderer Stelle abgearbeitet.
W.S.
W.S. schrieb:> Es läßt sich mit eigenem Nachdenken beheben.
Setz mich gerade dran, wird aber wahrscheinlich mit meinem momentanen
Wissen nicht Einfach. Mit dem timer interrupt, avr-bezeichnungen oder
manchen funktionen wie die sei() kenne ich mich z.B noch überhaupt nicht
aus. Aber irgendwo muss man ja mal anfangen.
W.S. schrieb:> ...Angucken einiger Teile der "Lernbetty"
Wahrscheinlich diese hier?
Beitrag "Die Lernbetty: Die SwissBetty von Pollin als ARM-Evalboard"W.S. schrieb:> Im Grunde ist das Prinzip recht simpel:> - in der Systemtick-ISR...
Werde ich mir mal anschauen.. aber simpel ist halt Definitionssache im
Auge de Betrachters ;-)
Habe nun etwas gefunden was mich hoffentlich einen großen Schritt nach
vorne bringt:
Beitrag "Re: Universelle Tastenabfrage"
Kann mir hier bitte jemand verraten wo ich die dort eingebundenen Header
her bekomme?
okay habe die meisten header in einem Paket von Texas Instruments
gefunden
http://elk.informatik.fh-augsburg.de/cdrom-stellaris/
nächste Frage ist nun wie ich diese richtig einbinde..
werde aber erstmal einen neuen Forumsbeitrag eröffnen da dieser hier
mittlerweile recht wenig mit der Eingangsthematik zu tun hat.
LPC_newbie schrieb:> Nein, das ist ein Fehler von mir, der Taster ist Low-aktiv. Meine> Korrektur:>>
1
LPC_PINCON->PINMODE4&=~(0x00<<6);// Pull-Up Widerstand für Pin
2
>P2[3]
>> ..bringt aber auch nicht den erwünschten Erfolg.
Das wundert mich nicht.
Das ist genauso Unsinn, wie das hier ...
1
LPC_PINCON->PINSEL4&=~(0x11<<6);
2
LPC_PINCON->PINMODE4&=~(0x3<<6);// Pull-Down Widerstand für Pin P2[3]
... alles mögliche gemacht hat, aber sicher nicht das, was im Kommentar
steht.
> Habe ich noch nicht drüber nachgedacht, kenne mich mit Time-ISR nicht> aus und das wäre somit das mittlerweile dritte Themengebiet in das ich> mich einarbeiten müsste
es sieht so aus, als ob du dich noch in vieles erst mal 'einarbeiten'
musst. Und das beginnt bei den banalsten Grundlagen, wie zb
Bitmanipulationen.
> Mein Problem, weshalb ich überhaupt auf Interrupts zum Taster einlesen> gekommen bin, ist das ich LED's mit Verzögerung betreiben möchte.> Während das Programm mit der Verzögerung beschäftigt ist kann ich ja> keine Tasten einlesen und bekomme deshalb Probleme.
Nope.
Das Programm bekommt Probleme, weil sein Programmierer nichts drauf hat.
Sorry. Aber das musste mal gesagt werden.