Hallo zusammen,
ich hab mir vor einiger Zeit ein Matrix-LED-Display zusammen gebaut aus 4 5x7 Matrixmodulen. Den Schaltplan und Quelcode hab ich aus dem Buch "AVR Hardeware und C-Programmierung in der Praxis" von Florian Schäffer.
Der Quelcode funktioniert und ist für mich, als Anfänger, einfach und zu verstehen.
Allerdings wird hier auch nur das auf dem Display angezeigt als Laufschrift,Code:/*************************************************** * Textausgabe auf 4 LED Modulen am Atmega 8 * * 5x7 Matrixmodule mit gemeinsamer Anode * * angesteuert über ULN2003A an PortB PB0 - PB6 * * Multiplexing über 3 Schieberegister 74HCT164 * * PC4 --> Bit setzen ; PC5 --> Tackt schieben * * * * Created: 13.02.2016 18:23:54 * * Author: Hendrik * ***************************************************/ #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include "charset.h" // beinhaltet Zahlen, keine und große Buchstaben sowie Sonderzeichen #include "lcd-routines.c" void set_row (uint8_t); void write_row (uint8_t); int main (void); #define DISPCOLS 20 // Anzahl der Spalten #define MEMCOLS 200 // Displayspeicher fuer 200 Spalten reservieren (>= 6 x Anzahl der Zeichen in Zeichenkette + 2 x DISPCOLS) #define CHARWIDTH 5 // Spalten je Zeichen #define CHARHEIGHT 7 // Zeilen je Zeichen #define DELAY 50 // Textgeschwindigkeit (ca. 10..200: schnell..langsam) volatile uint8_t memory[DISPCOLS]; // Speicher für Display, spaltenweise orientiert, Index 0=links volatile uint8_t pos=0; // ab welcher Speicherposition soll dargestellt werden volatile uint8_t zeile=0; // Zeilenzähler welche Zeile aktuell ist volatile uint8_t durchlauf=0; // Anzahl der Durchlaeufe volatile uint8_t chars=0; // Anzahl der Zeichen in Zeichenkette // *** Textausgabe *** uint8_t text[]= " Hallo Roboternetz "; // Zeichenkette Ausgabe void set_row (uint8_t row) { int8_t i; // Alle Spalten des Displays durchlaufen. Mit rechter Spalte beginnen for (i = DISPCOLS-1; i>=0; i--) { // Bit in der Spalte + Verschiebungswert pos an der übergebenden Zeile gesetzt? if ((memory[i+pos] >> (6-row)) & 1) // { PORTC |= (1 << PC4); // Data Bit setzen } else { PORTC &= ~(1 << PC4); // Data Bit löschen } PORTC |= (1 << PC5); // Takt HIGH -> Flanke PORTC &= ~(1 << PC5); // Takt LOW } } void write_row (uint8_t row) { PORTB = 0; // alle Zeilen aus set_row (row); // Daten für aktuelle Zeile in Schieberegister schieben PORTB = (1 << row); // aktuelle Zeile an } int main() { lcd_init(); uint8_t i, row; DDRC |= (1 << DDC4) | (1 << DDC5); // PC4, PC5 als Ausgang PORTC &= ~((1 << PC4) | (1 << PC5)); // PC4, PC5 aus DDRB = 0xFF; // PortB als Ausgang PORTB = 0; // PortB aus // Leerspalten am Anfang, damit Text von rechts kommt for (row=0; row<DISPCOLS; row++) memory[row]=1; // Eigentlich 0 aber für besseres Verständnis 1, damit eine LED leuchtet // Zeichenkette in Spaltenbeschreibung umsetzen while (text[chars] != 0) // solange Zeichen in Zeichenkette { memory[row]=charset[text[chars]-32][0]; row++; // aktuelle Spalte = 1. Spalte des Fonts memory[row]=charset[text[chars]-32][1]; row++; // aktuelle Spalte = 2. Spalte des Fonts memory[row]=charset[text[chars]-32][2]; row++; // usw. memory[row]=charset[text[chars]-32][3]; row++; memory[row]=charset[text[chars]-32][4]; row++; memory[row]=0; row++; // Leerspalte: Abstand zwischen 2 Buchstaben chars++; // Anzahl der Zeichen zählen } // Leerspalten am Ende, damit Textende aus Display geschoben wird for (i=0; i<DISPCOLS; i++) memory[i+row]=1; // Eigentlich 0 aber für besseres Verständnis 1, damit eine LED leuchtet OCR1A = (uint16_t)(F_CPU/1024.0*0.003); // Vergleichwert für 0,003s laden: Takt= 8MHz/1024 = 7812,5 Zählerschritte pro s TIMSK |= (1<<OCIE1A); // Interrupt wenn Timer Vergleichswert erreicht TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<WGM12); // Timer mit Div 1024 starten und Clear Counter on Compare Match sei(); lcd_clear(); lcd_setcursor(0,1); lcd_string("20x7 LED Matrix Text"); lcd_setcursor(3,3); lcd_string("Hallo Thomas!"); while(1) { asm volatile ("nop"); // nichts machen } return 0; } // Wird vom 16 Bit Timer ausgelöst, wenn dieser den Vergleichwert erreicht ISR (TIMER1_COMPA_vect) { write_row (zeile); // schreibe aktuelle Zeile zeile++; // nächste mal naechste Zeile if (zeile == CHARHEIGHT) // wenn alle Zeilen ausgegeben, wieder von vorne beginnen zeile = 0; durchlauf++; // Durchlaufzaehler: wie oft wurde das Display unverändert refresht if (durchlauf == DELAY) // Anzahl der Durchläufe erreicht { durchlauf = 0; pos++; // Displayinhalt eins verschieben } // Wenn der gesamte Speicherinhalt einmal durchlaufen wurde if (pos >= (chars*(CHARWIDTH+1)+(DISPCOLS))) pos = 0; // von vorne beginnen }
was in folgender Zeile eingefügt wird
Meine Frage,Code:// *** Textausgabe *** uint8_t text[]= " Hallo Roboternetz "; // Zeichenkette Ausgabe
ich würde gerne das Matrix-Display so ansteuern wie ich das LCD ansteuere, sprich einfach write_Matrix(" Hallo Roboternetz "); , oder über UART vom PC Text ans Display senden, oder Werte anzeigen lassen von ADC zum Beispiel ob als Laufschrift oder fest.
Könnte ich da den obrigen Code weiterhin verwenden und abändern, oder müsste was neues schreiben ?
LG Hendrik







Zitieren


Lesezeichen