Forum: Mikrocontroller und Digitale Elektronik TM1638 - AVR ASM Library


von Ralf J. (cosmicos)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe mir neulich auf ebay ein 8-fach 7-Segment-Modul mit einem 
TM1638 LED-Treiber gekauft.

Da ich gerade Assembler lerne, dachte ich mir, dass das es ein schönes 
Übungsprojekt wäre, dafür einen Treiber zu schreiben.

Gedacht... getan :-)

Der Treiber unterstützt  z.Zt. nur die "Common Cathode" Version des 
Moduls. "Common Anode" habe ich noch in Arbeit, dort ist die Ansteuerung 
schwieriger zu realisieren...

Die CC-Version funzt aber inzwischen sehr gut und man kann alle LED 
gezielt ansteuern, Zahlen als Hex, Dez und Bin ausgeben, sowie Texte als 
Laufschrift erscheinen lassen.

Das Demo im Anhang zeigt die Möglichkeiten:

https://drive.google.com/open?id=0Bztkubpzy4YtUTc5OFdManBwM0U

Da es sich um mein erstes AVR-ASM Projekt handelt würde ich mich über 
konstruktive Kritik sehr freuen. Es ist sicherlich nicht alles optimal 
z.B. hätte ich in der Sendeschleife das Carry-Flag verwenden können 
statt umständliche Logik zu programmieren. Daran sieht man, dass der 
Treiber Teil meines Lernprozesses ist...

Die Routinen zur Zahlenausgabe habe ich aus dem Tutorial genommen und an 
meinen Code angepasst. Man muss das Rad ja nicht jedesmal komplett neu 
erfinden. Der gesamte übrige Code (also der Treiber an sich...) ist auf 
meinen Mist gewachsen...

Ich freue mich auf Feedback!
Viele Grüße
Ralf

: Bearbeitet durch User
von Ralf J. (cosmicos)


Lesenswert?

Ich habe wohl einen falschen Link zum Demo kopiert :(

Der hier sollte funktionieren:

https://drive.google.com/file/d/0Bztkubpzy4YtUTc5OFdManBwM0U/view?usp=sharing


Und noch kurz ein paar Infos zum TM1638:

- Treiber für max. 10(!) 7-Segment-Anzeigen mit gemeinsamer Anode oder 
Kathode
- Kann außerdem max. 16 Taster abfragen (noch nicht im Code integriert)
- keine weiteren Bauteile erforderlich (Widerstände o. Transistoren)
- Ansteuerungen über 3 Leitungen (SPI-ähnlich). Strobe, Clock und Data
- Helligkeit per Display-Control-Command einstellbar
- Chips sind kaskadierbar mit je einer Strobe-Leitung per Chip
- günstig (<1€ vom Chinamann)

: Bearbeitet durch User
von Ralf J. (cosmicos)


Lesenswert?

Eine Frage:

Ich stieß beim Programmieren auf einen Assembler-Fehler, den ich mir 
nicht erklären kann.

Der Übersichtlichkeit halber verwende ich folgende Deklarationen:
1
.EQU  STB_PIN  =  PA0 ; TM1638 strobe input
2
.EQU  CLK_PIN  =  PA1 ; TM1638 clock input
3
.EQU  DATA_PIN =  PA2 ; TM1638 data input/output
4
5
ldi   AKKU, (1<<STB_PIN)|(1<<CLK_PIN)|(1<<DATA_PIN)

Das funktioniert!

1
.EQU DATA_CMD   = 0x40;
2
.EQU FIXED_ADDR = 0x04;
3
4
ldi    TM1638_DATA_BYTE, (1<<DATA_CMD)|(1<<FIXED_ADDR)

Dies funktioniert ebenfalls!

1
.EQU  DISP_CTRL_CMD  =  0x80
2
.EQU  DISP_PWM_MASK  =  0x03 ; first 3 bits are brightness (PWM)
3
.EQU  DISP_ON        =  0x08
4
5
ldi TM1638_DATA_BYTE, (1<<DISP_CTRL_CMD)|(1<<DISP_ON)|(1<<DISP_PWM_MASK)

Das letzte Konstrukt führt jedoch zu einer Assembler-Warnung (Constant 
out of Range o.ä.) und führt auch nicht zum gewünschten Ergebnis.


Wie kann das sein? Eine Oder-Verknüpfung von 0x80|0x03|0x08 ergibt doch:

1  0  0  0  0  0  0  0  0
0  0  0  0  0  1  0  0  0
0  0  0  0  0  0  0  1  1

------------------------

1  0  0  0  0  1  0  1  1

...also keinswegs "out of Range". Ich sehe auch keinen Unterschied zum 
2. Beispiel, welches ja funktioniert!?

Stehe gerade auf dem Schlauch :(

Nachtrag: Ich verwende avra unter Linux!

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

Also bei mir hat ein Byte 8 Bit (Bit7 ... Bit0)

>Das funktioniert!

>.EQU DATA_CMD   = 0x40;
>.EQU FIXED_ADDR = 0x04;

>ldi    TM1638_DATA_BYTE, (1<<DATA_CMD)|(1<<FIXED_ADDR)

Bezweifle ich:

1<<DATA_CMD schiebt eine 1 nach Bit64


>...also keinswegs "out of Range". Ich sehe auch keinen Unterschied zum
>2. Beispiel, welches ja funktioniert!?

Hier das gleiche

>.EQU  DISP_CTRL_CMD  =  0x80
>.EQU  DISP_PWM_MASK  =  0x03 ; first 3 bits are brightness (PWM)
>.EQU  DISP_ON        =  0x08

1<<DISP_CTRL_CMD -> Schiebt eine 1 zum Bit 128
1<<DISP_PWM_MASK)-> Schiebt eine 1 zum Bit 8

MfG Spess

von Ralf J. (cosmicos)


Lesenswert?

spess53 schrieb:
> Also bei mir hat ein Byte 8 Bit (Bit7 ... Bit0)

Bei mir selbstverständlich auch. Ich hatte mich da ganz offensichtlich 
vertippt.

spess53 schrieb:
> 1<<DISP_CTRL_CMD -> Schiebt eine 1 zum Bit 128
> 1<<DISP_PWM_MASK)-> Schiebt eine 1 zum Bit 8

Ok, das erklärt es. Danke!

von Eberhard H. (sepic) Benutzerseite


Lesenswert?

Dafür, dass du offensichtlich AVR-Assembler-Anfänger bist, schaut das 
Ergebnis schon recht gut aus.
Ein paar Dinge sind mir bei tm1638_cc.asm aufgefallen (nachdem du ein 
Feedback möchtest):

Gibt es einen Grund, warum du Bit-Banging statt SPI verwendest?
Ggf. könnte man beide Varianten per Assembler-Direktiven verwirklichen.

Ab TM1638_PRINT_DEC lassen die Kommentare ziemlich nach. ;-)
So solltest du u.a. auch kommentieren, wie du das T-Flag verwendest.

Im Source-Code wird manchmal per Leerzeichen getrennt, manchmal per TAB, 
manchmal sogar mit beiden nacheinander. Schöner wird es einheitlich mit 
TABs bis zum Kommentar (wie es bei dir oft, aber nicht immer der Fall 
ist).

Bei delay.inc scheint ein kleiner Fehler zu sein, denn für Delay1s wird 
das Unterprogramm Delay10ms 255 mal durchlaufen.

Delay1 soll (naheliegenderweise) vermutlich Delay100ms lauten (muss dann 
natürlich auch bei den Aufrufen geändert werden).

Die diversen aus der CPU-Frequenz berechneten .equ für die Zahl der 
Schleifendurchgänge könnte man noch etwas übersichtlicher an den Anfang 
von delay.inc stellen anstatt zwischen den Assembler-Befehlen.

Den Rest habe ich bislang nicht angeschaut.

Gute Fortschritte!

von Ralf J. (cosmicos)


Lesenswert?

Hallo Eberhard,

zunächst mal vielen Dank für dein Feedback!

Eberhard H. schrieb:
> Gibt es einen Grund, warum du Bit-Banging statt SPI verwendest?
> Ggf. könnte man beide Varianten per Assembler-Direktiven verwirklichen.

Als ich mir das Datenblatt des Chips anschaute, hatte ich das Protokoll 
nicht sogleich als SPI erkannt (Anfänger...). Daher kam mir die 
Verwendung des Hardware-SPI zu diesem Zeitpunkt gar nicht in den Sinn.
Die Erleuchtung kam dann erst mit der Analyse meines Bit-Banging Codes 
mittels Logic-Analyzer. Zu diesem Zeitpunkt war die Senderoutine aber 
schon fertig, so dass ich keine Lust mehr hatte sie auf Hardware-SPI 
umzustellen.

Ich schaue mir das aber auf jeden Fall noch an.

Eberhard H. schrieb:
> Ab TM1638_PRINT_DEC lassen die Kommentare ziemlich nach. ;-)
> So solltest du u.a. auch kommentieren, wie du das T-Flag verwendest.

Ja. TM1638_PRINT_DEC, ...PRINT_HEX und ...PRINT_BIN habe ich ja dem 
Tutorial hier auf mikrocontroller.net entnommen und lediglich angepasst. 
Ich hatte den Code natürlich analysiert, dann aber nicht mehr daran 
gedacht, ihn zu kommentieren.
Das hat sich dann leider auch in meinem weiteren Code so fortgesetzt. Da 
muss ich auf jeden Fall disziplinierter arbeiten!

Gleiches gilt für die Code-Formatierung. Ich verwende z.Zt. Geany unter 
Linux und da habe ich erst vor kurzem die Funktion gefunden, die mir 
Steuerzeichen anzeigen lassen kann. Sehr hilfreich :-)

Die Delay-Routinen habe ich auch nur auf die Schnelle reingefummelt, 
daher die inkonsistente Benennung.

Eberhard H. schrieb:
> Gute Fortschritte!

Danke! Es macht aber auch einen Riesen-Spaß :-)
Eines meiner vorrangigen Ziele war, Chips (z.B. Display-Treiber bzw. 
Controller) nach Datenblatt programmieren zu können. Ich war es leid, 
z.B. bei C-Projekten immer nach Librarys für die verwendeten Bausteine 
suchen zu müssen. Viel spannender erschien es mir, so etwas auch selber 
zu können und zu machen.

Viele Grüße
Ralf

von Ralf J. (cosmicos)


Angehängte Dateien:

Lesenswert?

Eberhards Vorschlägen folgend habe ich nun folgendes verändert:

1. Hardware SPI-Senderoutine per Assembler-Direktive implementiert.
1
#define BITBANGING

Damit wird der Bitbanging-Code assembliert, ansonsten der SPI-CODE.

2. Die Formatierung des Quelltextes ist nun vereinheitlicht (Tabs).

3. Der Quelltext ist weiter kommentiert (Zahlenausgaben: siehe Tutorial 
hier im Board).

Des Weiteren ist es mir nun auch gelungen, die Leuchtdiodenleiste (die 8 
Einzeldioden) oberhalb der 7-Segmentanzeigen anzusteuern.

Democode: TM1638_LEDS

https://drive.google.com/file/d/0Bztkubpzy4YtOUswaTZBVWp4RVU/view

von spess53 (Gast)


Lesenswert?

Hi

Da geht einiges in Bezug auf Hauptprogramm und Library durcheinander. 
Eine   Library sollte per .include in das das Hauptprogramm eingebunden 
werden und nicht umgedreht. Das heißt z.B. in der Lib haben '.INCLUDE 
"m32def.inc"', Interruptvektortabelle, ... nichts zu suchen. Das gehört 
ins Hauptprogramm.

In vielen Fällen ist es notwendig die Library in einen Teil mit 
Konstanten und einen Teil mit dem Librarycode aufzuteilen. Die 
Konstanten werden vor und der Code nach dem Hauptprogramm includiert.


>2. Die Formatierung des Quelltextes ist nun vereinheitlicht (Tabs).

Wenn es einheitlich werden soll benutzt man Leerzeichen und keine Tabs. 
Denn die Tabeinstellungen können durchaus verschieden sein.

MfG Spess

von Ralf J. (cosmicos)


Lesenswert?

Hallo Spess,
danke für die Tipps!
Ich werde den Code entsprechend umbauen...
Grüße
Ralf

von Ralf J. (cosmicos)


Angehängte Dateien:

Lesenswert?

Ich habe mir nun ein paar Projekte in der Codesammlung angeschaut und 
mich in Bezug auf die Library-Strukturierung an den Projekten von "peda" 
orientiert.

tm1638cc.asm        -  der Beispielcode
tm1638cc.h          -  Definitionen, Konstanten, Register
tm1638cc.mac        -  Makros
tm1638cc.inc        -  Funktionen der Library
tm1638cc_font.inc   -  Fonts der Library
tm1638cc_delay.inc  -  Delay-Routinen der Library

Das sollte nun stimmen, oder?

von M. (Gast)


Lesenswert?

Ralf J. schrieb:
> Das sollte nun stimmen, oder?

Ja schaut hübsch und übersichtlich aus. Ich möchte jetzt hier keine 
Diskussionen über Dateiendungen lostreten aber ich bin von diesem System 
trotzdem schon wieder weg und benenne nach Fertigstellung alles in 
.txt um. Das lässt sich halt von überall ohne weitere Rückfragen 
problemlos anzeigen und editieren. Der Dateiname bietet Raum genug für 
genauere Bezeichnung.

von Ralf J. (cosmicos)


Lesenswert?

Aufgrund eines aktuellen Feedbacks hier ein Link zur aktuellen Version 
der Library:

https://github.com/Radulfus/TM1638

Die Version hier im Board hat noch ein paar schwere Bugs, daher bitte 
nicht verwenden. Stattdessen einfach ein checkout bzw. clone von Github 
machen...

Gruß
Ralf

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.