Hallo, ik zal maar meteen met de deur in huis vallen...
dit is de code die wel werkt:

//**************************************************
//********** Programma instellingen ****************
//**************************************************

#define F_CPU 16000000  			// 16Mhz kristal

#include <util/delay.h>				// Include delay library
#include <avr/io.h>					// include I/O definities
	
const int SCK = PB5;				// SCK hangt aan PB5
const int RCK = PB2;				// RCK hangt aan PB2
const int SER = PB3;				// SER hangt aan PB3



//**************************************************
//********* Arrays voor R, G, B en anodes **********
//**************************************************


char NUL[8]= 	{	0x00,
					0x00,
					0x00,
					0x00,
					0x00,
					0x00,
					0x00,
					0x00};

char lA[8]={		0b00111000,
					0b01000100,
					0b01000100,
					0b01000100,
					0b01111100,
					0b01000100,
					0b01000100,
					0b00000000};

char lB[8]={		0b01111000,
					0b01000100,
					0b01000100,
					0b01111000,
					0b01000100,
					0b01000100,
					0b01111000,
					0b00000000};

char lC[8]={		0b00111000,
					0b01000100,
					0b01000000,
					0b01000000,
					0b01000000,
					0b01000100,
					0b00111000,
					0b00000000};


char ANODE[8]= {	0b10000000,		//1
					0b01000000,		//2
					0b00100000,		//3
					0b00010000,		//4
					0b00001000,		//5
					0b00000100,		//6
					0b00000010,		//7
					0b00000001};	//8



//**************************************************
//****** Doorsturen data naar schuifregisters ******
//**************************************************

int LADEN(char input, int SCK, int RCK, int SER)
{
	DDRB = 0xFF; 					// Heel portB als uitgang
	PORTB = 0x00; 					// Alle uitgangen laag maken

	uint8_t counter;				// Maak variabele 'counter' aan

	for(counter = 0; counter<=7; counter++) // Herhaal onderstaand 8 keer
	{										// (voor elke bit van 0-7)
		PORTB = 0x00; 						// Alle uitgangen laag maken
			if( ((1<<counter)&input) != 0 )	// Als inputbit gelijk is aan 1
			{
				PORTB |= (1<<SER);			// Stuur dan een 1	naar de data-ingang
			}
			else							// Anders...
			{
				PORTB &= ~(1<<SER);		 	// Stuur een 0 naar de data-ingang
			}
		PORTB |= (1<<SCK);					// Stuur data door naar schuifregister
	}
	return 0;								
}



//**************************************************
//****************** Hoofdfunctie ******************
//**************************************************

int main()							// Aanmaken van de hoofdfunctie
{
	DDRB = 0xFF; 					// Heel portB als uitgang
 	PORTB = 0x00; 					// Alle uitgangen laag maken
    PORTB |= (0 << PB2); 			// Enable laag -> schuifregister actief
		
	while(1)						// Oneindige lus
	{
		unsigned int i;
		for (i=0; i<20; i++)
		{
			uint8_t j;					// Maak variabele 'j' aan
			for(j=0;j<=8;j++)			// Herhaal onderstaande 8 keer (voor rij 1 tot 8)
			{
				LADEN(ANODE[j], SCK, RCK, SER);	// Doorsturen juiste rij van array ANODE
				LADEN(lA[j], SCK, RCK, SER);	// Doorsturen juiste rij van array BLAUW
				LADEN(lA[j], SCK, RCK, SER);	// Doorsturen juiste rij van array GROEN
				LADEN(NUL[j], SCK, RCK, SER); 	// Doorsturen juiste rij van array ROOD
				PORTB |= (1<<RCK); 				// Inhoud schuifregisters naar uitgang
			}
		}




		
		for (i=0; i<20; i++)
		{
			uint8_t j;					// Maak variabele 'j' aan
			for(j=0;j<=8;j++)			// Herhaal onderstaande 8 keer (voor rij 1 tot 8)
			{
				LADEN(ANODE[j], SCK, RCK, SER);	// Doorsturen juiste rij van array ANODE
				LADEN(NUL[j], SCK, RCK, SER);	// Doorsturen juiste rij van array BLAUW
				LADEN(lB[j], SCK, RCK, SER);	// Doorsturen juiste rij van array GROEN
				LADEN(lB[j], SCK, RCK, SER); 	// Doorsturen juiste rij van array ROOD
				PORTB |= (1<<RCK); 				// Inhoud schuifregisters naar uitgang
			}
		}





		for (i=0; i<20; i++)
		{
			uint8_t j;					// Maak variabele 'j' aan
			for(j=0;j<=8;j++)			// Herhaal onderstaande 8 keer (voor rij 1 tot 8)
			{
				LADEN(ANODE[j], SCK, RCK, SER);	// Doorsturen juiste rij van array ANODE
				LADEN(lC[j], SCK, RCK, SER);	// Doorsturen juiste rij van array BLAUW
				LADEN(NUL[j], SCK, RCK, SER);	// Doorsturen juiste rij van array GROEN
				LADEN(lC[j], SCK, RCK, SER); 	// Doorsturen juiste rij van array ROOD
				PORTB |= (1<<RCK); 				// Inhoud schuifregisters naar uitgang
			}
		}
	}
	return 0;
 return 0;
}

Dit werkt (heb zitten proberen todat het werkte :) )
Maar dit word zeer uitgebreid na een tijdje, en ik dacht er aan om zelf een functie te maken dat een hele hoop van die code in een header file zet (zoals de arrays, het laden van de schuifregisters, de wachttijd van elk scherm, ...)

ik dacht dan om iets zoals dit te maken:
SCHRIJF (a, b, c, d, e);
waar a, b, c, d arrays zijn en e de tijd dat het scherm wordt getoond (registers sturen LED matrix aan) (e is in dit voorbeeld dus i)

Echter het lukt mij langs geen kanten...

uiteindelijk wou ik dit als hoofdfunctie hebben voor dit voorbeeld:

int main()							// Aanmaken van de hoofdfunctie
{
		
	while(1)						// Oneindige lus
	{
		SCHRIJF(ANODE[j], lA[j], lA[j], NUL[j], 25);
		SCHRIJF(ANODE[j], NUL[j], lB[j], lB[j], 25);
                SCHRIJF(ANODE[j], NUL[j], lC[j], lC[j], 25);
	}
 return 0;
}

het tonen van A dan B en dan C op de matrix

Ik ben een complete newbie op het gebied van C, dus sorry voor de eventueel "domme" vraagstelling.

Alvast bedankt,
mvg,
Kevin

Er zijn zat tutorials te vinden met hoe je een header file maakt, kijk daar eens naar. Als het dan niet lukt kan je het altijd nog vragen. Een tut hier overtypen heeft weinig zin.

Kijk anders eens hoe de headers zoals io.h zijn opgebouwd.

Om je een kleine duw in de juiste richting te geven:

Maak 2 bestanden: LedMatrix.c en LedMatrix.h aan.
In de .h komen al je prototypes van je functies.
In de .c komen al je definities van je functies.
De .h include je in je main.c en LedMatrix.c.

En zoals Bas al zei, lees je best een tutorial. Zo leer je het van de eerste keer goed doen.

Alvast bedankt,
ik zal eens op zoek gaan naar een goede tutorial :)

vb

EDIT:
snelle schets en ik heb nu dit:

programma.C

#define F_CPU 16000000  			// 16Mhz kristal

#include <util/delay.h>				// Include delay library
#include <avr/io.h>					// include I/O definities
#include "RGBmatrix.h"

int main()							// Aanmaken van de hoofdfunctie
{
		
	while(1)						// Oneindige lus
	{
		SCHRIJF(ANODE, EEN, EEN, NUL, 25);
	}
 return 0;
}

RGBmatrix.h

char NUL[8]= {		0x00,
					0x00,
					0x00,
					0x00,
					0x00,
					0x00,
					0x00,
					0x00};					
					
char EEN[8]= {		0xFF,
					0xFF,
					0xFF,
					0xFF,
					0xFF,
					0xFF,
					0xFF,
					0xFF};

char ANODE[8]= {	0b10000000,
					0b01000000,	
					0b00100000,	
					0b00010000,	
					0b00001000,	
					0b00000100,	
					0b00000010,		
					0b00000001};




//********************************************



void SCHRIJF(char a, char b, char c, char d, int e); //a is anode, b c d is respectievelijk RGB, e is tijd van duur 
void LADEN(char input, int SCK, int RCK, int SER);

RGBmatrix.C

#define F_CPU 16000000  			// 16Mhz kristal

#include <util/delay.h>				// Include delay library
#include <avr/io.h>					// include I/O definities
#include "RGBmatrix.h"




void LADEN(char input, int SCK, int RCK, int SER)
{
	DDRB = 0xFF; 					// Heel portB als uitgang
	PORTB = 0x00; 					// Alle uitgangen laag maken
		
		uint8_t counter;				// Maak variabele 'counter' aan
		for(counter = 0; counter<=7; counter++) // Herhaal onderstaand 8 keer
		{										// (voor elke bit van 0-7)
		PORTB = 0x00; 						// Alle uitgangen laag maken
			if( ((1<<counter)&input) != 0 )	// Als inputbit gelijk is aan 1
			{
				PORTB |= (1<<SER);			// Stuur dan een 1	naar de data-ingang
			}
			else							// Anders...
			{
				PORTB &= ~(1<<SER);		 	// Stuur een 0 naar de data-ingang
			}
		PORTB |= (1<<SCK);					// Stuur data door naar schuifregister
	}
}





void SCHRIJF(char a, char b, char c, char d, int e) //a is anode, b c d is respectievelijk RGB, e is tijd van duur 
{
	const int SCK = PB5;				// SCK hangt aan PB5
	const int RCK = PB2;				// RCK hangt aan PB2
	const int SER = PB3;				// SER hangt aan PB3

	DDRB = 0xFF; 						// Heel portB als uitgang
 	PORTB = 0x00; 						// Alle uitgangen laag maken
    PORTB |= (0 << PB2); 				// Enable laag -> schuifregister actief


	unsigned int z; 						// maak z aan en stel z gelijk aan e zodat de wachttijd wordt ingesteld
	for (z=0; z<e; z++); 				// wachttijd z is gegeven waarde (e)
	{
			uint8_t j;					// Maak variabele 'j' aan
			for(j=0;j<=8;j++)			// Herhaal onderstaande 8 keer (voor rij 1 tot 8)
			{
				LADEN(a[j], SCK, RCK, SER);	// Doorsturen juiste rij van array ANODE
				LADEN(d[j], SCK, RCK, SER);	// Doorsturen juiste rij van array BLAUW
				LADEN(c[j], SCK, RCK, SER);	// Doorsturen juiste rij van array GROEN
				LADEN(b[j], SCK, RCK, SER); 	// Doorsturen juiste rij van array ROOD
				PORTB |= (1<<RCK); 				// Inhoud schuifregisters naar uitgang
			}
	}

}




Met 4x dezelfde error:
../RGBmatrix.c:73: error: subscripted value is neither array nor pointer
error over deze lijn uit RGBmatrix.c onderaan:
LADEN(a[j], SCK, RCK, SER);

hoe kan ik zeggen dan het het veld ANODE lijn J naar de schuifregisters moet worden gestuurd?

[Bericht gewijzigd door kevin_ op (92%)]


void SCHRIJF(char a, char b, char c, char d, int e)

SCHRIJF(ANODE, EEN, EEN, NUL, 25);

ANODE, EEN en NUL zijn geen chars, maar arrays. Maak er dit van:


void SCHRIJF(char *a, char *b, char *c, char *d, int e)

Je moet even goed kijken naar het volgende stukje code:

for(j=0;j<=8;j++)			// Herhaal onderstaande 8 keer (voor rij 1 tot 8)
			{
				LADEN(a[j], SCK, RCK, SER);	// Doorsturen juiste rij van array ANODE
				LADEN(d[j], SCK, RCK, SER);	// Doorsturen juiste rij van array BLAUW
				LADEN(c[j], SCK, RCK, SER);	// Doorsturen juiste rij van array GROEN
				LADEN(b[j], SCK, RCK, SER); 	// Doorsturen juiste rij van array ROOD
				PORTB |= (1<<RCK); 				// Inhoud schuifregisters naar uitgang
			}

Dat stukje doet niet helemaal wat het zou moeten doen. Je hebt je array's bevatten slechts 8 elementen. Je for-loop gaat momenteel van 0 tot en met 8. Terwijl er helemaal geen element bestaat met als index '8'. Een array gedeclareerd als char test[8], loopt van test[0] tot test[7]. Oftewel je moet de '<=' veranderen in '<'.

Verder zou ik wat doen aan je (vreselijke) naamgeving, misschien dat dit als voorbeeld bedoelt is, maar dan nog. Variabelen met de naam a, b, c etc. maakt de boel niet echt leesbaarder.

Tevens zou ik het volgende weglaten:

	const int SCK = PB5;				// SCK hangt aan PB5
	const int RCK = PB2;				// RCK hangt aan PB2
	const int SER = PB3;

En in je headerfile het volgende zetten:

#define SCK PB5
#define RCK PB2
#define SER PB3

Ook zou ik de laatste 3 parameters van LADEN weglaten, tenzij jij een hele goede reden hebt dit niet te doen (die goede reden zie ik in je huidige code niet).
Als je de parameters van de functie laden wilt houden, dan zou ik wel het datatype veranderen in char of uint8_t. Als je AVR-GCC gebruikt is een 'int' namelijk standaard 16bits en dat is in dit geval niet nodig.

Die functie "LADEN" noem je beter iets als SPI_MasterTransmit() daarmee weet je direct wat de functie doet. Waarom doe je aan software SPI? Als je AVR geen HW SPI heeft, neem je beter een andere die het wel heeft.

Om de bitmappen van je karakters op te slaan, maak je beter een ascii tabel aan. Een 2 dimentionale array.


const char ascii_table[128][8] PROGMEM;

Die array neemt wel 1kB ruimte in beslag, als dat een probleem is, kan je de array nog beperken tot enkel de gebruikte karakters.

Op die manier kan je makkelijk een print functie maken zonder dat de main hoeft te weten wat nu exact de bitpatronen van elke letter zijn (wat nu bij jou wel het geval is)

Het kan dan is worden zoals:


void print(char *tekst){
	while(*tekst){
		printLetter(*tekst);
		tekst++;
	}
}
void printLetter(char letter){
	// je code
	// om aan het bitpatroon te geraken doe je nu:
	// ascii_[letter]
}

Het multiplexen zelf doe je nu in de main routine. Je doet dit beter onder interrupts. Zorg er voor dat de interrupt routine aan 100 Hz je beeld volledig opvouwt (de routine moet dus meer dan 100 keer/sec aangeroepen worden, hoe ziet je harware er uit?). Die routine haalt zijn data uit een bepaalde structuur. Als je dan iets wil tonen op je scherm roep je 1 keer in je main routine een functie aan, die de data in de structuur aanpast.

Het idee voor dit is dat ik de code zo kan vereenvoudigen zodat het eenvoudig aanpasbaar en uitbreidbaar is.
Hierdoor kan ik op de opendeurdag van ons school iedereen de kans geven om zijn eigen boodschap te programeren op een 8x8RGB-display.

@ naffets, ik heb de code van het internet waar men schuifregisters gebruikte voor de uitbreiding van outputs... maar toegepast op het display in het school werd iedere keer 1 lijn niet aangestuurd als ik die 8 veranderde in een 7... het klopt in theorie mss niet, maar in praktijk werkt de *.C-code van de startpost.

EDIT:
Testen tot het werkt heb ik gedaan, en alle errors zijn weg behalve 1 waardoor ik geen .HEX kan maken:

make: *** [ny.elf] Error 1
Build failed with 1 errors and 0 warnings...

Wat betekend dit? Want ik ben echt nieuw in de wereld van C.

alvast bedankt,
kevin

Ik denk niet dat je goed begrepen hebt wat ik hierboven wou zeggen.

Tekst printen zou dan zo gaan:
print("Jouw tekst");
Dit is eenvoudiger aan te passen dan jouw code...

Je gebruikt een ATmega16, waarom dan software SPI?

Hoeveel kleuren wil je kunnen maken?

ik gebruik een ATmega8 (van het school) die gemonteerd staat op een bordje met allerlij LED's en displays rond. door 3 pinnen te bedienen, een heel RGBmatrix aan te sturen van het school een goed idee, alleen is het aan de leerlingen uit te dokteren hoe men dit moet doen (want leerkrachten kennen er zelf zo goed als niets van) en hoe men de code kan vereenvoudigen zodat alles overzichtelijk, eenvoudig aanpasbaar en 'custom made' is...

Dat schema dat ik had gepost lijkt een klein beetje op het schema dat in het school word gebruikt, mits een klein aanpassingen (waaronder ATmega8 ipv ATmega16). Omdat het niet het schema is dat ik gebruik, heb ik de links al terug verwijderd voor verdere kleine verwarringen te voorkomen.

nog 1 error te gaan...