Jackeder
21.01.2016, 12:29
Hallo,
ich habe in den letzten Wochen mir ein 20x7 LED Display aufgebaut und momentan propleme bei der Programmierung.
Den Schaltplan und Quelcode hab ich aus dem Buch "AVR Hardeware und C-Programmierung in der Praxis" von Florian Schäffer.
Feines Buch für Anfänger übrigens...
Verwendete Bauteile
CD74HCT164E Schieberegister für die Spalten
ULN2003A für die Zeilen
TA20-11CGKWA DOT MATRIX Anzeige 5x7 LED mit gemeinsame Anode
/************************************************** *
* Musteraufbau mit 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: 17.01.2016 17:30:27 *
* Author: Hendrik *
************************************************** */
#define F_CPU 8000000UL
#include <avr/io.h>
#include "lcd-routines.c"
#include <util/delay.h>
#define Spalten 20 // Anzahl der Spalten
volatile uint8_t memory[Spalten]; // Speicher für Display, Spaltenweise
// orientiert, Index 0=links
void set_row (uint8_t row)
{
uint8_t i; // Alle Spalten des Displays durchlaufen
// Mit rechten Spalte beginnen
for (i=Spalten-1; i>=0; i--)
{
if ((memory[i] >>(6-row)) & 1) // Bit in der Spalte an der übergebenen Zeile gesetzt?
{
PORTC |= (1<<PC4); // Data Bit setzen
}
else
{
PORTC &=~(1<<PC4); // Data Bit löschen
}
PORTC |=(1<<PC5); // Takt HIGH -> Flanke => schreiben
PORTC &=~(1<<PC5); // Takt LOW
}
}
void write_rows ()
{
uint8_t i;
for (i=0; i<=6; i++) // Alle Zeilen durchlaufen
{
PORTB = 0; // alle Zeilen aus
set_row (i); // Daten für aktuelle Zeile in Schieberegister schieben
PORTB = (1 << i); // aktuelle Zeile an
_delay_ms(2); // Zeile Leuchten lassen
}
}
int main(void)
{
// *** Ausgänge definieren und ausschalten ***
DDRC |= (1<< PC4) | (1<<PC5); // PC4 und PC5 als Ausgang
// PORTC &=~((1<<PC4) | (1<<PC5)); // PC4 und PC5 aus
DDRB = 0xFF; // PortB als Ausgang
// PORTB = 0; // PortB aus
lcd_init(); // LCD aktivieren
lcd_clear();
lcd_setcursor(2,2);
lcd_string("20x7 LED Matrix");
lcd_setcursor(3,4);
lcd_string("Muster ausgeben");
// beliebeiges Muster Spaltenweise definieren
// Spalte = -7654321
memory[0] = 0b01111110;
memory[1] = 0b01010101;
memory[2] = 0b00101010;
memory[3] = 0b01010101;
memory[4] = 0b01010101;
memory[5] = 0b01100110;
memory[6] = 0b00011001;
memory[7] = 0b01001100;
memory[8] = 0b01100110;
memory[9] = 0b01111111;
memory[10] = 0b01010101;
memory[11] = 0b00101010;
memory[12] = 0b01010101;
memory[13] = 0b00101010;
memory[14] = 0b00011100;
memory[15] = 0b01111001;
memory[16] = 0b01001001;
memory[17] = 0b01001001;
memory[18] = 0b01001001;
memory[19] = 0b01001111;
while(1)
{
write_rows();
}
return 0;
}
Den Code hab ich soweit vom Buch abgeschrieben und auf 20 Zeilen geändert(Buch waren nur 15Zeilen) doch nix tat sich hinterher, keine LED war an.
Ich hab momentan in einem Testprogramm die Zeilen einzeln ein und ausgeschalten, sprich
while(1)
{
PORTB |=(1<<PB0);
_delay_ms(500);
PORTB &=~ (1<<PB0);
_delay_ms(500);
}
und siehe da es leuchtet die erste Zeile, allerdings komplett alle 20. Auch die restlichen Zeilen (PB1 bis PB6) leuchten alle LEDs auf.
Nun ist meine Frage, kann der oben gezeigte Code so funktionieren, zumindest sollte das ja laut Buch, oder hab ich doch noch irgendwo einen Fehler übersehen ?
Würde mich freuen wenn ihr mir weiterhelfen könntet.
liebe Grüße Hendrik
ich habe in den letzten Wochen mir ein 20x7 LED Display aufgebaut und momentan propleme bei der Programmierung.
Den Schaltplan und Quelcode hab ich aus dem Buch "AVR Hardeware und C-Programmierung in der Praxis" von Florian Schäffer.
Feines Buch für Anfänger übrigens...
Verwendete Bauteile
CD74HCT164E Schieberegister für die Spalten
ULN2003A für die Zeilen
TA20-11CGKWA DOT MATRIX Anzeige 5x7 LED mit gemeinsame Anode
/************************************************** *
* Musteraufbau mit 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: 17.01.2016 17:30:27 *
* Author: Hendrik *
************************************************** */
#define F_CPU 8000000UL
#include <avr/io.h>
#include "lcd-routines.c"
#include <util/delay.h>
#define Spalten 20 // Anzahl der Spalten
volatile uint8_t memory[Spalten]; // Speicher für Display, Spaltenweise
// orientiert, Index 0=links
void set_row (uint8_t row)
{
uint8_t i; // Alle Spalten des Displays durchlaufen
// Mit rechten Spalte beginnen
for (i=Spalten-1; i>=0; i--)
{
if ((memory[i] >>(6-row)) & 1) // Bit in der Spalte an der übergebenen Zeile gesetzt?
{
PORTC |= (1<<PC4); // Data Bit setzen
}
else
{
PORTC &=~(1<<PC4); // Data Bit löschen
}
PORTC |=(1<<PC5); // Takt HIGH -> Flanke => schreiben
PORTC &=~(1<<PC5); // Takt LOW
}
}
void write_rows ()
{
uint8_t i;
for (i=0; i<=6; i++) // Alle Zeilen durchlaufen
{
PORTB = 0; // alle Zeilen aus
set_row (i); // Daten für aktuelle Zeile in Schieberegister schieben
PORTB = (1 << i); // aktuelle Zeile an
_delay_ms(2); // Zeile Leuchten lassen
}
}
int main(void)
{
// *** Ausgänge definieren und ausschalten ***
DDRC |= (1<< PC4) | (1<<PC5); // PC4 und PC5 als Ausgang
// PORTC &=~((1<<PC4) | (1<<PC5)); // PC4 und PC5 aus
DDRB = 0xFF; // PortB als Ausgang
// PORTB = 0; // PortB aus
lcd_init(); // LCD aktivieren
lcd_clear();
lcd_setcursor(2,2);
lcd_string("20x7 LED Matrix");
lcd_setcursor(3,4);
lcd_string("Muster ausgeben");
// beliebeiges Muster Spaltenweise definieren
// Spalte = -7654321
memory[0] = 0b01111110;
memory[1] = 0b01010101;
memory[2] = 0b00101010;
memory[3] = 0b01010101;
memory[4] = 0b01010101;
memory[5] = 0b01100110;
memory[6] = 0b00011001;
memory[7] = 0b01001100;
memory[8] = 0b01100110;
memory[9] = 0b01111111;
memory[10] = 0b01010101;
memory[11] = 0b00101010;
memory[12] = 0b01010101;
memory[13] = 0b00101010;
memory[14] = 0b00011100;
memory[15] = 0b01111001;
memory[16] = 0b01001001;
memory[17] = 0b01001001;
memory[18] = 0b01001001;
memory[19] = 0b01001111;
while(1)
{
write_rows();
}
return 0;
}
Den Code hab ich soweit vom Buch abgeschrieben und auf 20 Zeilen geändert(Buch waren nur 15Zeilen) doch nix tat sich hinterher, keine LED war an.
Ich hab momentan in einem Testprogramm die Zeilen einzeln ein und ausgeschalten, sprich
while(1)
{
PORTB |=(1<<PB0);
_delay_ms(500);
PORTB &=~ (1<<PB0);
_delay_ms(500);
}
und siehe da es leuchtet die erste Zeile, allerdings komplett alle 20. Auch die restlichen Zeilen (PB1 bis PB6) leuchten alle LEDs auf.
Nun ist meine Frage, kann der oben gezeigte Code so funktionieren, zumindest sollte das ja laut Buch, oder hab ich doch noch irgendwo einen Fehler übersehen ?
Würde mich freuen wenn ihr mir weiterhelfen könntet.
liebe Grüße Hendrik