66-SPI_HD-TM1638-Library (STM32F4)

Wer bei Ebay (oder wo auch immer) eine externe IO-Platine mit dem TM1638-Chip gekauft hat, kann diese Library benutzen.

Auf der Platine sind (neben dem Controller) :
8x 7Segment-Anzeige
8x rote LEDs
8x Buttons

Der Controller wird über SPI (im Half-Duplex-Mode) angesteuert, aus dem Grund wird die LoLevel-Library (STM32_SPI_HD) benötigt. Im Beispiel habe ich SPI2 benutzt.

Die Funktionen sollten eigentlich selbsterklärend sein. Im Notfall im Quellcode die Kommentare lesen.

Beispielbild :

tm1638

Benutzte Pins :

1
2
3
SCK an PB13
DIO an PB15
ChipSelect an PB12

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO
Benutzte Librarys : STM32_UB_SPI2_HD

Funktionen :

1
2
3
4
5
6
7
8
9
10
ErrorStatus UB_TM1638_Init(void);                               // init vom TM1638
void UB_TM1638_Display_Off(void);                               // Display ausschalten
void UB_TM1638_Display_On(uint8_t pwm);                         // Display einschalten (mit Helligkeit)
void UB_TM1638_LED_On(uint8_t led_nr);                          // um eine einzelne LED einzuschalten
void UB_TM1638_LED_Off(uint8_t led_nr);                         // um eine einzelne LED auszuschalten
void UB_TM1638_LED_Value(uint8_t wert);                         // um eine 8bit-Zahl an den LEDs auszugeben
void UB_TM1638_7Seg_Ziffer(uint8_t segment_nr, uint8_t ziffer); // um eine einzelne 7Segment anzusteuern
void UB_TM1638_7Seg_Dec(uint32_t wert);                         // eine Dezimalzahl an den 7Segment ausgeben
void UB_TM1638_7Seg_Hex(uint32_t wert);                         // eine Hex-Zahl an den 7Segment ausgeben
uint8_t UB_MT1638_Get_Key(void);                                // um alle 8Buttons einzulesen

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//--------------------------------------------------------------
// File     : main.c
// Datum    : 01.01.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.4
// GCC      : 4.7 2012q4
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der TM1638-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_tm1638.h"
 
int main(void)
{
  uint8_t wert;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init vom TM1638
  UB_TM1638_Init();
 
  // Display einschalten (niedrigste Helligkeit)
  UB_TM1638_Display_On(0);
 
  // 8Stellige Hex-Zahl anzeigen
  UB_TM1638_7Seg_Hex(0x1234ABCD);
 
  while(1)
  {
    // status der 8Tasten abfragen
    wert=UB_MT1638_Get_Key();
    // an den 8LEDs ausgeben
    UB_TM1638_LED_Value(wert);
  }
}

Hier die Library zum Download :

ub_stm32f4_spi_hd_tm1638_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_66_SPI_HD_TM1638


6 Antworten auf 66-SPI_HD-TM1638-Library (STM32F4)

  1. ManiB sagt:

    Hi Uwe,

    tolle Umsetzung!

    Das LED KEY Modul gibt’s zur Zeit bei eBay für 7,29 €:

  2. Joerg sagt:

    Auf Ebay.com noch 2 € günstiger

    • Joerg sagt:

      wow das war mal schnell, am 17.Okt. bestellt und heute in der Post :D

  3. Fabrice Muller sagt:

    Hallo ,
    Ich habe diese Modul zeit heute morgen aber mit der stm429 Discovery ist der
    SPI2 nicht frei :)
    Als ich sehen der SPI4 wurde ok aber deine neues library ist für full duplex Mode und
    die alter SPI für stm407 was für half-Duplex Mode :)
    Ist hier möglich das einfach zu benutzen mit deine neues SPI library ?

    MFG.

    Fabrice.

    • Fabrice Muller sagt:

      Erledigt :)
      Ich sende dir der spi4_hd und tm1638 lib für stm429 via gmail.

      MFG.

      Fabrice.

      • admin_ub sagt:

        Danke, gesehen und upgedated.


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (1 Bewertungen, Durchschnitt: 5,00 von 5)
Loading...

17 Antworten zu 66-SPI_HD-TM1638-Library (STM32F4)

  1. ali sagt:

    Hallo @All,
    kommen da keine widerstände etc. dazwichen ?

    SCK an PB13
    DIO an PB15
    ChipSelect an PB12

    Wie ist Es mit den Spannungspegel zwichen dem STM32F4(,3,v) und TM1638(5,0v) .

    Mfg Ali

    • admin_mb sagt:

      Hi Ali,
      ja, das Modul muss an 5V betrieben werden. Laut TM1638 Datenblatt ist die minimale HIGH Spannung 0.7*Vcc, also ca. 3.5V (High level input voltage). Und die IO-Pins am Mikrocontroller sind TTL resistent. Also kannst du das Modul direkt anschließen;)

  2. Ali sagt:

    Hallo @admin_mb,

    habe Es gerade nochmal nachgeschaut diese GPIO sind tatsächlich 5Volt(TTL) tolerant.
    Das ist Toll dann kann ich mir einen Pegelwandler sparen.

    ps.: Habe die Library nocht nicht angeschaut und kenne bisher nur Full-Duplex-Mode.

    Nur aus neugier wie funktionert das Empfangen mit nur 1 Datenleitung (SPI im Half-Duplex-Mode).

    Mfg Ali

  3. Ali sagt:

    Hallo @admin_mb,

    habe Es mir angeschaut und stelle Es mir so vor:

    IO(out) –> Senden #–> Warten #–> IO(IN) –> Empfangen.
    ————————————————————————
    Die epochale Erkenntnis von mir ist das Es auch mit einer Spannung von 3,3 Volt funktioniert.
    (Optional: Ich habe zwichen den GPIO verbindungen noch 1Kohm eingefügt)
    ————————————————————————
    Wie steuert mann eigentlich die Punkt LED an der 7Segment-Anzeige.

    Mfg Ali

    • admin_mb sagt:

      Die Library bietet dieses Feature leider nicht;( Man müsste die folgenden drei Funktionen um einen neuen Parameter erweitern, über den man dann in der Funktion das achte Bit des Wertes setzt, welches in das RAM geschrieben wird:
      void UB_TM1638_7Seg_Ziffer(uint8_t segment_nr, uint8_t ziffer, uint8_t dp);
      void UB_TM1638_7Seg_Dec(uint32_t wert, uint8_t dpp);
      void UB_TM1638_7Seg_Hex(uint32_t wert, uint8_t dpp);

      //--------------------------------------------------------------
      // gibt eine einzelne HEX-Ziffer an einer 7Segment aus
      // (oder schaltet eine 7Segment dunkel)
      // segment_nr : [0...7]
      // ziffer     : [0...15, 16=OFF]
      // dp         : [0..1] Dezimalpunkt aus bzw. ein.
      //--------------------------------------------------------------
      void UB_TM1638_7Seg_Ziffer(uint8_t segment_nr, uint8_t ziffer, uint8_t dp)
      {
        uint8_t adr,wert;
      
        if(segment_nr>7) segment_nr=7;
        if(ziffer>16) ziffer=16;
      
        adr=(segment_nr << 1); // Seg0=0, Seg1=2, Seg2=4, Seg7=14
        wert=HEX_7SEG[ziffer];
        if (dp) wert|=0x80;
      
        P_TM1638_WriteRAM(adr,wert);
      }
      
      //--------------------------------------------------------------
      // gibt eine Zahl als Dezimalwert
      // an der 7Segment-Anzeige aus
      // dpp : [0..8] Dezimalpunkt-Position aus bzw. 1 bis 8
      //--------------------------------------------------------------
      void UB_TM1638_7Seg_Dec(uint32_t wert, uint8_t dpp)
      {
        uint8_t n;
        uint8_t dp;
      
        if(wert>99999999) wert=99999999;
      
        for(n=0; n < 8; n++) {
          if (8-n==dpp) dp=1; else dp=0;
          UB_TM1638_7Seg_Ziffer(7-n,wert % 10, dp);
          wert /= 10;
        }
      }
      
      //--------------------------------------------------------------
      // gibt eine Zahl als Hexwert
      // an der 7Segment-Anzeige aus
      // dpp : [0..8] Dezimalpunkt-Position aus bzw. 1 bis 8
      //--------------------------------------------------------------
      void UB_TM1638_7Seg_Hex(uint32_t wert, uint8_t dpp)
      {
        uint8_t n;
        uint8_t dp;
      
        for(n=0; n < 8; n++) {
          if (8-n==dpp) dp=1; else dp=0;
          UB_TM1638_7Seg_Ziffer(7-n,(wert & 0x0F),dp);
          wert >>= 4;
        }
      }
      
  4. Ali sagt:

    Hallo @admin_mb,
    dem zu folge ist der Wert für dpp 0x80 .
    ein kleiner fehler ist in der folgenden zeile: adr=(segment_nr< <1);

    Ein Leerzeichen hat sich eingeschlichen so ist Es richtig: adr=(segment_nr<<1);

    Die erste Punkt LED istbei dir ganz rechts an der 7Segment-Anzeige .

    Durch veränderung der Abfragen vom dpp habe ich Es nach links gesetzt:

    if (8-n==dpp) dp=1; else dp=0;

    Ansonsten funktioniert Alles bestens !!!

    Vielen Dank nochmals für deine Mühe.

    Mfg Ali

    • admin_mb sagt:

      Hi Ali, ich bin stolz auf dich!
      Ja, ich hatte die drei Funktionen ungeprüft in meinem Kommentar angegeben – und es freut mich umso mehr, dass es funktioniert;)

      Preisfrage: Beim Blick auf den TM1638 Schaltplan sollte klar werden, warum der Wert 0x80 den Dezimalpunkt aufleuchten lässt.
      Wer kennt die Antwort?
      TM1638 Schaltplan
      Quelle: os.mbed.com

  5. Ali sagt:

    Hallo @admin_mb,
    SEG8 ist Bit7.

    Habe mir das Datasheet zum TM1638 doch mal genauer angeschaut und wollte die Library mal genauer nachvolziehen . (Library funktioniert)

    Irgendwie stimmt das mit der Tabelle vom Datasheet (Seite:4 und Figure:4) und der Library(Tastaturabfrage) nicht überein.

    Habe mal die Register 1 bis vier einzeln ausgelesn und bekomme folgendes:
    BYTE1(KS1 + KS5)
    BYTE2(KS2 + KS6)
    BYTE3(KS3 + KS7)
    BYTE4(KS4 + KS8)

    und im DATASHEET vom TM1638 steht folgendes :
    BYTE1(KS1 + KS2)
    BYTE2(KS3 + KS4)
    BYTE3(KS5 + KS6)
    BYTE4(KS7 + KS8)

    Was stimmt hier nicht?
    Wer kennt die Antwort?

    ps.: Wäre Es möglich den STM32f103C8T6 auch mit aufzunehmen?

    Mfg Ali

    • admin_mb sagt:

      Hallo Ali,
      die acht Tasten auf der Platine sind alle dem Eingangszustand K3 zugeordnet. Wenn also die 4Byte Key-Daten nacheinander gelesen werden, sind jeweils die Werte der Bits B0 und B4 für uns von Interesse:
      1. Bits B0 und B4 vom ersten Byte entsprechen Bits B0 und B4 der gedrückten Tasten
      2. Bits B0 und B4 vom zweiten Byte entsprechen Bits B1 und B5 der gedrückten Tasten
      3. Bits B0 und B4 vom dritten Byte entsprechen Bits B2 und B6 der gedrückten Tasten
      4. Bits B0 und B4 vom vierten Byte entsprechen Bits B3 und B7 der gedrückten Tasten
      Wenn du mehr über das TM1638 Modul wissen willst, dann schau mal diese Blog Seite von Michael Williamson an.

  6. ali sagt:

    Hallo @admin_mb,

    sehr gut erklärt, soweit habe ich bisher Deine Erklärung begriffen.

    Nur die angegebene reihenfolge in der Tabelle im Datenblatt vom TM1638 kann ich nicht beobachten.

    zb.: 1.BYTE <<B4<<KS2(TASTER 2)
    ist bei mir folgendes :1.BYTE <<B4<<KS5(TASTER 5)

    Ich scheine nicht der einzige damit zu seien.

    Habe dazu folgendes gefundes gefunden:
    Ganz unten im Dateianhang ist eine PDF-Datei
    http://forum.g-heinrichs.de/viewtopic.php?t=108

    In der PDF-Datei auf der Seite 8
    ist die Tabelle so wie ich das auch bei mit beobachte !

    Mfg Ali

  7. ali sagt:

    Hallo @admin_mb,

    ich glaube das ich Es gelöst habe.

    Die Tabelle im Datenblatt vom TM1638 stimmt doch.

    Auf dem LED&KEY-Modul sind die Tasten S1 bis S8 nicht eins zu eins mit SEG1 bis SEG8 verbunden!!

    Sondern folgendermasen:
    SEG1= Taster1 ## SEG2= Taster5
    SEG3= Taster2 ## SEG4= Taster6
    SEG5= Taster3 ## SEG6= Taster7
    SEG7= Taster4 ## SEG8= Taster8

    Somit sind unsere Beobachtungen auch Richtig:

    BYTE1 (B0=SEG1(KS1)–> Taster1 ## B4=SEG2(KS2)–> Taster5)
    BYTE2(B0=SEG3(KS3)–> Taster2 ## B4=SEG4(KS4)–> Taster6)
    BYTE3(B0=SEG5(KS5)–> Taster3 ## B4=SEG6(KS6)–> Taster7)
    BYTE4(B0=SEG7(KS7)–> Taster4 ## B4=SEG8(KS8)–> Taster8)

    Mfg Ali

    • admin_mb sagt:

      Hi Ali,
      na dann können wir ja heute alle beruhigt schlafen gehen;)
      Prima, mach weiter so!
      PS: Jetzt, wo du das TM1638 praktisch wie deine Hosentasche kennst, wie wäre es mit einer kleinen Herausforderung?
      Hier hat jemand das Simon Game umgesetzt. Was meinst du, bekommst du sowas auch zum Laufen?

  8. Paul Veldhuijzen van Zanten sagt:

    Es gibt noch einen Fehler in den Function digit2segment(). Die richtige code ist:
    uint8_t digit2segment( uint8_t digit )
    {
    uint8_t segments = 0;
    if ( digit < 16 ) {
    segments = HEX_7SEG[ digit ];
    }
    else if ( digit < 32 ){
    segments = HEX_7SEG[ digit-16 ]; // hinzugefügt
    segments |= 0x80; //add point
    }
    else {
    segments = HEX_7SEG[ 16 ]; //off // ändert
    }
    return segments;
    }

  9. Manouchehr sagt:

    Hallo,
    bei mir funktiniert alles ausser Key Scannen. Ich bekommen immer nur 4 Bytes „FF“ zurück. Ich verwende SPI half-duplex.
    Ich habe mit 1 MHz ausprobiert und ich habe immer 5 Bytes zurück bekommen. Meine Clk Frequenz ist aktuell 62.5 KHz und damit bekomme ich 4 Bytes zurück aber immer alle 4 Bytes sind „FF“. Egal ob ich die Tasten drücke oder nicht.
    Kann Jemand mir helfen?
    Viele Grüße
    Manouchehr

  10. Manouchehr sagt:

    Es hat sich erledigt. Ich habe in „ReadKEY“ Funktion den „STB“ PIN auf „0“ halten müssen.
    Übrigens SPI clk darf nicht weniger als 62.5 KHz sein.
    Viele Grüße

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert