upigors hat geschrieben: das probier ich gleich mal....


Danke

Moderator: radioscout
worauf thomas_st schon ein paar Anmerkungen hatte.Ich denke mal, der Thread ist der richtige für meine Frage:
ich möchte (eigentlich relativ einfach) 8 Taster an einem yController (genauer: Attiny 2313) erkennen. Prinzipiell soll in Abhängigkeit der Taster etwas auf dem Display (hängt an Port D) ausgegeben werden bzw. eine Aktion passieren (hängt an mehreren seriellen Schieberegistern).
Mein Gedanke dazu war, den Interrupt PCINT an Port B zu benutzen und immer wenn er ausgelöst wird irgendwie die gerade anliegenden Tasten zu lesen und eine Hilfsvariable zu setzen.
Versuch 1:
(einfach nach dem auslösen des Interrupts die Pineingänge lesen) schlug fehl:
On Pcint On_pcint
Enable Pcint
Enable Interrupts
Pcmsk = &B11111111
On_pcint:
if pinb.0 = 1 then
hilfsmerker =1
endif
if pinb.1=1 then
hilfsmerker=2
endif
usw....
Versuch 2:
liefert in der Hauptschleife immer komische Werte, die auch "0" sein können, obwohl nie auf "0" mit nem Interrupt gesetzt wird ...
On Pcint On_pcint
Enable Pcint
Enable Interrupts
Pcmsk = &B11111111 On_pcint:
Debounce Pinb.0 , 0 , 8press , Sub
Debounce Pinb.1 , 0 , 1press , Sub
Debounce Pinb.2 , 0 , 2press , Sub
Debounce Pinb.3 , 0 , 3press , Sub
Debounce Pinb.4 , 0 , 4press , Sub
Debounce Pinb.5 , 0 , 5press , Sub
Debounce Pinb.6 , 0 , 6press , Sub
Debounce Pinb.7 , 0 , 7press , Sub
Return
1press:
Zahl = 1
Return
2press:
Zahl = 2
Return
3press:
Zahl = 3
Return
4press:
Zahl = 4
Return
5press:
Zahl = 5
Return
6press:
Zahl = 6
Return
7press:
Zahl = 7
Return
8press:
Zahl = 8
Return
Wer kann mir helfen ?? Wer hat vielleicht einen sinnvollen Codeschnippsel, um mehrere Tasten nach einem (Soft- d.h. PCINT-)Interrupt abzufragen ??
Ich hoffe, ich bin hier richtig, sonst gebt mir einen Hinweis ...
Gruß
Henrik
Code: Alles auswählen
$regfile = "ATtiny2313.dat"
$crystal = 1000000
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , _
Db7 = Portd.5 , E = Portd.6 , Rs = Portd.0
Config Lcd = 16 * 2
Ddrb = &B00000000 ' alle PortB Pins auf Eingang definieren
Portb = &B11111111 ' alle PortB Pins auf High setzen / Pullup
On Pcint On_pcint
Enable Pcint
Enable Interrupts
Pcmsk = &B11111111 'alle pcint´s anmachen
Dim Initcounter As Byte
Dim Bt As Byte
Dim S As String * 2
Dim Zahl As Byte
Initlcd
Do
Locate 1 , 1
Lcd "Zaehlen: "
Lcd Zahl
For Bt = 1 To 100
S = Str(bt)
S = Format(s , "000")
Locate 2 , 1
Lcd S
Waitms 50
Next Bt
Initlcd
Loop
On_pcint:
if pinb.0 = 1 then
Zahl = 1
endif
if pinb.1=1 then
Zahl = 2
End If
If Pinb.2 = 1 Then
Zahl = 3
endif
If Pinb.3 = 1 Then
Zahl = 4
End If
If Pinb.4 = 1 Then
Zahl = 5
endif
If Pinb.5 = 1 Then
Zahl = 6
End If
If Pinb.6 = 1 Then
Zahl = 7
endif
If Pinb.7 = 1 Then
Zahl = 8
End If
Return
Code: Alles auswählen
' Codeeingabe mit einer 7-Segment Anzeige
$regfile = "m8def.dat" 'Atmega 8-Deklarationen
$hwstack = 8
$swstack = 8
$framesize = 24
$crystal = 8000000
$baud = 9600
Dim A As Byte
Dim B As Byte
Dim C As String * 9
Dim D As Integer
Config Portd.2 = Input 'Taster 1 - auf
Config Portd.5 = Output ' Ausgang für Relais
Config Portd.4 = Input 'Taster 3 Enter
Config Portb.0 = Output ' Strich in der Mitte
Ddrc = &B11111111 'Port C komplet auf Output
Pind.2 = 0 'Taster 1 auf Low
Pind.4 = 0 'Taster 3 auf Low
Afg:
A = 0 'Variable A auf 0 setzen
Gosub Sub0 '0 ausgeben
Do
Debounce Pind.2 , 1 , Cnt , Sub 'Wenn Taster 1 gedrückt gehe zum zählen
Debounce Pind.4 , 1 , Entr , Sub 'Wenn Taster 3 gedrücht gehe zum übernehmen
If C = "135798642" Then 'Abfrage ob String vollständig und richtig ist dann
Gosub Sub9 ' Countdown Ausgabe
Waitms 150 '9
Gosub Sub8 '8 usw.
Waitms 150
Gosub Sub7
Waitms 150
Gosub Sub6
Waitms 150
Gosub Sub5
Waitms 150
Gosub Sub4
Waitms 150
Gosub Sub3
Waitms 150
Gosub Sub2
Waitms 150
Gosub Sub1
Waitms 150
Gosub Sub0
Portd.5 = 1 'Ausgang einschalten
C = "1" 'String zurücksetzen damit der Countdown nicht weiterläuft
End If
Loop
Cnt: 'Zählen
A = A + 1 'hochzählen
If A = 1 Then Gosub Sub1 '1 ausgeben
If A = 2 Then Gosub Sub2 '2 ausgeben usw.
If A = 3 Then Gosub Sub3
If A = 4 Then Gosub Sub4
If A = 5 Then Gosub Sub5
If A = 6 Then Gosub Sub6
If A = 7 Then Gosub Sub7
If A = 8 Then Gosub Sub8
If A = 9 Then Gosub Sub9
If A = 10 Then Gosub Sub0
If A = 10 Then Goto Afg ' Zähler wieder zurück auf 0
Return
Sub0:
Portc = &B00111111 'Zahl 0 darstellen
Portb.0 = 0
Return
Sub1:
Portc = &B00000110 'Zahl 1 darstellen
Portb.0 = 0
Return 'usw.
Sub2:
Portc = &B01011011
Portb.0 = 1
Return
Sub3:
Portc = &B01001111
Portb.0 = 1
Return
Sub4:
Portc = &B01100110
Portb.0 = 1
Return
Sub5:
Portc = &B01101101
Portb.0 = 1
Return
Sub6:
Portc = &B01111101
Portb.0 = 1
Return
Sub7:
Portc = &B00000111
Portb.0 = 0
Return
Sub8:
Portc = &B01111111
Portb.0 = 1
Return
Sub9:
Portc = &B01101111
Portb.0 = 1
Return
Entr: 'Zahl übernehmen
Select Case A
Case 1 'Wenn A =1
D = 1 'setze D = 1
C = C + Str(d) 'übernehme D zum Vorhandenen String C
For B = 1 To 3 'Zahl 3x blinken lassen
Portc = &B00000110
Portb.0 = 0
Waitms 20 'analog zu den anderen Werten
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B00000110
Portb.0 = 0
Next B
Case 2
D = 2
C = C + Str(d)
For B = 1 To 3
Portc = &B01011011
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01011011
Portb.0 = 1
Next B
Case 3
D = 3
C = C + Str(d)
For B = 1 To 3
Portc = &B01001111
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01001111
Portb.0 = 1
Next B
Case 4
D = 4
C = C + Str(d)
For B = 1 To 3
Portc = &B01100110
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01100110
Portb.0 = 1
Next B
Case 5
D = 5
C = C + Str(d)
For B = 1 To 3
Portc = &B01101101
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01101101
Portb.0 = 1
Next B
Case 6
D = 6
C = C + Str(d)
For B = 1 To 3
Portc = &B01111101
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01111101
Portb.0 = 1
Next B
Case 7
D = 7
C = C + Str(d)
For B = 1 To 3
Portc = &B00000111
Portb.0 = 0
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B00000111
Portb.0 = 0
Next B
Case 8
D = 8
C = C + Str(d)
For B = 1 To 3
Portc = &B01111111
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01111111
Portb.0 = 1
Next B
Case 9
D = 9
C = C + Str(d)
For B = 1 To 3
Portc = &B01101111
Portb.0 = 1
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B01101111
Portb.0 = 1
Next B
Case 10
D = 0
C = C + Str(d)
For B = 1 To 3
Portc = &B00111111
Portb.0 = 0
Waitms 20
Portc = &B00000000
Portb.0 = 0
Waitms 20
Portc = &B00111111
Portb.0 = 0
Next B
End Select
Return
ich muß das jetzt nochmal aufwärmen.Kappler hat geschrieben: Also folgendermaßen:
**** hier mal gekürzt wegen der übersichtlichkeit....****
Config Portb = &B00110000 'Pinb.4+5 auf 'Ausgang', Rest auf 'Eingang' schalten
Portb = &B00001110 'Ausgänge 1-3auf Low setzen
Stop Ac 'Analog-Komparator abschalten, um Strom zu sparen
**** hier mal gekürzt wegen der übersichtlichkeit....****
Do
Reset Watchdog
Powerdown
If Pinb.1 = 0 Then
Gosub A
End If
If Pinb.2 = 0 Then
Gosub B
End If
Loop
**** hier mal gekürzt wegen der übersichtlichkeit....****
End[/code]
Code: Alles auswählen
Do
Hilfsvariable = 0
If Pinb.1 = 0 Then
Hilfsvariable = 1
End If
If Pinb.2 = 0 And Hilfsvariable = 1 Then
Gosub A
Elseif
Gosub B
End If
If Pinb.3 = 0 Then
Gosub B
End If
Loop
Code: Alles auswählen
Do
Hilfsvariable = 0
If Pinb.1 = 0 Then
Hilfsvariable = 1
End If
If Hilfsvariable = 1 Then
If Pinb.2 = 0 Then
Gosub A
Else
Gosub B
End If
End If
If Pinb.3 = 0 Then
Gosub B
End If
(jetzt sollte noch irgendwas hierhin, das die Hilfsvariable
nach einer bestimmten Zeit auf 0 zurück setzt...
In den Unterprogrammen sollte die Hilfsvariable auch auf
0 gesetzt werden)
Loop
Erstmal TFTC (Thanks For The Code)Kappler hat geschrieben:Eher so:Code: Alles auswählen
Do .................... Loop
Code: Alles auswählen
$hwstack = 20 'hardwarestack herabsetzen damit genügend variablen zur verfügung stehen
$regfile = "ATtiny13.DAT"
$crystal = 128000 'Frequenz des internen Oszillators
Config Portb = &B00011000 'Pinb.4+3 auf 'Ausgang', Rest auf 'Eingang' schalten
Portb = &B00000111 'Ausgänge auf Low setzen
Stop Ac 'Analog-Komparator abschalten, um Strom zu sparen
Wdtcr = &B11010011 'Watchdog definieren: 0.125 Sekunden, Interrupt auslösen, kein Reset
Enable Interrupts 'Interrupts freigeben
Dim H As Bit
Do
Wdtcr = &B11010101
Reset Watchdog
Powerdown
If Pinb.0 = 0 Then
Gosub B
End If
H = 0
If Pinb.1 = 0 Then
H = 1
End If
If H = 1 Then
Wait 1
If Pinb.2 = 0 Then
Gosub A
Else
Gosub B
End If
End If
Loop
A:
Wdtcr = &B11010101
Portb = &B00010110 'grün
Reset Watchdog
Powerdown
Portb = &B00000110
Reset Watchdog
Powerdown
Wdtcr = &B11110001 'lange pause
Reset Watchdog
Powerdown
Return
B:
Wdtcr = &B11010011
Portb = &B00001110 'rot
Reset Watchdog
Powerdown
Portb = &B00000110
Reset Watchdog
Powerdown
Return
End
Ich weiß es nicht, aber könnte das was mit dem prellen des Tasters zu tun hat.upigors hat geschrieben:Kappler hat geschrieben:Eher so:
Starte ich das ganze zum ersten mal (Spannung anlegen) passiert erstmal nichts - was ja sicher auch so sein soll da der ja auf den ersten Input wartet. Der Ablauf ist dann ok wenn entweder PB1 und PB2 hintereinander (mit wait 1) oder gleichzeitig betätigt werden (Taster) folgt A (grüne LED), kommt irgendwie PB0 ins Spiel folgt B(rote LED). ABER:
Warum warum springt der nach Ablauf von A und der Pause gleich wieder zu B (B blinkt dauerhaft bis A mal aktiviert wird)? Beim Erststart halt nicht, läuft das Programm weiter dann ja.... Sollte der nicht wieder auf die erste Eingabe warten? In meiner Anwendung ist das gut so aber interessiert mich halt trotzdem![]()
Code: Alles auswählen
Config Int0 = Falling 'steigende (Rising) oder fallende Flanke (beim drücken oder beim loslassen)
Enable Interrupts 'einschalten Der Interrupts
Enable Int0 'einschalten Von Interrupt Int0
On Int0 B ' Wenn Int0 dann gehe zu B