Hallo!
Ich hab mir vor kurzem ein Übungsboard mit nem ADUC831 drauf zugelegt.
Nun möchte ich die 4 auf dem Board vorhandenen Tasten abfragen, in der
Art: Wenn Taste 1 gedrückt ist, dann soll LED1 leuchten.
Laut Beschreibung kann man eine Taste z.B. mit taste=P1&0x0F in "einer
Interruptfunktion" abfragen. Aber wie programmiert man das genau (in C)
?
ich habe schon lange hier im Forum gesucht, bin aber leider noch nicht
fündig geworden, was so ein simples (?) Problem betrifft :-)
Laut einem - nicht funktionierenden - Beispielprogramm von AnalogDevices
sieht die InterruptRoutine so aus:
1
voidtasten(void)interrupt0
2
{
3
flag1=1;
4
// 0 1 1 1 1 0 0 0 Dekodierung für Tasten
5
taste=(P2&0x78)>>3;
6
}
Doch wie erhalte ich daraus einen Wert im main-Programm bzw. wie lese
ich einen bestimmten Tastenwert aus ??
Danke!
Lg
bluefox
Hallo bluefox
Leider konnte ich im Schaltplan die Tasten nicht finden. Wo sind die
denn angeschlossen? Manche Ports der ADUCs haben keinen internen PullUp,
die müssen dann selber verdrahtet werden. Da Port1 auch als AD-Eingang
verwendet wird, könnten die hier auch fehlen.
Aus dem Datenblatt:
Port 1 is an 8-bit input port only. Unlike other ports, Port 1 defaults
to Analog Input mode, to configure any of these Port Pins as a digital
input, write a "0" to the port bit. Port 1 pins are multifunction and
share the following functionality...
1
#include<stdio.h>
2
#include<aduc831.h>
3
4
#define TASTE1 1
5
#define TASTE2 2
6
#define TASTE3 4
7
#define TASTE4 8
8
9
intmain()
10
{
11
chartaste;
12
13
while(1)
14
{
15
taste=P1&0x0F;
16
if(taste)
17
{
18
switch(taste)
19
{
20
caseTASTE1:funktion1();
21
break;
22
caseTASTE2:funktion2();
23
break;
24
caseTASTE3:funktion3();
25
break;
26
caseTASTE4:funktion4();
27
break;
28
}
29
}
30
31
// Tu in der Zwischenzeit irgendwas
32
}
33
return0;
34
}
Erst mal so probieren. Wenn das funktioniert, dann mit einem Timer
Interrupt die Tasten abfragen und per globaler Variablen an main()
übergeben.
Danke für die Hilfe!
Leider funktioniert mit dem Code aber gar nix :-(
Die Tasten hängen alle an den Port1-Pins (P10 bis P13), aber außerdem
habe ich noch in der Beschreibung gelesen, dass alle Port1-Pins auf den
"INT0" zusammengeführt sind (??).
Interessanterweise funktioniert der Zugriff auf INT0 zwar, also z.B.:
1
P2=INT0;//P2 sind die LEDs.
Es leuchtet aber so immer nur die unterste LED (also binär 0001) beim
Tastendruck, egal welche Taste ich drücke - sprich: INT0 ist anscheinend
nur 1Bit breit.
:-((( Ich kenn mich nimmer aus.
Ich hab schon viel mit dem Vorgänger ADuC812 gemacht, welcher ja fast
identisch ist. Der Interrupt 0 ist ein externer Interrupt (P3.2/INT0).
Damit kann man aber ohne weiteren Aufwand nur eine Taste abfragen. Dazu
muss auch zuvor der Interrupt eingeschaltet werden.
>Die Tasten hängen alle an den Port1-Pins (P10 bis P13)>dass alle Port1-Pins auf den "INT0" zusammengeführt sind (??).
Wahrscheinlich gehen 4 Dioden von den Tasten zu INT0
>P2=INT0; //P2 sind die LEDs.
Mach mal P2 = P1&0x0F;
Geht jeweils die LED an, entsprechnd der Taste? Dann gibt es Pull Ups
und die Taste zieht den Port auf Null. Das Programm ist umgekehert
gedacht. Widerstände auf Masse und Tasten auf Plus.
Vielleicht gehts so:
#define TASTE1 0x0E
#define TASTE2 0x0D
#define TASTE3 0x0B
#define TASTE4 0x07
>Es leuchtet aber so immer nur die unterste LED (also binär 0001) beim
Das stimmt, INT0 wird als Bit und nicht als Byte eingelesen.
PS.
Die Syntax des Interupts ist für den Keil Compiler. Das kann sich bei
Dir etwas unterscheiden.
Hm. Es will einfach nicht funktionieren.
Ich hab alles so reinprogrammiert, wie du es beschrieben hast, ich hab
sogar noch einen default-Wert für die switch-Funktion hineingenommen.
Jedes Mal springt er aber direkt in diesen default-Wert, d.h. der
Tastendruck wird gar nicht erkannt.
Hier mein Code:
funktioniert leider auch nicht - es wird auch hier immer nur der
default-Wert vom switch aufgerufen.
P.S: ich habe auch den keil-compiler - das kann also kein fehler sein.
sorry für den Doppelpost...
Leider hab ich gerade keinen ADuC hier, um das nachzuvollziehen. Bei den
externen Interrupts kann man noch einstellen, ob sie auf Flanke oder
Zustand reagieren und hohe Priorität (PX0=1).
Vielleicht geht der Interrupt noch nicht. Kontrollier mal, ob er
überhaupt reinspringt.
void ext0_int(void) interrupt 0
{
taste = P1 & 0x0F;
P2=5;
waitms(1000);
}
funktioniert, d.h. anscheinend wird der Interrupt zwar erkannt, aber
es wird noch immer in den default-Wert gesprungen. Demnach kann das Teil
nicht zwischen den einzlnen Tasten unterscheiden (oder so ähnlich?) :-(
Also der Interrupt geht, aber es kommt keine Taste an und
P2 = P1&0x0F;
Jetzt hab ichs entdeckt. Die Tasten sind an J14 - J17 angeschlossen. Die
Tasten ziehen die Spannung auf Null, aber die Schmitt Trigger
invertieren. Bei gedrückter Taste liegt eine 1 am Port an und eine 0 am
P3.2.
Also ist doch die alte Version richtig:
#define TASTE1 1
#define TASTE2 2
#define TASTE3 4
#define TASTE4 8
Vielleicht macht diese Zeile noch Probleme.
while(taste); // warten bis Taste losgelassen
Könntest Du die einfach mal auskommentieren?
Also ich hab beide Variante versucht (while(taste) auskommentieren und
deinen neuen Quelltext), aber leider funktionierts nicht:
Bei
1
...
2
if(taste)// falls taste gedrückt
3
{
4
P2=taste;
5
waitms(1000);
6
P2=0xFF;
7
}
8
...
werden nur die 4 unteren der 8 LEDs deaktiviert (also eben 0x0F), aber
nach 1 Sekunde passiert gar nichts, der Befehl 0xFF wird also nicht
ausgeführt (ist mir unerklärlich).
Mir ist immer noch nicht ganz klar, wie das Board zwischen den vier
Tasten unterscheiden soll, wenn ja nur eine 1Bit-Leitung (INT0)
verwendet wird.
In deinem Beispiel mit der switch-Anweisung ist es zwar ausprogrammiert,
aber das will leider auch nicht funktionieren.
verzweifel
,
also die Kodierung für "TASTE4" auf 15 geändert. Nun wird immer der case
TASTE4 ausgeführt (LEDs auf 8binär) --> d.h. sobald ich irgendeine Taste
drücke, werden ALLE 4 Pins vom Port1 auf 1 gezogen.
Wie soll man da zwischen den einzelne Tasten unterscheiden können, wenn
eh immer der selbe Code (1111b) ausgegeben wird??
Ob die Tasten am ADUC ankommen, lässt sich einfach mit einem Multimeter
überprüfen oder mit einer LED von GND auf den entsprechenden Pin. Bei
gedrückter Taste müsste eine 1 ankommen.
Es könnte doch noch was damit zu tun haben:
Port 1 is an 8-bit input port only. Unlike other ports, Port 1 defaults
to Analog Input mode, to configure any of these Port Pins as a digital
input, write a "0" to the port bit.
main()
{
ser_ini();
taste=0;
P1 = 0xF0; // Bit 0 to 3 as digital input
init_interrupts();
.
.
.
Das ist eine Besonderheit, die es so bei anderen 51ern nicht gibt.
Kannst du mir noch bei nem anderen Problem bei diesem µC helfen?:
Ich möchte gern ein Signal (eine Gleichspannung) nach außen abgeben. Mit
welchen Pins kann ich das am einfachsten machen? (P1.0 bis P1.3 ist ja
für die Taster reserviert und P2 für die LEDs) - und wie mache ich das?