Tastatureingabe beim Multiplexen

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Tastatureingabe beim Multiplexen

      Moin allerseits.

      Seit Tagen suche ich vergeblich, eine Lösung für folgendes Problem zu finden. Ich habe eine Platine gefertigt, welche mit einem Atmega16 5 LED's im Mulltiplexverfahren ansteuert. Dies funktioniert auch einwandfrei. Es erscheinen nach dem Einschalten die 5 Nullen und wenn ich wie im Code zu sehen, vor der Loopschleife eine Zahle eingebe, erscheint diese auch im Display. Ebenfalls lassen sich 5 Taster so programmieren, daß der Zahlenwert eines Diplays bis 9 incrementiert werden kann.
      Nun möchte ich aber eine 12er-Tastatur anschließen, mit der ich den Zahlenwert einmal über eine Taste eingebe und die Eingabe dann eine Stelle nach rechts weiterspringt um den nächsten Wert einzutippen. Nach der 5ten Eingabe will ich weiterspringen um die Zahlenwerte zu verarbeiten. Die letzten Eingaben im Code (Taste_x etc.) beziehen sich auf einen Versuch, mit dem ich eine Stelle erfolgreich anwählen kann. Das war's dann auch.
      Es wäre toll, wenn mir jemand von Euch verhelfen würde.

      MfG
      Wolle

      Anlage
      Files
    • wolleausmallo wrote:

      Die letzten Eingaben im Code (Taste_x etc.) beziehen sich auf einen Versuch, mit dem ich eine Stelle erfolgreich anwählen kann
      Mir fehlt das Taste_X ? Wie soll die Auswahl aussehen?
      Eine Möglichkeit wäre mit der */# Taste links rechts zu springen. Als Indikator welches Segment erwählt ist könnte der Dezimalpunkt gelten oder das Segment blinken?
      Oder wie beim TV ein paar Zahlen eingeben und wenn eine gewisse Zeit keine mehr kommt das ganze übernehmen?
    • Beim Multiplexen der Anzeige ist es wichtig, dass die regelmäßig und gleichmäßig aktualisiert wird.
      Eine Möglichkeit ist per Interrupt die Anzeige zu multiplexen. Die Daten kommen dann aus einem Array für die Stellen, so wie du das jetzt auch hast (Dim Stelle(n) as Byte).

      Bei jedem Interrupt-Aufruf wird die anzuzeigende Stelle (Segment) aktiviert und der Wert für diese Stelle ausgegeben. Beim nöchten Interrupt aufruf wieder eine Stelle weiterschalten und den Wert der neuen Stelle ausgeben.

      Bei 5 Digits und mindestens 25 komplett-Anzeigen pro Sekunde, wäre eine Interrupt-Frequenz von mindestens 5 x 25Hz = 125 Hz nötig.

      Die Anzeige läuft dann autonom im Hintergrund. Zum Ändern der Anzeige schreibst du dann nur neue Werte in das Array Stelle(n).

      Den Interrupt kannst du gleichzeitig nutzen, um die Blink-Frequenz des Digits, für die eine Eingabe zu machen ist, festzulegen.
      Bei obigen 125 Herz müsstest du dann um eine Blinkfrequenz von 1 Hz zu erreichen (Umschaltung alle 0,5s) die 125Hz / 2 Hz teilen. Ein Zähler (Byte) wird einfach hochgezählt und bei erreichen von 62 wird ein Flag getoggelt und der Zähler auf 0 gesetzt.

      Ein gesetztes Flag zeigt an, dass ein Cursor als Ziffer bei der Ausgabe (ISR) anzuzeigen ist.
      Hier könnte man einen Querstrich (unten oder mittig) anzeigen. Das im Wechsel mit der vorhandenen Ziffer.

      Um die Stelle zu bestimmen, in der der Cursor steht machst du eine Variable (Byte) z.B. Cursor_Input.

      Ist der Wert 1, ist die Stelle ganz links am blinken, bei 2 die Stelle rechts daneben etc.
      Ist der Wert 6, kann der Wert zum erkennen der vollständigen Eingabe dienen.

      Für die Tasteneingabe kannst du dann auch Debounce verwenden, um die Tasten zu entprellen.

      Wird eine Taste gedrückt, z,B. die 5, dann wird der Wert 5 in das Array Stelle(n) geschrieben.
      n ist hierbei der Wert von Cursor_Input. Dann wird Cursor_Input inkrementiert.

      In der ISR muss also bei der Ausgabe der Anzeige-Stelle berücksichtigt werden, ob Cursor_Input im Bereich 1 bis 5 liegt, dann wird wenn Flag = 1 ist ein Cursor an dem Digit ausgegeben anstelle des Inhalts aus dem Array Stelle(n). Ist das Flag = 0 wid der Bufferinhalt für die Stelle ausgegeben.

      Du steuerst also über die Variable Cursor_Input, welche Stelle bei der Ausgabe blinkt und wohin der Tastenwert geschrieben wird.

      Wenn im späteren Verlauf der Programm-Entwicklung das Debounce stört, weil da ja eine Verzögerung intern mit rund 25ms gemacht wird, kann man die Tastenabfrage auch in dem vorhandenen Interrupt durchführen.
    • Hi Mitch

      Das ist nicht wirr, da die Anordnung der PINs nicht das übliche Schema hat, nämlich:
      Case 1 : Portd = &H79
      Case 2 : Portd = &H24
      Case 3 : Portd = &H30
      Case 4 : Portd = &H19
      Case 5 : Portd = &H12
      Case 6 : Portd = &H02
      Case 7 : Portd = &H78
      Case 8 : Portd = &H00
      Case 9 : Portd = &H10
      Case Else : Portd = &B01000000

      Gruß
      Wolle
      Files
      • Plan.jpg

        (119.28 kB, downloaded 29 times, last: )
    • So vielleicht?

      Source Code

      1. $regfile = "m16def.dat"
      2. $crystal = 3686400
      3. $hwstack = 100
      4. $swstack = 100
      5. $framesize = 100
      6. Dim Einer As Byte 'Dimensionierungen
      7. Dim Zehner As Byte
      8. Dim Hunderter As Word
      9. Dim Tausender As Byte
      10. Dim Zehntausender As Word
      11. Dim Zaehlen As Word
      12. Dim Zahl As Word
      13. Dim Tzahl As Byte ' Tastenspeicher
      14. Dim Gedrueckt As Byte ' Tastenflag
      15. Dim I As Word
      16. Dim Z1 As Byte
      17. Dim Test As Byte
      18. Dim Stelle(5) As Word
      19. Dim Tstelle As Byte : Tstelle = 1
      20. Dim Temp As Word
      21. Dim Auswahl As Byte
      22. Dim T1 As Bit 'Die Dimenionierungen für die 5 Displays
      23. Dim T2 As Bit
      24. Dim T3 As Bit
      25. Dim T4 As Bit
      26. Dim T5 As Bit
      27. Dim X As Byte 'Ports konfigurieren
      28. Config Porta = Input
      29. Porta = &B11111111
      30. Config Portb = Output
      31. 'Portb = &B11111111
      32. Config Portc = Input
      33. Portc = $ff 'Portc = &B10111111 Taste8 immer gedrückt?
      34. Config Portd = Output
      35. Config Portd.7 = Input '=DDRB = &B01111111
      36. Set Portd.7
      37. 'Alias-Namen für die 12er Tastatur
      38. Taste_1 Alias Pind.7
      39. Taste_2 Alias Pinc.0
      40. Taste_3 Alias Pinc.1
      41. Taste_4 Alias Pinc.2
      42. Taste_5 Alias Pinc.3
      43. Taste_6 Alias Pinc.4
      44. Taste_7 Alias Pinc.5
      45. Taste_8 Alias Pinc.6
      46. Taste_9 Alias Pinc.7
      47. Taste_10 Alias Pina.7.
      48. Taste_stern Alias Pina.6
      49. Taste_raute Alias Pina.7
      50. Zahl = 54321 ' Anzeige durch die umgekehrte Stelle(x) Anordung,
      51. Gosub Zahl2ziff
      52. Do
      53. Gosub 7segment
      54. Gosub Tasten
      55. Waitms 1
      56. Loop
      57. 7segment:
      58. 'For I = 1 To 40 '40(10 mal anzeigen bis zur nächsten berechnung)
      59. Portb.z1 = 0
      60. 'For Z1 = 1 To 5 'Abfrage bder Stellen - Stelle(1)-(5)
      61. If Z1 < 4 Then
      62. Incr Z1
      63. Else
      64. Z1 = 0
      65. End If
      66. Test = Stelle(z1 + 1)
      67. Select Case Test
      68. Case 1 : Portd = &HCF 'Die Hex -werte Für Die Einzelnen Zahlen Des Arrays Von 1 -9 Und Dan 0 Case 2 : Portd = &H92 für dieses Projekt
      69. Case 3 : Portd = &H86
      70. Case 4 : Portd = &HCC
      71. Case 5 : Portd = &HA4
      72. Case 6 : Portd = &HA0
      73. Case 7 : Portd = &H8F
      74. Case 8 : Portd = &H80
      75. Case 9 : Portd = &H84
      76. Case Else : Portd = &B10000001
      77. End Select 'Low Bit = G= Querstrich für die 8(muß aber 0 sein) - High Bit = PORTD.7 für die Tastatur
      78. Portb.z1 = 1 'Durchlauf Multiplexverfahren
      79. ' Waitms 1
      80. ' Z1 = Z1 + 1
      81. ' Next Z1
      82. 'Next I
      83. Return
      84. Tasten:
      85. If Taste_1 = 0 Then
      86. Tzahl = 0 : Gedrueckt = 1
      87. Elseif Taste_2 = 0 Then
      88. Tzahl = 1 : Gedrueckt = 1
      89. Elseif Taste_3 = 0 Then
      90. Tzahl = 2 : Gedrueckt = 1
      91. Elseif Taste_4 = 0 Then
      92. Tzahl = 3 : Gedrueckt = 1
      93. Elseif Taste_5 = 0 Then
      94. Tzahl = 4 : Gedrueckt = 1
      95. Elseif Taste_6 = 0 Then
      96. Tzahl = 5 : Gedrueckt = 1
      97. Elseif Taste_7 = 0 Then
      98. Tzahl = 6 : Gedrueckt = 1
      99. Elseif Taste_8 = 0 Then
      100. Tzahl = 7 : Gedrueckt = 1
      101. Elseif Taste_9 = 0 Then
      102. Tzahl = 8 : Gedrueckt = 1
      103. Elseif Taste_10 = 0 Then
      104. Tzahl = 9 : Gedrueckt = 1
      105. Else 'keine gedrückt/losgelassen
      106. If Gedrueckt = 1 Then
      107. Stelle(tstelle) = Tzahl
      108. Incr Tstelle
      109. If Tstelle > 5 Then Tstelle = 0
      110. End If
      111. Gedrueckt = 0
      112. End If
      113. Return
      114. Zahl2ziff:
      115. Temp = Zahl
      116. Temp = Temp / 10000 'div/1000 , vom Rest
      117. Stelle(1) = Temp Mod 10
      118. Temp = Zahl
      119. Temp = Temp / 1000 'div/1000 , vom Rest
      120. Stelle(2) = Temp Mod 10 'rechte Stelle bleibt übrig
      121. ''
      122. Temp = Zahl 'div/100, vom Rest
      123. Temp = Temp / 100 'rechte Stelle bleibt übrig
      124. Stelle(3) = Temp Mod 10
      125. Temp = Zahl
      126. Temp = Temp / 10 'div/10, vom Rest
      127. Stelle(4) = Temp Mod 10 'rechte Stelle bleibt übrig
      128. Temp = Zahl
      129. Temp = Temp / 1 'echt ;-) 'div/10, vom Test
      130. Stelle(5) = Temp Mod 10 'Mod 10 rechte Stelle bleibt übrig
      131. Return
      Display All
      da ist noch viel Luft zum Optimieren, vor allem fehlt noch eine Routine die geänderten Stellen zu der Zahl zu konvertieren. Auch eine "Stellenänderungsanzeige"
      Die verdrehte Anzeige ist gewollt? Die Zahl wird nie größer 65535?

      The post was edited 1 time, last by Pluto25 ().

    • Ich möchte hier auch meinen Beispiel-Code zeigen.

      Tasten sind entprellt, Ausgabe der Anzeige im Hintergrund per Interrupt,
      Blink-Frequenz und Refresh-Frequenz per Konstanten einstellbar.
      Die Steuerung wurde mit einem sehr vereinfachten Automaten realisiert, so dass das jeder nachvollziehen kann.
      Und last but not least. Der Wert in der Anzeige lässt sich vorgeben und auch Abfragen.

      Mit Blinken ist gemeint, dass die Ziffer abwechselnd mit einem Strich angezeigt wird, da wo die Stelle bearbeitet werden soll.

      Alles im Code dokumentiert.

      Auch hier ist Optimierung möglich.

      Der Quellcode passt hier leider nicht rein, daher ist er als Download angehängt.
      Files
    • Guten Morgen Mitch64 und Michael und Pluto25.

      Das ist ja mehr als ich erwartet habe. Ich werde die Codes jetzt ausdrucken und anschauen. Wenn ich weiter gekommen bin, melde ich mich noch mal. Bis hierher schon mal vielen Dank für die Unterstützung.

      Grüße
      Wolle
    • Ich war neugierig und wollte wissen, ob und wie gut mein Code aus Post #10 funktioniert.
      Also habe ich das soweit auf meinem Steckboard aufgebaut und ausprobiert.

      Dabei habe ich festgestellt, dass Refresh-Raten noch bei 35Hz flirren.
      Ich habe daher die Refresh-Rate auf 50Hz erhöht.

      Dann noch ein Fehler beseitigt, weil ein "Incr Cursor_Pos" ein Bearbeiten im Zustand ST_EDIT verhinderte.
      Den Fehler habe ich beseitigt.

      Weiterhin habe ich den Buffer für die Anzeige als String mit überlagertem Array ausgeführt. Das vereinfacht den Zugriff deutlich. Es waren dann aber ein paar Anpassungen notwendig, damit der Wert als Zahl gesetzt und ausgelesen werden kann und auch die Ausgabe beim Multiplexer klappt sowie das Bearbeiten im Mode ST_EDIT.

      Jetzt spielt der Code exzellent!

      Beim Ausprobieren die Kommentare beachten!

      Die neue Version 1.1 ist angehängt.
      Files
    • Moin Jungs.

      Ich freue mich, daß ich Euer Interesse geweckt habe. Danke für die 2te Version Mitch64. Bis jetzt habe ich mir die Version von Pluto25 vorgenommen und so verändert(Kleinigkeiten), daß sie zu meinem Projekt passt. Die Idee ist einen Stepper nach eingetippter Vorgabe zu bewegen, zB. 1233,3mm und diese Werte dann abzuspeichern und auch wieder abzurufen. Das ist ein Projekt für meine Bandsäge.
      Nun werde ich erstmal bis Sonntag eine Motorradtour machen. Danach werde ich Deine 2te Version ausdrucken und aufspielen. Zu meiner Schande muß ich gestehen, nicht der Bascom-Crack zu sein, obwohl ich das Programm schon seit 15J nutze. Melde mich wieder.

      LG
      Wolle

      PS. Die Eingabe soll von links nach rechts beginnen und mit 5XNull starten.

      The post was edited 2 times, last by wolleausmallo ().

    • Hallo Mitch64.

      Ich habe mir den Code ausgedruckt, angeschaut und aufgespielt. Das war ja ganz schön viel Arbeit für Dich. Das Display bleibt bei mir dunkel und ich habe noch nicht herausgefunden warum. Da ich schon 73 bin, fällt mir der Durchblick schwerer. Aber ich schau mal.
    • hallo @wolleausmallo

      Bei mir hat der Code sauber gespielt.

      Du solltest die Pins mal prüfen, die an die Anzeige und zu den Tastern gehen, ob die mit den Angaben im Code
      übereinstimmen.


      BASCOM Source Code: Auszug

      1. DDRD = &b0111_1111 ' PortD[6:0] = Output ' 7-Segment-Ansteuerung
      2. ' Alias-Namen für die 12er Tastatur (int. PullUp aktiv)
      3. Taste_1 Alias Pind.7 : Set PortD.7
      4. Taste_2 Alias Pinc.0 : Set PORTC.0
      5. Taste_3 Alias Pinc.1 : Set PortC.1
      6. Taste_4 Alias Pinc.2 : Set PortC.2
      7. Taste_5 Alias Pinc.3 : Set PortC.3
      8. Taste_6 Alias Pinc.4 : Set PortC.4
      9. Taste_7 Alias Pinc.5 : Set PortC.5
      10. Taste_8 Alias Pinc.6 : Set PortC.6
      11. Taste_9 Alias Pinc.7 : Set PortC.7
      12. 'Taste_10 Alias Pina.7
      13. Taste_0 Alias Pina.7 : Set PortA.7
      14. Taste_Stern Alias Pina.6 : Set PortA.6
      15. Taste_Raute Alias Pina.5 : Set PortA.5
      Display All

      Bei dir war da irgendwo bei den Tasten ein Pin doppelt belegt! (Ich meine Stern oder Raute war gleicher Pin wie eine Zifferntaste).

      Ansonsten stelle den code wie du ihn hast nochmal ein und schildere exakt das Problem.