Forum: Mikrocontroller und Digitale Elektronik TM1637, 4-stellige LED 7-Segmentanzeige mit AVR-GCC


von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Hallo erstmal,

nachdem vor ein paar Wochen jemand nach Code für ein "China-Modul" 
4-stellige LED-Siebensegmentanzeige mit Baustein TM1637 angefragt hat, 
hab ich mir aus China über die Bucht eines bestellt und dafür den Code 
erstellt.. (für ARDUINO gibts Code wie Sand am Meer)

- Nein, ich habe kein Problem mit diesem Teil, ich möchte hier nur den 
Code für dieses Modul mit demjenigen teilen, der das eventuell innerhalb 
von "reinem C" gebrauchen kann.

Der Treiberbaustein wird mittels I2C angesteuert, dieses allerdings 
etwas "merkwürdig", weil er keine I2C-Busadresse besitzt, sondern IMMER 
angesteuert wird, wenn auf dem Bus der Wert 0x40, 0x80 oder 0xC0 
ausgegeben wird.

Deshalb habe ich ein "Bitbanging Soft-I2C" implementiert bei dem dann 
auch die Anschlußpins frei gewählt werden können.

Wenn das jemand gebrauchen kann: Schaltplan und Code sind angehängt, ins 
englische übersetztes Datenblatt gibts 
http://vk.com/doc121030043_316564659 , viel Spaß,

Ralph

von Rudi M. (rudimentaer)


Lesenswert?

Ralph S. schrieb:
> Hallo erstmal,
> ...
> - Nein, ich habe kein Problem mit diesem Teil, ich möchte hier nur den
> Code für dieses Modul mit demjenigen teilen, der das eventuell innerhalb
> von "reinem C" gebrauchen kann.
> ...

Na das nenne ich mal timing. Ich bin zwar nicht der von vor ein paar 
Wochen, habe aber gestern gerade nach Code für den TM1637 gesucht. 
Deiner ist mit Abstand der übersichtlichste den ich gefunden habe.
Ich sag mal ein fettes Danke dafür!

Grüße,
Rudi

P.S. Feedback gibts nach dem ausprobieren

von Rudi M. (rudimentaer)


Lesenswert?

Hallo Ralph,

das war ja schmerzfrei! Klappt auf Anhieb und Du hast mir ein paar 
Stunden gespart.
You made my day!

Danke,
Rudi

@Moderator: schieb das doch bitte in die Projekte/Codesammlung

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Smilw, vielen Dank fürs Lob, freut mich wenn das gebrauchen kannst...

von Rudi M. (rudimentaer)


Lesenswert?

Just 4 the records...

die Helligkeitssteuerung funktioniert mit Werten von 8 bis 15, alles
unter 8 schaltet das Display dunkel.
Sinnvoll sind eigentlich nur 8,9,10,11 und 15.

von Ralph S. (jjflash)


Lesenswert?

... das habe ich für das Display so auch bemerkt, der TM1637 lässt aber 
das komplette untete Halbbyte als Wert zu. Vllt. sollte man da im 
Programm noch eine Anpassung vornehmen... Guck ich nächste Woche mal.... 
Gute Nacht.

von Rudi M. (rudimentaer)


Lesenswert?

Hallo Ralph,
ja, bit 3 schaltet ein oder aus, die bits 0-2 setzen die Helligkeit.

Ich habe es für mich so gelöst das ich die Werte von 0-8 akzeptiere, 
0=aus, 1-8 sind die Helligkeitsstufen:


/*  ----------------------- SETBRIGHT -------------------------------
       setzt die Helligkeit der Anzeige
       erlaubte Werte fuer Value sind 0..8 (0=aus, 1= min, 8 = max)
    ----------------------------------------------------------------- */
void tm1637_setbright(uint8_t value)
{
  if (value > 8) value = 8;   // alles >= 8 ist max.
  tm1637_start();
  if ( value ) { tm1637_write(0x88 | (value -1)); } // bits 0-2 = hell
  else { tm1637_write(0x80); }                      // 0 = dunkel
  tm1637_stop();
}


ich habe auch noch für setdez und sethex eine Variante mit Unterdrückung 
der führenden nullen eingebaut:

/*  ----------------------- SETDEZ0 --------------------------
       gibt einen 4-stelligen dezimalen Wert auf der
       Anzeige aus, unterdrueckt fuehrende nullen
    --------------------------------------------------------- */
void tm1637_setdez0(int value)
{
  uint8_t i,v;

  tm1637_clear();
  for (i= 4; i> 0; i--)
  {
    v= value % 10;
    tm1637_setbmp(i-1, led7sbmp[v]);
    value= value / 10;
  if ( ! value ) { break; }
  }
}

Natürlich beim Prototyping nicht vergessen:
void tm1637_setdez0(int value);

analog dazu für sethex.

Viele Grüße,
Rudi

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

... smile, das darf sich jeder gerne so abändern wie es für ihn 
brauchbar ist.

Der Code für den TM1637 ist nun wirklich nicht etwas herausragendes, :-) 
am besten noch vergleichbar mit einer Funktion zum Zeichnen von Rahmen 
im Textmodus auf einem PC.

... es gäbe noch viele "Möglichkeiten" das zu erweitern. Man kann eine 
32 Bit Variable oder ein 4 Byte Array definieren, und auf dieses mittels 
Bitmanipulation zugreifen um einzelne Bits zu setzen oder zu löschen und 
bei jedem "Zugriff" auf die Anzeige genau diese 4 Bytes zur Anzeige 
bringen (die 4 Bytes wären dann -hochtrabend ausgedrückt- der 
Framebuffer oder der Schattenspeicher der Anzeige).

Das hätte den Vorteil, dass jede einzelne Leuchtdiode der Anzeige 
getrennt voneinander gesetzt oder gelöscht werden kann....

:-) laß deinem Spieltrieb freien Lauf,

Gruß,

Ralph

von Paul (Gast)


Lesenswert?

Hallo,

funktioniert der TM1637 auch mit dem Hardware I2C des AVR?
Ich benutze die nämlich, aber das Display bleibt dunkel.

Viele Grüße

Paul

von Ralph S. (jjflash)


Lesenswert?

... ich werde diese Woche den Kram mal wieder auspacken und versuchen 
das mittels Hardware I2C zu realisieren, aber grundsätzlich macht das 
für mich keinen Sinn, da dann diese 4 stellige Anzeige grundsätzlich 
keine weiteren I2C Einheiten zulässt (weil der TM1637 keine Adresse 
besitzt und somit auf JEDE Kommunikation auf dem I2C Bus reagiert).

Grundsätzlich kannst du natürlich die Anschlusspins an die Pins legen, 
an denen normalerweise Hardware-SPI aufgelegt ist, aber wie gesagt: 
TM1637 muss alleine am Bus angeschlossen sein (und da es nur sehr wenig 
Datentransfer zum TM1637 sind Geschwindigkeitsvorteile mit Hardware I2C 
nur sehr gering).

Aber wie gesagt, ich werde es ausprobieren (und grundsätzlich glaube ich 
auch, dass das funktionieren sollte).

von Paul (Gast)


Lesenswert?

Hallo,

Danke für deine Rückmeldung. Ohne wirklich vorher darüber nachzudenken 
wie simpel Soft-I2C ist, habe ich nen Busumschalter mit nem 74HC4066 
gebastelt.
Um andere Fehler auszuschließen, habe ich gestern mal kurz deine 
Bibliothek verwendet und damit ging das Display sofort.

Ich hänge das Display jetzt an zwei extra GPIOs und schmeiße den 
Busumschalter raus. Aber dennoch vielen Dank für deine Hilfe. Ein kleine 
Anpassung habe ich noch eingebaut. Ich schalte die Pegel an SCL/SDA 
nicht mit dem Portregister sondern mit dem Datenrichtungsregister.

Viele Grüße

Paul

von Ralph S. (jjflash)


Lesenswert?

Paul schrieb:
> Ich schalte die Pegel an SCL/SDA
> nicht mit dem Portregister sondern mit dem Datenrichtungsregister.

Kann man machen, aber dann benötigt es extern die obligatorischen Pullup 
Widerstände eines I2C Buses.

Wenn die Anzeige doch aber eh schon exklusiv 2 I/O Leitungen erhält, 
können doch die Widerstände auch entfallen.

von Rob (Gast)


Lesenswert?

Hallo Leute,
gibt es den Quellcode von oben noch irgendwo unter dem Link findet man 
leider nichts mehr.
Grüße

von ??? (Gast)


Lesenswert?

der Quellcode ist doch noch da, es geht nur der Link zum Datenblatt 
nicht mehr. Das kann man dann ja g**geln...

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

Rob schrieb:
> Hallo Leute,
> gibt es den Quellcode von oben noch irgendwo unter dem Link findet man
> leider nichts mehr.
> Grüße

Wie Vorredner geschrieben hat: Der Quellcode ist doch noch da und das 
Datenblatt häng ich hier jetzt noch einmal her !

von Eike J. (Gast)


Lesenswert?

Hallo und guten Abend,
ich habe mir in Fernost auch mal so lustige TM1637 Module ergattert.
Leider hat diese Lib auf Anhieb nicht richtig funktioniert.
Mal leuchtete es sehr wild durcheinander, meistens blieb alles dunkel.

Beim Einbau der seriellen Konsole für Debug-Ausgaben bin ich durch
Zufall einem Timing-Problem auf die Schlichte gekommen.
Mit Seriellen Ausgaben funktionierte die Anzeige Plötzlich. ;-)

Die finale Lösung war eine Wartezeit von einer Mikrosekunde zu Beginn
der write-Funktion:

[...Schnipp...]
void tm1637_write (uint8_t value)    // I2C Bus-Datentransfer
{
  uint8_t i;
  _delay_us(1);    // Loesung meines Timing Problems
  for (i = 0; i <8; i++)
[...Schnapp...]

Mit dieser Delay funktioniert es auch bei mir.
Ralph, vielen Dank dafür! :-)

Viele Grüße

Eike J.

von Anja (Gast)


Lesenswert?

Hallo,
ich versuche bis jetzt leider vergeblich, ein TM1637 LED-Modul mit 
I2C-Anschluss (SDA, SCL) zum Laufen zu bringen (=das mit 6 Digits und 6 
Tastern).

Hat jemand hiermit Erfahrungen gemacht und kann mir evtl. einen 
Beispiel-Sketch zeigen.
Der Link von ganz oben geht leider nicht mehr (403 forbidden)
http://vk.com/doc121030043_316564659

Viele Grüsse
Anja

von Ralph S. (jjflash)


Lesenswert?

Hm, ich hab jetzt diese WE keinen Zugriff auf meine Elektronik. Von sen 
7-Segmentmodulwn scheint es einige zu geben. Vor allen Dngen mit 
unterschiedlichen Chips: TM1637, TM1638, TM1651 ... und einer fällt mir 
gerade nicht ein. Dein Modul kenn ich jetzt nicht: 6 Digits und 6 
Tasten. Hm, außerdem ist das hier kein Arduino Sketch... Aber sag mir 
welcher Chip und ich guck mirs an.

von Anja (Gast)


Lesenswert?

ich kann leider nicht erkennen, welcher Chip da verbaut ist, aber 
vielleicht hilft das ja weiter:
https://www.amazon.de/MagiDeal-Display-TM1637-Arduino-Raspberry-Multi/dp/B076BD6M99

Gruß, Anja

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Anja schrieb:
> ich kann leider nicht erkennen, welcher Chip da verbaut ist, aber
> vielleicht hilft das ja weiter:

 In der Anzeige ist TM1637 eingebaut.

 Das kriegst du nicht mit Hardware I2C zum laufen, aber mit Bit-
 banging geht das ohne Probleme.
 Etwa so, bin nicht mehr ganz sicher, ist schon lange her:
1
/* INIT */
2
// Set sda pin als output, high
3
// Set scl pin als output, high
4
// wait 15ms
5
// Clear Display
6
7
/*  START */
8
 scl = 1; sda = 1;
9
// wait 5us
10
 sda = 0;
11
12
/* STOP */
13
 scl = 0;
14
// wait 5us
15
 sda = 0;
16
// wait 5us
17
 scl = 1;
18
// wait 5us
19
 sda = 1;
20
21
/* WRITE BYTE */
22
#define chk_bit(var,pos) (((var)>>(pos)) & 1)
23
 for(uint8_t bitcnt=0; bitcnt<8; bitcnt++) {
24
   scl = 0;
25
   if chk_bit(Byt2Wrt, bitcnt) { sda = 1; }
26
   else { sda = 0; }
27
// wait 5us
28
   scl = 1;
29
// wait 5us 
30
 }
31
 scl = 0;
32
// --- ACK --- 
33
// sda pin = input, pullup
34
// wait 15us
35
 scl = 1;
36
// wait 5us
37
 scl = 0;
38
// sda pin = output, high

 Alles andere steht im DaBla.

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?

Hm, laut Beschreibung ist das ein TM1637 und mein Code sollte darauf 
funktionieren. Der Link von oben funktioniert tatsächlich nicht mehr 
(das war das Datenblatt) , aber die Software ist ja noch da und wenn dir 
das genauer anschaust, solltest du daraus auch Arduino machen können.

von Anja (Gast)


Lesenswert?

Vielen Dank Marc,

ein Datenblatt hätte ich auch gerne....

Ich werde Deinen Vorschlag ausprobieren, bin mal gespannt, ob ich das 
hinbekomme. Werde auf jeden Fall berichten.

Kannnst Du mir sagen, warum das mit dem I2C Hardware nicht funktioniert? 
Das Display hat (kann man auf dem Foto erkennen) schließlich auch die 
I2C -Pins SCL und SDA (anders als in der Beschreibung zum Display 
steht).

VG, Anja

von Horst (Gast)


Lesenswert?

Anja schrieb:
> ein Datenblatt hätte ich auch gerne....

https://www.mcielectronics.cl/website_MCI/static/documents/Datasheet_TM1637.pdf

Anja schrieb:
> Kannnst Du mir sagen, warum das mit dem I2C Hardware nicht funktioniert?

Weil nicht jede serielle Schnittstelle mit Clock und Data I2C ist.
Der TM1637 hat keine I2C-Schnittstelle.

von Rudi M. (Gast)


Lesenswert?

Anja schrieb:
> Kannnst Du mir sagen, warum das mit dem I2C Hardware nicht funktioniert?
> Das Display hat (kann man auf dem Foto erkennen) schließlich auch die
> I2C -Pins SCL und SDA (anders als in der Beschreibung zum Display
> steht).

Lies doch noch mal den allerersten Post von Ralph, da erklärt er es.
Beitrag "TM1637, 4-stellige LED 7-Segmentanzeige mit AVR-GCC"
In der Software ist das schon berücksichtigt.

von Horst (Gast)


Lesenswert?

Rudi M. schrieb:
> Lies doch noch mal den allerersten Post von Ralph, da erklärt er es.

Die Erklärung ist aber komplett falsch. Das Verhalten ist nicht 
'merkwürdig', I2C ist einfach die falsche Schnittstelle. Das Programm 
macht auch kein Soft-I2C sondern eher ein Soft-SPI.
I2C ist deutlich mehr als an einem Pin zu Wackeln und dem anderen die 
Daten rauszuschieben.

von jjflash (Gast)


Lesenswert?

Das Datenblatt hatte ich noch einmal hier mit angefügt gehabt, weil der 
Link tot war:

Beitrag "Re: TM1637, 4-stellige LED 7-Segmentanzeige mit AVR-GCC"

Die Software und ein Beispiel fandest du ganz im ersten Thread (der ist 
zwar C-Code und kein Arduino Sketch, zeigt aber sehr genau wie das 
funktioniert).

Anja schrieb:
> Kannnst Du mir sagen, warum das mit dem I2C Hardware nicht funktioniert?
> Das Display hat (kann man auf dem Foto erkennen) schließlich auch die
> I2C -Pins SCL und SDA (anders als in der Beschreibung zum Display
> steht).

Jetzt wird es schwierig, ich glaube aufgrund des Arduino-Frameworks und 
wie es augebaut ist, geht es mit Arduino und der Hardware tatsächlich 
nicht.

Prinzipiell jedoch kann man eine I2C Hardware (egal welchen Chips, es 
muss ja nicht immer AVR sein) verwenden, aaaaaaaber:

Auf einem I2C Bus wird normalerweise das höchstwertigste Bit zuerst 
versendet, der TM1637 Chip will aber zuerst das niederwertigste Bit 
haben. Bei vielen Controllern mit I2C Hardware kann man die Reihenfolge 
einstellen, würde also immer noch mit der Hardware zu verschicken sein.

Die größte Abweichung zu I2C ist: der TM1637 Chip hat keine 
Deviceadresse, das heißt, bei einer Busaktivtät antwortet der CHIP 
immer, auch dann, wenn man eigentlich eine Adresse sendet.

Das heißt: ich kann die I2C Hardware eines Controllers verwenden, wenn 
der TM1637 Chip seine Bitreihenfolge mit LSB first erhält (im Gegensatz 
zum I2C Standard) UND wenn der chip der einzige ist, der am I2C Bus 
angehängt ist.

Aus diesem Grunde hatte ich mich damals zu einem Bitbanging für den 
TM1637 entschieden gehabt.

Gruß Ralph

von jjflash (Gast)


Lesenswert?

Horst schrieb:
> Die Erklärung ist aber komplett falsch. Das Verhalten ist nicht
> 'merkwürdig', I2C ist einfach die falsche Schnittstelle. Das Programm
> macht auch kein Soft-I2C sondern eher ein Soft-SPI.
> I2C ist deutlich mehr als an einem Pin zu Wackeln und dem anderen die
> Daten rauszuschieben.

Schmunzeln muss: können wir uns darauf einigen, dass es ein proprietäres 
serielles Protokoll ist?

Gegen ein SPI würde beispielsweise sprechen, dass beim TM1637 auf der 
gleichen Leitung Daten gesendet und gelesen werden. Hierfür würde ein 
SPI ein MOSI / MISO verwenden.

von Horst (Gast)


Lesenswert?

jjflash schrieb:
> Gegen ein SPI würde beispielsweise sprechen, dass beim TM1637 auf der
> gleichen Leitung Daten gesendet und gelesen werden

Also 3-Wire-SPI.

@Ralph:
Du beschreibst ganz richtig, warum es kein I2C ist, es fehlen nur die 
Unterschiedlichen Hardwareeigenschaften (OpenCollector/Drain, 
bidirektionale Clock...), und bezeichnest es doch weiter als I2C. Warum?
Es ist einfach eine synchrone serielle Verbindung.
Und die ließe sich, auch auf dem Arduino, in SPI-Hardware einfacher 
umsetzen als in I2C.

von Axel S. (a-za-z0-9)


Lesenswert?

jjflash schrieb:
> Horst schrieb:
>> Die Erklärung ist aber komplett falsch. Das Verhalten ist nicht
>> 'merkwürdig', I2C ist einfach die falsche Schnittstelle. Das Programm
>> macht auch kein Soft-I2C sondern eher ein Soft-SPI.
>> I2C ist deutlich mehr als an einem Pin zu Wackeln und dem anderen die
>> Daten rauszuschieben.
>
> Schmunzeln muss: können wir uns darauf einigen, dass es ein proprietäres
> serielles Protokoll ist?
>
> Gegen ein SPI würde beispielsweise sprechen, dass beim TM1637 auf der
> gleichen Leitung Daten gesendet und gelesen werden. Hierfür würde ein
> SPI ein MOSI / MISO verwenden.

Es ist ganz sicher kein SPI. Aber auch kein korrektes I²C. Die Bit- und 
Framesignalisierung ist zwar wie bei I²C. Das Protokoll hingegen ist 
ganz anders. Siehe Bitreihenfolge. Siehe fehlendes Adreßbyte.

Die Unterschiede zu SPI sind aber größer. Es sind nur zwei Leitungen zum 
Lesen, Schreiben und zur Framesignalisierung. SPI bräuchte 3 Leitungen 
zum Lesen und Schreiben, sowie eine 4. (Slave-Select) für die 
Signalisierung von Frame-Start bzw. -Ende.

von Ralph S. (jjflash)


Lesenswert?

@Horst: ich bezeichne es nicht weiter als I2C... und werde auch die Doku 
dazu ändern. Mein erstes Modul wurde mir als I2C verkauft und war dann, 
wie wir jetzt alle wissen keines.

Nach Datenblatt des TM Bausteines benötigt er aber auch PullUp 
Widerstände, was beim Host Open Drain erfordert, unter anderem auch 
deswegen, weil der TM Acknowlege sendet.

Das "Merkwürdig" bezog sich von mir auf den Chiphersteller, warum er so 
viele Ähnlichkeiten zu I2C aufweißt, aber dann eben doch keines ist (und 
wie wir beide wissen) auch kein SPI ist. Synchrones, bidirektionales 
serielles System (das ich so nur auf dem TM Chip gesehen habe). Noch 
merwürdiger von Seiten des Chipherstellers ist aus meiner Sicht der 
Dinge ein Baustein TM1638. Ich hatte von der Serie gedacht gehabt, dass 
die alle nach deselben Protokoll funktionieren und es war Pustekuchen: 
Er hat zwar fast identsche Controll-, Adress- und Statusregister, aber 
der Datentransfer erfordert ein zusätzliches Strobe zur Übernahme eines 
internen Latches.

Für Anja werde ich nächste Woche mal auf Suche gehen was sie für ein 
Modul har. Bisher hatte ich nur welche mit 4 oder 8 stelliger 7 
Segmentanzeige (aber nicht mit 6).... Und wie ich schmerlich gelernt 
habe bisweilen komplett unterschiedlich verdrahtet.

Dann werde ich mal sehen, wie universell ich das machen kann, auch im 
Bezug auf das Auslesen eines Keypads. In ihrem Fall vermute ich sogar 
aufgrund der vielen Anschlusspins, dass die Anzeige über den TM1637 
läuft, aber die Tasten auf die Anschlußpins des Moduls direkt gelegt 
worden sind.

von Anja (Gast)


Lesenswert?

Hallo zusammen,
vielen Dank für Eure Hilfe.
Ich habe das Display mit Hilfe der "TM1637_6D" -Libary zum Laufen 
bekommen (ohne die I2C-HW PIN).
Jetzt stehe ich allerdings vor dem Problem die Tasten auszulesen. Die 
sind jedenfalls nicht an den PINs ausgeführt sondern müssen ebenfalls 
über DIO ausgelesen werden.
Hat jemand Erfahrung hiermit?

Gruß, Anja

von Ralph S. (jjflash)


Lesenswert?

Wenn ich einen Schaltplan davon hätte könnte ich dir (wahrschreinlich) 
auch helfen, habe ich aber nicht (und ich werde auch kein weiteres Modul 
mit TM16xx kaufen).

Wenn die Tasten wie im Datenblatt angeschlossen sind, wird dir das hier 
vllt. helfen:

Beitrag "Siebensegment und Tasten ansteuern mit TM1651 \ TM1637"

von Anja (Gast)


Lesenswert?

Vielen Dank Ralf,
das hilft mir bestimmt weiter.
Ich werde mich da mal durchbeißen.

von Anja (Gast)


Lesenswert?

Hallo in die Runde,
wenn es noch jemanden gibt, der versucht das keyScan-Modul zu nutzen...

Hier gibt es die passende Library dazu:

https://github.com/Erriez/ErriezTM1637/

von Klaus R. (klaus2)


Lesenswert?

...kennt jmd einen in D verfügbaren I2C LED Treiber als fertiges Board 
mit dem man "recht schnell" ohne Arduino zeug eine 7 seg ansteuern kann? 
Nein, ich möchte mir eigentlich keine mutliplexingtabelle dafür selber 
bauen, am besten ich geb der lib die zahlen und die Position und die 
tauchen dann dort auf :)

EDIT: Hm, vll wäre HX16K33 eine Option, aber den gibt's als "Shield" 
hier auch nicht wirklich...zumindest nicht zu einem fairen preis, alles 
nur +500%.

Klaus.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.