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