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

Code:
/***************************************************
 *  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