HT16K33 und 7-Segment-Anzeigen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • mC_fAkEr schrieb:

      Was meint ihr?
      Mach das, was dir am meisten Spaß macht. Löten musst du alles alleine, beim Programmieren kann dir geholfen werden.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Fredred:
      Nicht immer muss es der Standard IC sein, auch wenn er noch so billig ist. Der Max z.b. ist ja SPI, und machmal (wie bei mir damals) hat man eh schon I2C im Einsatz, also warum mit nem zweiten Protokoll rumärgern? Man muss auch den Haupteinsatzzweck des HT16k33 sehen: Front Panels, das kann der MAX z.b. nicht: LEDs treiben und gleichzeitig Tasten einlesen, alles verbunden nur mit I2C. Deshalb gern genommen von der Industrie an Microwellenöfen, Videorecordern etc.
      Und der MAX geht offiziell nicht auf 3,3V runter, auch vielleicht ein grund was anderes nehmen zu wollen.... Natürlich gibts den kompatiblen AS1107 für 3,3V, auch der MAX funktioniert oft bei 3,3V aber wie schon gesagt, machmal muss es was anderes sein. Hier sollten es 8 Stück 16seg Anzeigen sein und ca 30 Taster, da hätt ich mit was anderem wesentlich mehr Silizium gebraucht:
      20180908_132016[1].jpg
      20180908_132028[1].jpg
      War für ne Eisenbahnanlage gedacht, kam dan anders als erwartet, nu sind halt >60 Kippschalter verbaut, konnte der Besitzer aber eher mit umgehen als mit Programmierung wenn er Änderungen wollte....
      So schlimm find ich den Ht16K33 mal nicht wenn man sich eingeschafft hat, natürlich gibts für den MAX mehr Hilfe und Beispiele, aber wo bleibt da der Spass :)

      Tobias
    • Hallo Tobias,
      bezog mich auf

      mC_fAkEr schrieb:

      nach langer "Bastelpause" wollte ich mal einen I2C/LED Driver zum Ansteuern von einer 7-Segment Anzeige testen.
      so mein Tipp.

      Schraubbaer schrieb:

      So schlimm find ich den Ht16K33 mal nicht wenn man sich eingeschafft hat, natürlich gibts für den MAX mehr Hilfe und Beispiele, aber wo bleibt da der Spass

      Habe ich auch nicht vermitteln wollen, da ja keine zusätzliche Projektanforderungen bekannt.
      Deine Hinweise sind natürlich okay und sollten bei der Planung beachtet werden.
      Mit freundlichen Grüßen
      Fred
    • Kurzes Update: Beim dieser "Bastelaktion" handelt es sich um einen kompletten Neuaufbau eines Dartautomaten aus dem Jahre 86. Komplette Elektronik wird entfernt und durch eigene ersetzt. Deshalb viel auch meine Auswahl auf den HT16K33 (Viele 7-Segment-Anzeigen und viele Eingänge).
      Sobald das restliche Material da ist, wird weiter getestet.
      Gruß Stefan
      20180905_173820.png

      20180905_220350.png

      20180905_220353.png
    • Wenn du noch Anzeigen suchst kann ich dir ein paar links schicken.
      Die Eingänge kann man auch ruhig mit dem HT realisieren, muss man zwar pollen, macht aber nix. Die Bits werden ja alle gespeichert bis man sie abgerufen hat, mehr als einen Eingang/Feld kann man mit einem Pfeil ja eh nicht auslösen, zumindest die Löwen Automaten hatten ja noch nen Schallsensor drin um Pfeile festzustellen (z.b. Leerwürfe ausserhalb der Scheibe).
      Find das toll dasnicht alles mit MAX-en gemacht wird :)

      Tobias
    • Neu

      So Leute,
      die Segmentanzeigen mit Common Kathode sind heute gekommen. Und was soll ich sagen... Angeschlossen und geht ;)

      Bin jetzt dabei eine Zahl (0-999) auf drei Digits darstellen zu lassen. Leider finde ich meinen Weg, die Einer, Zehner und Hunderter stellen zu berechnen und Auszugeben etwas umständlich. Fällt euch dazu vielleicht etwas besseres ein?

      Hier mal mein Code:

      BASCOM-Quellcode

      1. '###############################################################################
      2. 'Hardwareconfig #
      3. '###############################################################################
      4. '$sim
      5. $regfile = "m2560def.dat"
      6. $crystal = 16000000 '16MHz
      7. $hwstack = 100
      8. $swstack = 100
      9. $framesize = 400
      10. $baud = 19200
      11. 'Anschluss der 7-Segment Anzeige:
      12. 'Gemeinsame Kathode (-)
      13. '7-Segment HT16K33
      14. 'Kathode COM COM0
      15. 'Anode A Row0
      16. 'Anode B Row1
      17. 'Anode C Row2
      18. 'Anode D Row3
      19. 'Anode E Row4
      20. 'Anode F Row5
      21. 'Anode G Row6
      22. 'Anode DP Row7
      23. '
      24. 'I2C Config
      25. Config Sda = Portd.1
      26. Config Scl = Portd.0
      27. $lib "i2c_twi.lbx"
      28. Config Twi = 400000
      29. I2cinit
      30. Const 16k33 = &HE0 'Schreibadresse , alle Adresseingänge offen
      31. Const 16k33r = &HE1 'Leseadresse , alle Adresseingänge offen
      32. Dim Temp As Byte
      33. Dim I As Byte
      34. Dim T_byte(16) As Byte
      35. Dim Digi1_einer As Byte
      36. Dim Digi1_zehner As Byte
      37. Dim Digi1_hunderter As Byte
      38. Dim Digi1_tmp As Byte
      39. 'Als erstes HT16K33 initialisieren
      40. Wait 1
      41. Print "Init"
      42. Gosub Led_init 'Zu Beginn erst mal ein INIT ausführen!
      43. Wait 1
      44. Print "Init OK"
      45. Wait 1
      46. Do
      47. 'Berechnung Einer,Zehner,Hunderter Anzeige 1
      48. 'Hunderter
      49. Digi1_hunderter = I / 100
      50. 'Hunderter abziehen
      51. Digi1_tmp = Digi1_hunderter * 100
      52. I = I - Digi1_tmp
      53. 'Zehner
      54. Digi1_zehner = I / 10
      55. 'Zehner abziehen
      56. Digi1_tmp = Digi1_zehner * 10
      57. I = I - Digi1_tmp
      58. 'Einer
      59. Digi1_einer = I
      60. 'Zahlen den einzelnen Digits zuweisen
      61. Select Case Digi1_hunderter
      62. Case 0 : T_byte(2) = &H3F
      63. Case 1 : T_byte(2) = &H06
      64. Case 2 : T_byte(2) = &H5B
      65. Case 3 : T_byte(2) = &H4F
      66. Case 4 : T_byte(2) = &H66
      67. Case 5 : T_byte(2) = &H6D
      68. Case 6 : T_byte(2) = &H7D
      69. Case 7 : T_byte(2) = &H07
      70. Case 8 : T_byte(2) = &H7F
      71. Case 9 : T_byte(2) = &H6F
      72. End Select
      73. Select Case Digi1_zehner
      74. Case 0 : T_byte(4) = &H3F
      75. Case 1 : T_byte(4) = &H06
      76. Case 2 : T_byte(4) = &H5B
      77. Case 3 : T_byte(4) = &H4F
      78. Case 4 : T_byte(4) = &H66
      79. Case 5 : T_byte(4) = &H6D
      80. Case 6 : T_byte(4) = &H7D
      81. Case 7 : T_byte(4) = &H07
      82. Case 8 : T_byte(4) = &H7F
      83. Case 9 : T_byte(4) = &H6F
      84. End Select
      85. Select Case Digi1_einer
      86. Case 0 : T_byte(6) = &H3F
      87. Case 1 : T_byte(6) = &H06
      88. Case 2 : T_byte(6) = &H5B
      89. Case 3 : T_byte(6) = &H4F
      90. Case 4 : T_byte(6) = &H66
      91. Case 5 : T_byte(6) = &H6D
      92. Case 6 : T_byte(6) = &H7D
      93. Case 7 : T_byte(6) = &H07
      94. Case 8 : T_byte(6) = &H7F
      95. Case 9 : T_byte(6) = &H6F
      96. End Select
      97. I2csend 16k33 , T_byte(1) , 16
      98. Print "Loop " ; I
      99. Incr I
      100. Waitms 500
      101. Loop
      102. End
      103. ' #############################################################################
      104. Led_init:
      105. 'Register "System setup"
      106. Temp = &H21 'Oszillator einschalten
      107. I2csend 16k33 , Temp , 1
      108. Waitms 1
      109. 'Register "Display setup"
      110. Temp = &H81 'Display on - no Blink
      111. I2csend 16k33 , Temp , 1
      112. Waitms 1
      113. 'Register "Dimming set"
      114. Temp = &HEF 'Dimmimg auf 100% 16/16
      115. I2csend 16k33 , Temp , 1
      116. Waitms 1
      117. Return
      118. ' #############################################################################
      119. 'Decoding Table Zahlen:
      120. '0x3F, /* 0 */
      121. '0x06, /* 1 */
      122. '0x5B, /* 2 */
      123. '0x4F, /* 3 */
      124. '0x66, /* 4 */
      125. '0x6D, /* 5 */
      126. '0x7D, /* 6 */
      127. '0x07, /* 7 */
      128. '0x7F, /* 8 */
      129. '0x6F, /* 9 */
      Alles anzeigen
      Bin für bessere Lösungsvorschläge jederzeit bereit ;)

      Gruß Stefan
    • Neu

      So Nachtrag:
      Hab die Berechnung etwas optimiert aber ganz so Zufrieden bin ich auch noch nicht.
      Wisst ihr was besseres?

      Danke

      BASCOM-Quellcode

      1. Do
      2. 'Stellen berechnen
      3. Digi1_einer = I Mod 10
      4. I = I - Digi1_einer
      5. I = I / 10
      6. Digi1_zehner = I Mod 10
      7. I = I - Digi1_zehner
      8. I = I / 10
      9. Digi1_hunderter = I Mod 10
      10. I = I - Digi1_hunderter
      11. I = I / 10
      12. 'Zahlen den einzelnen Digits zuweisen
      13. Select Case Digi1_hunderter
      14. Case 0 : T_byte(2) = &H3F
      15. Case 1 : T_byte(2) = &H06
      16. Case 2 : T_byte(2) = &H5B
      17. Case 3 : T_byte(2) = &H4F
      18. Case 4 : T_byte(2) = &H66
      19. Case 5 : T_byte(2) = &H6D
      20. Case 6 : T_byte(2) = &H7D
      21. Case 7 : T_byte(2) = &H07
      22. Case 8 : T_byte(2) = &H7F
      23. Case 9 : T_byte(2) = &H6F
      24. End Select
      25. Select Case Digi1_zehner
      26. Case 0 : T_byte(4) = &H3F
      27. Case 1 : T_byte(4) = &H06
      28. Case 2 : T_byte(4) = &H5B
      29. Case 3 : T_byte(4) = &H4F
      30. Case 4 : T_byte(4) = &H66
      31. Case 5 : T_byte(4) = &H6D
      32. Case 6 : T_byte(4) = &H7D
      33. Case 7 : T_byte(4) = &H07
      34. Case 8 : T_byte(4) = &H7F
      35. Case 9 : T_byte(4) = &H6F
      36. End Select
      37. Select Case Digi1_einer
      38. Case 0 : T_byte(6) = &H3F
      39. Case 1 : T_byte(6) = &H06
      40. Case 2 : T_byte(6) = &H5B
      41. Case 3 : T_byte(6) = &H4F
      42. Case 4 : T_byte(6) = &H66
      43. Case 5 : T_byte(6) = &H6D
      44. Case 6 : T_byte(6) = &H7D
      45. Case 7 : T_byte(6) = &H07
      46. Case 8 : T_byte(6) = &H7F
      47. Case 9 : T_byte(6) = &H6F
      48. End Select
      49. 'Ausgabe
      50. I2csend 16k33 , T_byte(1) , 16
      51. Print "Zahl: " ; I2 ; " Einer: " ; Digi1_einer ; " Zehner: " ; Digi1_zehner ; " Hunderter: " ; Digi1_hunderter
      52. Incr I2
      53. I = I2
      54. Waitms 500
      55. Loop
      Alles anzeigen
    • Neu

      @mC_fAkEr das Aufdrösen in einzelne Ziffer geht auch mit 'makebcd'. Das sollte mit einer word-Variable auch gehen. Das geht dann bis 9999. Die Variable, die nach dem makebcd den bcd-Wert enthält, muss mit and &b1111 maskiert werden, damit nur das unterste nibble übrig bleibt, das ist dann der Einer. Jetzt die bcd-Variable um 4 bits nach rechts shiften, maskieren und das Ergebnist ist jetzt der Zehner. Shiften, maskieren, Ergebnis ist der Hunderter, shiften, Ergebnis ist der Tausender. Ob das insgesamt schneller geht, hab' ich noch nicht probiert.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Neu

      Hallo,

      wurde schon erwähnt, dass diese Anzeigen meist mit BCD- Dekoder betrieben werden. Bin nach wie vor der Meinung das diese Dekorder in größeren Projekten eine SPI – Verbindung zum Controller haben sollten. I²C ist da schon eine „Bremse“ im Ablauf des Gesamtprojektes, sollten noch mehrere Teilnehmer am Bus hängen(bin begeisterter I²C Nutzer aber, aber).

      Egal.

      Nur als Anregung wie ich Daten für Zähler mit 8 stelliger 7-Segment-Anzeige aufbereite.

      Vorab: Bei Serielle Datenübertragung ist ein senden von „Pakete“ immer zu bevorzugen.

      Hier ist es eine Zeichenkette (Txt).


      ### als Text da nicht als lauffähige Bas getestet ### *

      *Dann laß einfach die Hervorhebung weg. In einem Codetag ist es trotzdem übersichtlicher [ceperiga]

      Quellcode

      1. '******************************************************************
      2. 'Allgemeinde Variablen
      3. Dim Txt As String * 16'erstellen einer String-Variable
      4. Dim I As Integer'allgemeine Variable
      5. Dim Led_digit As Byte , Led_data As Byte
      6. '******************************************************************
      7. For I = 1 To 8 'komplettes LED-Array leeren
      8. Led_digit = I
      9. Led_data = 0
      10. Gosub Led_write 'Schickt Daten
      11. Next I
      12. I = 0
      13. Txt = Str(i)'wandelt die Zahl in ein String
      14. Txt = Format(txt , "00000000") 'Formatiert die Zahl als 8 Stellig
      15. Call Dezibcddekoder(txt) 'Gibt Zahl an Dekoder aus
      16. '********************DEMO*****************************************
      17. 'Variable I wird jede Sekunde um 1 hochgezählt
      18. Do
      19. I = I + 1
      20. Txt = Str(i)'wandelt die Variable I in ein String
      21. Txt = Format(txt , "00000000")'Formatiert die Zahl als 8 Stellig
      22. Call Dezibcddekoder(txt)'Gibt Zahl an Decoder aus
      23. Wait 1
      24. Loop
      25. '********************************************************************
      26. Sub Dezibcddekoder(byval Fakt As String)
      27. Local S$ As String * 1
      28. S$ = Right(fakt , 1) 'Rechte Zahl aus dem String (die Einer-Zahl) filtern
      29. Led_data = Val(s$) 'daraus ein Bytewert machen.
      30. Call Zahlen 'Zahl zuordnen
      31. Led_digit = 8
      32. Gosub Led_write
      33. S$ = Mid(fakt , 7 , 1) 'aus dem String die Zehner-Zahl filtern (Stelle, Anzahl)
      34. Led_data = Val(s$)
      35. Call Zahlen
      36. Led_digit = 7
      37. Gosub Led_write
      38. S$ = Mid(fakt , 6 , 1) 'aus dem String die Hunderter-Zahl filtern (Stelle, Anzahl)
      39. Led_data = Val(s$)
      40. Call Zahlen
      41. Led_digit = 6
      42. Gosub Led_write
      43. S$ = Mid(fakt , 5 , 1) 'aus dem String die Tausender-Zahl filtern (Stelle, Anzahl)
      44. Led_data = Val(s$)
      45. Call Zahlen
      46. Led_digit = 5
      47. Gosub Led_write
      48. S$ = Mid(fakt , 4 , 1) 'aus dem String die Zehntausender-Zahl filtern (Stelle, Anzahl)
      49. Led_data = Val(s$)
      50. Call Zahlen
      51. Led_digit = 4
      52. Gosub Led_write
      53. S$ = Mid(fakt , 3 , 1) 'aus dem String die Hunderttausender-Zahl filtern (Stelle, Anzahl)
      54. Led_data = Val(s$)
      55. Call Zahlen
      56. Led_digit = 3
      57. Gosub Led_write
      58. S$ = Mid(fakt , 2 , 1) 'aus dem String die Einemillion-Zahl filtern
      59. Led_data = Val(s$)
      60. Call Zahlen
      61. Led_digit = 2
      62. Gosub Led_write
      63. S$ = Left(fakt , 1 ) 'nun die Zehnmillionen- Zahl filtern.
      64. Led_data = Val(s$)
      65. Call Zahlen
      66. Led_digit = 1
      67. Gosub Led_write
      68. End Sub
      69. '*************************************************************
      70. 'nur mal so da ich kein 16k33 zum testen habe.
      71. Led_write:
      72. I2cstart
      73. I2cwbyte 16k33
      74. I2cwbyte Led_digit , 1
      75. I2cwbyte Led_data , 1
      76. I2cstop
      77. Return
      78. ‘*******************************************************
      79. ‘Daten zum MAX7219 senden sieht so aus
      80. ‘Reset Led_din
      81. ‘Reset Led_clk
      82. ‘Reset Led_load
      83. ‘Shiftout Led_din , Led_clk , Led_digit , 1
      84. ‘Shiftout Led_din , Led_clk , Led_data , 1
      85. ‘Set Led_load
      86. '**************************************************************
      87. Zahlen:
      88. If Led_data = 0 Then Restore Z0 'Daten aus Z0 in Led_data laden
      89. If Led_data = 1 Then Restore Z1
      90. If Led_data = 2 Then Restore Z2
      91. If Led_data = 3 Then Restore Z3
      92. If Led_data = 4 Then Restore Z4
      93. If Led_data = 5 Then Restore Z5
      94. If Led_data = 6 Then Restore Z6
      95. If Led_data = 7 Then Restore Z7
      96. If Led_data = 8 Then Restore Z8
      97. If Led_data = 9 Then Restore Z9
      98. Return
      99. '**************************************************************
      100. 'Decode B
      101. ' &B dp-a-b-c-d-e-f-g
      102. Z0:
      103. Data &B0000_0000
      104. Z1:
      105. Data &B0000_0001
      106. Z2:
      107. Data &B0000_0010
      108. Z3:
      109. Data &B0000_0011
      110. Z4:
      111. Data &B0000_0100
      112. Z5:
      113. Data &B0000_0101
      114. Z6:
      115. Data &B0000_0110
      116. Z7:
      117. Data &B0000_0111
      118. Z8:
      119. Data &B0000_1000
      120. Z9:
      121. Data &B0000_1001
      Alles anzeigen


      Gruß
    • Neu

      Das ist jetzt nicht das schönste Beispiel für restore..read, wenn nur ein data-Eintrag pro label vorhanden ist. Lookup mit 10 datas ist da schon eleganter. Aber das ist auch nur ein kleiner Hinweis ;)

      Ah, ich find kein 'read' a_30_7dc14a07
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Neu

      tschoeatsch schrieb:

      Das ist jetzt nicht das schönste Beispiel für restore..read, wenn nur ein data-Eintrag pro label vorhanden ist. Lookup mit 10 datas ist da schon eleganter. Aber das ist auch nur ein kleiner Hinweis


      Ja schön ist dieses Beispiel wahrlich nicht. Wollte nur zeigen wie es auch realisiert werden kann. War doch die letzte Anfrage oder?

      Nun hast Du mich aber neugierig gemacht warum Lookup eleganter ist.

      Mit Restore rufe ich doch auch nur eine indizierte Wertetabella auf . In diesem Projekt sollte gefragt werden ob überhaupt eine Zuordnungstabelle egal ob Lookup Table (LUT) oder was auch immer nötig ist.
      So komplex und nichtlineare Funktionen, die einen hohen Rechenaufwand erfordern sehe ich hier nicht. Ein Geschwindigkeitsgewinn, sofern die benötigten Speicherzugriffe schneller sind als die normale Berechnung auch nicht.

      Wichtig ist nur das @mC_fAk sein Projekt nach seinen Vorstellungen erfolgreich realisiert kann.

      Gruß