TM1637, 4-stellige LED 7-Segmentanzeige mit AVR-GCC

OP #4503405
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
Angehängte Dateien:
Gast #4504261
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
Gast #4505540
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
OP #4507754
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
OP #5270572
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).
Gast #5270693
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
OP #5270746
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.
Gast #5384942
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.
OP #5781435
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.
(Firma: Vescomp) #5781533
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.
OP #5781665
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.
Gast #5781668
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
Gast #5781691
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.
Gast #5781712
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.
Gast #5781716
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
Gast #5781722
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.
Gast #5781753
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.
#5781880
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.
OP #5782172
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.
Gast #5783076
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
#6204836
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren