Jag vet nu inte hur hela programmet ser ut, men det är viktigt att du vet vad de olika variablerna egentligen innehåller för data.
ta t.ex. det här exemplet:
Kod: Markera allt
// funktion för att skicka ut en bit på shiftregister
void shifta_en_bit(char colour) {
PORTB = STROBE | colour; // sätt färg - "strobe" skall alltid vara på (se * nedan)
_delay_ms(1);
PINB = CLOCK; // toggla klockan
_delay_ms(1);
PINB = CLOCK;
}
*
(En sak att fundera på : Strobe-utgången ska alltid vara ETTA. I koden står det därför PORTB = STROBE | colour;. Men man kan utesluta strobe och skriva PORTB = colour; och strobeutgången blir fortfarande en ETTA. Hur kommer det sig? Strobe definieras som #define STROBE (1<<PB6) )
Här tar funktionen in ett 8-bitars värde (char colour). Vad gör de olika bitarna i den variabeln?
På första raden i funktionen skickar vi ut data på port B.
Så varje bit i "colour" motsvarar en utgång på PORTB. Har man schemat framför sig (
sidan7 i denna tråden) ser man att PORTB har en massa olika funktioner : bit 3 är OUTPUT_BLUE, bit 4 är OUTPUT_GREEN och bit 5 är OUTPUT_RED. Bit 6 är strobe. Det är därför jag har definierat färgerna (inverterat) såhär:
Kod: Markera allt
#define OUTPUT_BLUE ( ~(1<<PB3))
#define OUTPUT_GREEN ( ~(1<<PB4))
#define OUTPUT_RED ( ~(1<<PB5))
För att få ut GUL färg måste bit 5 och 4 vara nolla, och bit 3 vara etta (och alla övriga bitar kan också var etta) . PORTB = 0b11001111;
(1<<5) är detsamma som 0b00100000. inverterar vi det värdet (~(1<<5)) blir det 0b11011111 som är värdet på OUTPUT_RED. om vi nu skriver:
får vi gul på första kolumnen.
bitvis och (&):
Kod: Markera allt
0b11011111
& 0b11101111
========
0b11001111
Detta är
hur bitarna ser ut på PORTB i det läge man skickar en puls till shiftregistren att läsa in datan.
Men det är ju
åtta kolumner som ska ha var sin färg. Och i den här funktionen:
Kod: Markera allt
// funktion som skickar ut data till shiftregistren
// red,blue,green innehåller var och en 8 bitar data.
// varje bit tänder en LED i den kolumnen
void skicka_data(char red, char blue, char green) {
// SKRIV ALGORITM HÄR
}
så hade jag tänkt att de
åtta bitarna i var och en av variablerna red, blue och green kunde motsvara var sin kolumn. På så vis kommer funktionen att kunna sätta alla tänkbara färgkombinationer som finns på 8 kolumner... om den bara kan ta bitarna en och en ur varje färgvariabel och shifta ut dem...
Ett sätt att göra det på kan vara t.ex:
Kod: Markera allt
// funktion som skickar ut data till shiftregistren
// red,blue,green innehåller var och en 8 bitar data.
// varje bit tänder en LED i den kolumnen
void skicka_data(char red, char blue, char green) {
for (char i=0;i<7;i++) { // åtta varv
// "output" är den variabel vars databitar kommer att skickas ut på PORTB.
char output = 0b11111111; // ettställ alla bitar först
// kolla bit nr 7 i var och en av de tre färgerna
if (red & 7) output &= OUTPUT_RED;
if (green & 7) output &= OUTPUT_GREEN;
if (blue & 7) output &= OUTPUT_BLUE;
// shifta bitarnas position ett steg år vänster (bit 6 blir bit7 osv..)
red = (red << 1);
green = (green << 1);
blue = (blue << 1);
// skicka ut data för en kolumn
// variablen "output" innehåller nu data för alla tre färger
shifta_en_bit(output); // denna funktion skickar ut datan till shiftregistren
}
}
Om det är någon operation i den här funktionen du inte förstår så försök sätta dig in i det. Om du ska kunna utveckla projektet behöver du förstå i detalj exakt vad som händer.
Nu kan du med en enda rad skicka ut alla färger på alla kolumner:
Kod: Markera allt
// raden nedan tänder följande färger i ordning kolumn 0 till kolumn7
// svart,röd,blå,grön,gul,violett,vit,magenta,svart
skicka_data(0b010011100,0b001001110,0b000110110 )// red,blue,green
lägg de tre binära talen över varandra så ser du vilka färger det blir:
Kod: Markera allt
kol 01234567
========
red 010011100
blue 001001110
green 000110110
Nu kan man matematiskt eller logiskt skapa olika mönster som man skickar ut med hjälp av den fuktionen. Detta är ett sätt att organisera data på. Här ör de tre kanalerna röd, grön, blå skilda åt. Ett alternativ (som kanske är bättre) är att man har åtta variabler (en för varje rad) i en array, som villserligen är 8-bitars heltal, men där man bara använder tre av bitarna, vilka då motsvarar röd, grön och blå.
char column[8];
Då kan man fortfarande använda de "gamla" färgdefinitionerna om man vill, t.ex.
column[4] = YELLOW;
column[5] = RED;
eller varför inte
Kod: Markera allt
for (char i = 0; i<8; i++) {
column[i] = i;
}
Du kan ju fundera på hur du skriver en funktion
void skicka_data( char* column ) som skickar ut sådan data istället. Fördelen med det är kanske att man sedan kan skapa en matris som innehåller data för alla färger i alla kolumner i alla rader:
char PIXEL[8]∞; // tvådimensionellt!