Der TM1637 (mit dem Atmega8)




Der TM1637 heißt deshalb so , weil der Treiber , also der verbaute Baustein hinten eben : TM1637 heißt.



Gut, man könnte auch  : 4-digit , 7 Segmentanzeige mit passendem Treiber schreiben , wäre aber vll. etwas lang.

Der TM1637 ist ursprünglich für 6 Stk 7-Segment gedacht !!



Ist aber recht schwer zu erhalten.  Außer vll. unter anderem bei :



Der TM1637 kann ausschliesslich nur ZAHLEN  !
Nun ja, könnte er auch Buchstaben , wäre es eher ein 14 Segment , gelle ;-)
Jetzt kann man im Internet viel drüber lesen wie der TM1637 angesteuert wird und zwar über I²C !
Das ist zwar richtig , aber er  brauch es etwas besonders , drum schreiben wir die Routinen dann doch selber.
Hat den Vorteil , das man für die üblichen : CLK , DIN , DO (SDA) , frei die Pins wählen kann.


Die wesentlichen Routinen sind recht überschaubar :

Sub I2C_ack()
   Reset CLK
   Waitus 5
   Reset Dout
   Bitwait Din , Reset
   Set CLK
   Waitus 2
   Reset CLK
   Set Dout
End Sub

Sub I2C_off()
   I2C_start
   I2C_write &H80 
   I2C_ack
   I2C_stop
End Sub

Sub I2C_on()
   I2C_start
   I2C_write &H8A
   I2C_ack
   I2C_stop
End Sub

Sub I2C_start()
   Set CLK
   Set Dout
   Waitus 2
   Reset Dout
End Sub

Sub I2C_stop()
   Reset CLK
   Waitus 2
   Reset Dout
   Waitus 2
   Set CLK
   Waitus 2
   Set Dout
End Sub

Die eigentliche Routine , welche die Zahlen an den TM1637 schickt , ist dann etwas komplizierter.

Da die Zahlen 0 - 9 etwas konfus sind  ....

0 = 00111111 - 63
1 = 00000110 - 6
2 = 01011011 - 91
3 = 01001111 - 79
4 = 01100110 - 102
5 = 01101101 - 109
6 = 01111101 - 125
7 = 00000111 - 7
8 = 01111111 - 127
9 = 01101111 - 157

ist es doch besser man macht sich eine SELECT CASE Anweisung dafür nach meiner Meinung.

Case "0" :I2C_write &B00111111
Case "1" :I2C_write &B00000110
Case "2" :I2C_write &B01011011
Case "3" :I2C_write &B01001111
Case "4" :I2C_write &B01100110
Case "5" :I2C_write &B01101101
Case "6" :I2C_write &B01111101
Case "7" :I2C_write &B00000111
Case "8" :I2C_write &B01111111
Case "9" :I2C_write &B01101111

denn , .... immer wenn am entsprechenden Segment , also 1. / 2. / 3. / 4. ein Punkt erscheinen soll ,
muss man die Zahl 128 , sprich das 7. Bit setzen !
Hinzu kommt , da es ein Treiber für 6 Segmente eigentlich  ist , wir aber nur immer 4 Segmente nutzen (haben) ,
zählt man immer von 2-5 !
NICHT von 1-4 !

Hört sich jetzt erstmal alles komisch an , ist aber , wenn man es einmal kapiert hat recht einfach.

Man geht also wie folgt vor ...
die gewünschte Zahl einer Procedur übergeben. Diese Zahl dann in der Procedur als STRING umwandeln.
Dann kann man mit MID schön Zahl für Zahl ermitteln (auch ob 's mit Punkt sein soll ) und BINÄR dann
zu I²C senden.


Hier dann jetzt mal ein Beispiel Code :


$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 40
$framesize = 40


Config Portd.2 = Output       ' clock
Config Portd.3 = Output       '  data


Clk Alias Portd.2
Dout Alias Portd.3
Din Alias Pind.3


Declare Sub Send_Display(byval Displaywert As Word)
Declare Sub I2C_write(byval Bdata As Byte)
Declare Sub I2C_on()
Declare Sub I2C_off()
Declare Sub I2C_start()
Declare Sub I2C_stop()
Declare Sub I2C_ack()


Dim Zaehler As Byte
Dim Str_Displaywert As String * 5
Dim Ascii As String * 1
Dim w As Word ' !!!!! höchste Zahl ist 9999


'========================================================================
'
'     Start main
'
'========================================================================

I2C_on
Do
     ' 1. Segment
     for w=0 to 9
       Send_Display w
       waitms 500
     next w
      2. Segment
     for w=10 to 100 step 10
       Send_Display w
       waitms 500
     next w
      3. Segment
     for w=100 to 1000 step 100
       Send_Display w
       waitms 500
     next w
     4. Segment
     for w=1000 to 9000 step 1000
       Send_Display w
       waitms 500
     next w
      ' Display OFF/ON
     I2C_off
     waitms 1500
     I2C_on
loop
end


'=========================================================================
'
'     Subroutines
'
'========================================================================

Sub I2C_ack()
   Reset CLK
   Waitus 5
   Reset Dout
   Bitwait Din , Reset
   Set CLK
   Waitus 2
   Reset CLK
   Set Dout
End Sub

Sub I2C_off()
   I2C_start
   I2C_write &H80       ' display off
   I2C_ack
   I2C_stop
End Sub

Sub I2C_on()
   I2C_start
   I2C_write &H8A       ' display on und Helligkeit auf 25%
   I2C_ack
   I2C_stop
End Sub

Sub I2C_start()
   Set CLK
   Set Dout
   Waitus 2
   Reset Dout
End Sub

Sub I2C_stop()
   Reset CLK
   Waitus 2
   Reset Dout
   Waitus 2
   Set CLK
   Waitus 2
   Set Dout
End Sub

Sub I2C_write(byval Bdata As Byte)
   Local Bbitcounter As Byte

   For Bbitcounter = 0 To 7     
      Reset CLK
      Dout = Bdata.bbitcounter
      Waitus 3
      Set CLK
      Waitus 3
   Next
End Sub


Sub Send_Display(byval Displaywert As Word)

   Str_Displaywert = Str(Displaywert)
   Str_Displaywert = Format(Str_Displaywert , "     ")

   I2C_start
   I2C_write &H40       'autoincrement adress mode
   I2C_ack
   I2C_stop
   I2C_start
   I2C_write &HC0       'startaddress first digit (HexC0) = MSB display
   I2C_ack

   For Zaehler = 2 To 5
      Ascii = Mid(Str_Displaywert , Zaehler , 1)
         if Zaehler=1 then
             ' mit Punkt
            Select Case Ascii
                    Case "0" :I2C_write &B10111111
                    Case "1" :I2C_write &B10000110
                    Case "2" :I2C_write &B11011011
                    Case "3" :I2C_write &B11001111
                    Case "4" :I2C_write &B11100110
                    Case "5" :I2C_write &B11101101
                    Case "6" :I2C_write &B11111101
                    Case "7" :I2C_write &B10000111
                    Case "8" :I2C_write &B11111111
                    Case "9" :I2C_write &B11101111
                    Case Else:I2C_write &B10000000
            End Select

         else
 
             ' ohne Punkt
            Select Case Ascii
                    Case "0" :I2C_write &B00111111
                    Case "1" :I2C_write &B00000110
                    Case "2" :I2C_write &B01011011
                    Case "3" :I2C_write &B01001111
                    Case "4" :I2C_write &B01100110
                    Case "5" :I2C_write &B01101101
                    Case "6" :I2C_write &B01111101
                    Case "7" :I2C_write &B00000111
                    Case "8" :I2C_write &B01111111
                    Case "9" :I2C_write &B01101111
                    Case Else:I2C_write &B00000000
           End Select

         endif
        I2C_ack
   Next
   I2C_stop
End Sub




















zurück zur Beispiel-Übersicht