Val av microprocessor, RGB LED styrning
Re: Val av microprocessor, RGB LED styrning
Är det inte dessutom omvänd logik på färgerna, så man får skicka en nolla till skifregistren för att tända en färg/kolumn och etta för att släcka? (Jag har nästan samma koppling (med samma sorts led-display) på en labplatta, men det var ett tag sedan jag pillade på den)
Edit: Jo skiftregistren sitter ju på katod-sidan
Edit: Jo skiftregistren sitter ju på katod-sidan
Re: Val av microprocessor, RGB LED styrning
Hoppsan! Bra iakttagelse. Det hade jag missat. Det betyder med andra ord att det inte riktigt blir de färger som jag tänkte. Då får man invertera de bitarna. Annars blir vit svart, grön blir lila och lila blir grön...
Däremot inverteras inte raderna (transistorerna). Det beror på att där sitter NPN-transistorer. Hade det varit PNP-transisptrer där hade även de varit inverterade.
Själv hade jag nog inverterat själva definitionerna , så att OUTPUT_BLUE blev ~(1<<PB3) osv.. men då måste man använda bitvis AND istället för bitvis OR när man lägger ihop bitarna: PORTB = OUTPUT_RED & OUTPUT_BLUE; // lila färg De bitvisa operatorerna & (AND), | (OR) och ~ (NOT) måste man förstå när man jobbar med detta. En bra C -programming tutorial finns här. Där kan man hitta operanderna.
När man skriver måste man förstå exakt vad som händer med alla bitar på porten!
PB5 motsvarar alltså pinnen PB5 och är bit nr 5 i den 8-bitars data som skickas till porten. Bit nr 5 har värdet 32 decimalt, eftersom 32 = 0b00010000. (bitarna numreras från höger till vänster och börjar med noll). Om jag skriverFår jag alltså följande data :
OUTPUT_RED = 0b00010000
STROBE = 0b01000000
PORTB = 0b01010000
Om jag istället inverterar OUTPUT_RED och STROBE och använder bitvis AND får jag
OUTPUT_RED = 0b11101111
STROBE = 0b10111111
PORTB = 0b010101111
så vi ser att alla andra utgångar (PB0 till PB7) påverkas också. De blir ettor istället för nollor. Detta kan påverka andra funktioner så som t.ex. CLOCK (PB2), MOSI (PB0) och MISO (PB1)... Nu använder vi inte MOSI och MISO, men klockan till shiftregistren blir inverterad. Det kan ha en viss betydelse beroende på hur man togglar klockan sedan. Shiftregistren triggar på uppåtgående flank på klockan - det är det som har betydelse när den flanken kommer. Sedan om klockan vilar i högt eller lågt läge är mindre viktigt. MOSI och MISO används inte så det spelar ingen roll här.

Däremot inverteras inte raderna (transistorerna). Det beror på att där sitter NPN-transistorer. Hade det varit PNP-transisptrer där hade även de varit inverterade.
Själv hade jag nog inverterat själva definitionerna , så att OUTPUT_BLUE blev ~(1<<PB3) osv.. men då måste man använda bitvis AND istället för bitvis OR när man lägger ihop bitarna: PORTB = OUTPUT_RED & OUTPUT_BLUE; // lila färg De bitvisa operatorerna & (AND), | (OR) och ~ (NOT) måste man förstå när man jobbar med detta. En bra C -programming tutorial finns här. Där kan man hitta operanderna.
När man skriver
Kod: Markera allt
#define OUTPUT_RED ~(1<<PB5)
PORTB = OUTPUT_RED;
PB5 motsvarar alltså pinnen PB5 och är bit nr 5 i den 8-bitars data som skickas till porten. Bit nr 5 har värdet 32 decimalt, eftersom 32 = 0b00010000. (bitarna numreras från höger till vänster och börjar med noll). Om jag skriver
Kod: Markera allt
#define OUTPUT_RED ~(1<<PB5)
#define STROBE (1<<PB6) // shiftregister strobe (STR)
PORTB = STROBE | OUTPUT_RED;
OUTPUT_RED = 0b00010000
STROBE = 0b01000000
PORTB = 0b01010000
Om jag istället inverterar OUTPUT_RED och STROBE och använder bitvis AND får jag
OUTPUT_RED = 0b11101111
STROBE = 0b10111111
PORTB = 0b010101111
så vi ser att alla andra utgångar (PB0 till PB7) påverkas också. De blir ettor istället för nollor. Detta kan påverka andra funktioner så som t.ex. CLOCK (PB2), MOSI (PB0) och MISO (PB1)... Nu använder vi inte MOSI och MISO, men klockan till shiftregistren blir inverterad. Det kan ha en viss betydelse beroende på hur man togglar klockan sedan. Shiftregistren triggar på uppåtgående flank på klockan - det är det som har betydelse när den flanken kommer. Sedan om klockan vilar i högt eller lågt läge är mindre viktigt. MOSI och MISO används inte så det spelar ingen roll här.
-
- Inlägg: 144
- Blev medlem: 8 september 2010, 14:26:12
Re: Val av microprocessor, RGB LED styrning
Där fick jag en hel del ny info.
Jag har inte hunnit testa det Jesse skrev sist om invertering, och jag förstod inte helt hur det skulle göras.
Men jag kom att tänka på hur konstruktionen av (i alla fall mitt eget, senare) programmet skulle kunna vara utformat.
Skulle det gå att göra så att när man programmerar mönstret så behöver man bara skriva in två eller tre variabler?
EX: r (röd), 3 (rad) och 7 (kolumn). eller bara två: 5 (rad) 12 (kolumn).
Det senare exemplet skulle inte veta vad som är vilken färg, utan bara aktivera en rad och en kolumn (så att en led tänds).
Den första ser varje rad som röd, grön och blå, och väljer ut en beroende på den tredje variabeln.
Detta skulle kunna skickas via exempelvis: AKTIVERA_LED(r, 6, 15); (Eller kanske AL(r, 6, 15); så det blir kort.)
Som använder dessa för att skicka kommando till shiftregister och så.
Tror ni detta skulle detta kunna fungera? (Förutsatt att man kan kommandon som tänder en specifik led.) Finns det något sådant för det nuvarande kortet?
För det skulle underlätta otroligt mycket vid själva mönsterprogrammeringen. Då man bara behöver skriva korta kommandon.
Jag har inte hunnit testa det Jesse skrev sist om invertering, och jag förstod inte helt hur det skulle göras.
Men jag kom att tänka på hur konstruktionen av (i alla fall mitt eget, senare) programmet skulle kunna vara utformat.
Skulle det gå att göra så att när man programmerar mönstret så behöver man bara skriva in två eller tre variabler?
EX: r (röd), 3 (rad) och 7 (kolumn). eller bara två: 5 (rad) 12 (kolumn).
Det senare exemplet skulle inte veta vad som är vilken färg, utan bara aktivera en rad och en kolumn (så att en led tänds).
Den första ser varje rad som röd, grön och blå, och väljer ut en beroende på den tredje variabeln.
Detta skulle kunna skickas via exempelvis: AKTIVERA_LED(r, 6, 15); (Eller kanske AL(r, 6, 15); så det blir kort.)
Som använder dessa för att skicka kommando till shiftregister och så.
Tror ni detta skulle detta kunna fungera? (Förutsatt att man kan kommandon som tänder en specifik led.) Finns det något sådant för det nuvarande kortet?
För det skulle underlätta otroligt mycket vid själva mönsterprogrammeringen. Då man bara behöver skriva korta kommandon.
Re: Val av microprocessor, RGB LED styrning
>Jag har inte hunnit testa det Jesse skrev sist om invertering, och jag förstod inte helt hur det skulle göras.
Det märker du när du testar
(observera tecknet för bitvis NOT som betyder att inverera alla bitar i en variabel: ~ )
Pyssla lite med koden, skriv om olika värden osv. för att se vad som händer. Det är det bästa sättet att lära sig. Om du inte förstår exakt vad som händer kommer du inte senare kunna göra ett program som styr alla dioder.
>Detta skulle kunna skickas via exempelvis: AKTIVERA_LED(r, 6, 15);
Detta kommer i ett senare skede när du fixat grundfunktionerna. Orsaken att det inte går att göra direkt på ett enkelt sätt är flera. (1) dels måste du ha en minnesmatris i SRAM som innehåller data för alla dioder, för att , när du ändrar data för en diod, måste shifta ut data för alla andra dioder samtidigt. (2) Som det är nu så sätter du utgångarna statiskt, dvs. fasta nivåer. Det gör att du bara kan tända samma lysdioder med samma färg i alla rader. För att kunna variera färg mellan raderna krävs att programmet i hög hastighet skickar ut data för varje rad om och om igen... Där är vi inte än på länge. För att förstå varför så gör följande tankeexperiment:
Överkurs:
antag att du aktiverar "röd" i kolumn 1 och "grön" i kolumn 2. Sedan aktiverar du rad 4 och rad 7. Vilka lysdioder kommer att lysa? dioderna anges som (rad:kolumn): diod(4:1) lyser rött, diod(4:2) lyser grönt. Samma mönster upprepas i alla andra aktiverade rader, så i rad 7 får du diod(7:1) = röd och diod(7:2) = grön.
Vad du till exempel kan göra när du fått mitt exempel att fungera som shiftar ut tre färger i de tre första kolumnerna, så kan du utöka detta till att omfatta alla åtta kolumner. Antingen fortsätter du att upprepa koden åtta gånger , eller så skriver du en loop. Om en kod upprepas ofta är det dags att skriva en funktion. Därför kan följande funktion vara praktisk: (du känner igen kodsnutten från tidigare exempel, fast nu är konstanten OUTPUT_RED utbytt mot variabeln colour:
då kan du lätt sätta färgen för fem kolumner eller fler:
(jag har bytt ut OUTPUT_RED mot enbart RED osv... dessutom har jag lagt till fler färger, t.ex. YELLOW - dessa extra färger definierar jag utifrån hur färger adderas:

(det jag kallade "violett" är egentligen magenta)
#define YELLOW RED & GREEN
#define WHITE RED & GREEN & BLUE
*** hur definieras BLACK ? ***
För att något ska synas måste minst en rad vara aktiverad. Jag skrev PORTA = 0b11111111; Det är binär representation av raderna, och tänder alla rader. Att det är skrivet binärt spelar ingen som helst roll för processorn - du kunde lika gärna skrivit 255 (decimalt) eller 0xff (hexadecimalt) eller använt de fördefinierade rad-konstanterna: PORTA = RAD1|RAD2|RAD3|RAD4|RAD5|RAD6|RAD7;. Resultatet blir exakt detsamma. Du skulle också kunna ändra rad automatiskt: Nedanstående kodsnutt byter rad automatiskt. Jag har dessutom definierat ett macro, sett_rad(radnr)för att koden ska bli mer lättläst.
Då rör det på sig !!! 
(det blir mycket om C-programmering här - använd några timmar att sätta dig in i alla nya begrepp)
>Eller kanske AL(r, 6, 15); så det blir kort.
Undvik alla sådana förkortningar! Det blir bara svårt att tolka när man inte vet vad förkortningen står för. Det är mycket lättare att förstå vad funktionen gör om den heter aktivera_led(); än om den heter al();. Funktioner skrivs alltid med små bokstäver, ibland med en stor bokstav i mitten, t.ex aktiveraLed();
Det märker du när du testar

Pyssla lite med koden, skriv om olika värden osv. för att se vad som händer. Det är det bästa sättet att lära sig. Om du inte förstår exakt vad som händer kommer du inte senare kunna göra ett program som styr alla dioder.
>Detta skulle kunna skickas via exempelvis: AKTIVERA_LED(r, 6, 15);
Detta kommer i ett senare skede när du fixat grundfunktionerna. Orsaken att det inte går att göra direkt på ett enkelt sätt är flera. (1) dels måste du ha en minnesmatris i SRAM som innehåller data för alla dioder, för att , när du ändrar data för en diod, måste shifta ut data för alla andra dioder samtidigt. (2) Som det är nu så sätter du utgångarna statiskt, dvs. fasta nivåer. Det gör att du bara kan tända samma lysdioder med samma färg i alla rader. För att kunna variera färg mellan raderna krävs att programmet i hög hastighet skickar ut data för varje rad om och om igen... Där är vi inte än på länge. För att förstå varför så gör följande tankeexperiment:
Överkurs:
antag att du aktiverar "röd" i kolumn 1 och "grön" i kolumn 2. Sedan aktiverar du rad 4 och rad 7. Vilka lysdioder kommer att lysa? dioderna anges som (rad:kolumn): diod(4:1) lyser rött, diod(4:2) lyser grönt. Samma mönster upprepas i alla andra aktiverade rader, så i rad 7 får du diod(7:1) = röd och diod(7:2) = grön.
Vad du till exempel kan göra när du fått mitt exempel att fungera som shiftar ut tre färger i de tre första kolumnerna, så kan du utöka detta till att omfatta alla åtta kolumner. Antingen fortsätter du att upprepa koden åtta gånger , eller så skriver du en loop. Om en kod upprepas ofta är det dags att skriva en funktion. Därför kan följande funktion vara praktisk: (du känner igen kodsnutten från tidigare exempel, fast nu är konstanten OUTPUT_RED utbytt mot variabeln colour:
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å.
_delay_ms(1);
PINB = CLOCK; // toggla klockan
_delay_ms(1);
PINB = CLOCK;
}
Kod: Markera allt
shifta_en_bit(RED);
shifta_en_bit(GREEN);
shifta_en_bit(WHITE);
shifta_en_bit(YELLOW);
shifta_en_bit(BLACK);
PORTA = 0b11111111 // tänd alla rader!!!

(det jag kallade "violett" är egentligen magenta)
#define YELLOW RED & GREEN
#define WHITE RED & GREEN & BLUE
*** hur definieras BLACK ? ***
För att något ska synas måste minst en rad vara aktiverad. Jag skrev PORTA = 0b11111111; Det är binär representation av raderna, och tänder alla rader. Att det är skrivet binärt spelar ingen som helst roll för processorn - du kunde lika gärna skrivit 255 (decimalt) eller 0xff (hexadecimalt) eller använt de fördefinierade rad-konstanterna: PORTA = RAD1|RAD2|RAD3|RAD4|RAD5|RAD6|RAD7;. Resultatet blir exakt detsamma. Du skulle också kunna ändra rad automatiskt: Nedanstående kodsnutt byter rad automatiskt. Jag har dessutom definierat ett macro, sett_rad(radnr)för att koden ska bli mer lättläst.
Kod: Markera allt
// definierar en macro som tänder EN rad med lysdioder och samtidigt släcker alla andra rader.
// radnr ska vara ett tal mellan 0 och 7 som anger radens nummer
#define sett_rad(radnr) PORTA = (1 << radnr)
shifta_en_bit(BLUE);
while (1) {
for (char i = 0; i<8 ; i++) {
sett_rad(i);
_delay_ms(200);
}
}

(det blir mycket om C-programmering här - använd några timmar att sätta dig in i alla nya begrepp)
>Eller kanske AL(r, 6, 15); så det blir kort.
Undvik alla sådana förkortningar! Det blir bara svårt att tolka när man inte vet vad förkortningen står för. Det är mycket lättare att förstå vad funktionen gör om den heter aktivera_led(); än om den heter al();. Funktioner skrivs alltid med små bokstäver, ibland med en stor bokstav i mitten, t.ex aktiveraLed();
Senast redigerad av jesse 30 september 2010, 00:41:56, redigerad totalt 1 gång.
Re: Val av microprocessor, RGB LED styrning
hoppsan,
jag gjorde ett typiskt nybörjarfel när jag satte invert-tecknet i mina macron:
man ska alltid ta som vana att ange parenteser runt ett uttryck i ett macro, för att macrot ska uppfattas rätt när det placeras i en formel.
alltså:
fel:
#define BLUE ~(1 << PB3)
rätt:
#define BLUE (~(1 << PB3))
annars kan det bli fel. exempelvis om det hade varit två siffror som adderats istället:
fel:
rätt:
Nu råkade det visserligen inte bli fel i just det här programmet, men man ska alltid ta som vana att ha parenteser.
PORTA = RED & BLUE; blir PORTA = ~(1 << PB5) & ~(1 << PB3); när det ska kompileras.

man ska alltid ta som vana att ange parenteser runt ett uttryck i ett macro, för att macrot ska uppfattas rätt när det placeras i en formel.
alltså:
fel:
#define BLUE ~(1 << PB3)
rätt:
#define BLUE (~(1 << PB3))
annars kan det bli fel. exempelvis om det hade varit två siffror som adderats istället:
fel:
Kod: Markera allt
#define SJU 3+4
A = SJU; // A = 7
A = SJU * 2; // blir INTE 14, eftersom A = 3+4*2 = 11.
Kod: Markera allt
#define SJU (3+4)
A = SJU; // A = 7
A = SJU * 2; // blir 14, eftersom A = (3+4)*2 = 14.
PORTA = RED & BLUE; blir PORTA = ~(1 << PB5) & ~(1 << PB3); när det ska kompileras.
Re: Val av microprocessor, RGB LED styrning
Hittade mycket bra läsning för att förstå hur man hanterar bitarna i en variabel:
Bitwise operation
och denna:
Bit manipulation
Helt nödvändig grundläggande kunskap i detta sammanhang!
Bitwise operation
och denna:
Bit manipulation
Helt nödvändig grundläggande kunskap i detta sammanhang!
Re: Val av microprocessor, RGB LED styrning
Lite andra roliga macron att roa sig med för att ändra rader:
Kod: Markera allt
#define sett_only_rad(radnr) PORTA = (1 << radnr) // tänder en rad, släcker övriga
#define sett_rad(radnr) PORTA |= (1 << radnr) // tänder en rad, låter övriga vara oförändrad
#define clear_rad(radnr) PORTA &= (1 << radnr) // släcker en rad, låter övriga vara oförändrad
#define clear_alla_rader PORTA = 0 // släcker alla rader
#define invertera_rader PINA = 0xff; // tänder de som varit släckta och släcker de som varit tända.
#define invertera_rad(radnr) PINA = (1 << radnr) // inverterar en specifik rad.
-
- Inlägg: 144
- Blev medlem: 8 september 2010, 14:26:12
Re: Val av microprocessor, RGB LED styrning
Där kom det in en hel del ny info.
Då vet jag vad jag kan göra med spilltid de närmaste dagarna =)
Då vet jag vad jag kan göra med spilltid de närmaste dagarna =)
-
- Inlägg: 144
- Blev medlem: 8 september 2010, 14:26:12
Re: Val av microprocessor, RGB LED styrning
Hej!
Nu har jag kommit fått reda på att skolan har en hel del utbildningsmaterial och saker, samt en rektor som kan en hel del om detta ämne. (Bättre upptäcka detta sent än aldrig.)
Dock är detta i assembler, men det låter ändå lockande att gå över på detta i stället, då jag kan få en hel del hjälp, på nära håll.
Skolan har kört på 16F877 microprocessorer, från Microchip.com. Tror ni dessa kan vara tillräckligt kraftfulla för mitt projekt?
Och tror ni att detta över huvudtaget kan vara värt det? och vara ett fungerande koncept?
Nu har jag kommit fått reda på att skolan har en hel del utbildningsmaterial och saker, samt en rektor som kan en hel del om detta ämne. (Bättre upptäcka detta sent än aldrig.)
Dock är detta i assembler, men det låter ändå lockande att gå över på detta i stället, då jag kan få en hel del hjälp, på nära håll.
Skolan har kört på 16F877 microprocessorer, från Microchip.com. Tror ni dessa kan vara tillräckligt kraftfulla för mitt projekt?
Och tror ni att detta över huvudtaget kan vara värt det? och vara ett fungerande koncept?
Re: Val av microprocessor, RGB LED styrning
Att du kan få hjälp direkt av någon på plats betyder mycket mer
än vilken modell eller fabrikat det är på processorn !
Just 16F877 är en utgången modell, om du vill ha en väldigt lik processor
så är det 16F887 som gäller. Det är ingen avgörande skillnad på den och
på den AVR som du har jobbat med hittills, det är som sagt helt andra
sakar som är viktigare.
Jag ser inte heller något avgörande problem med att göra detta i
assembler, det är kanske så att det hela passar bättre för assembler,
det är lite mer maskinnära så att säga.
än vilken modell eller fabrikat det är på processorn !
Just 16F877 är en utgången modell, om du vill ha en väldigt lik processor
så är det 16F887 som gäller. Det är ingen avgörande skillnad på den och
på den AVR som du har jobbat med hittills, det är som sagt helt andra
sakar som är viktigare.
Jag ser inte heller något avgörande problem med att göra detta i
assembler, det är kanske så att det hela passar bättre för assembler,
det är lite mer maskinnära så att säga.
Re: Val av microprocessor, RGB LED styrning
Jag skulle inte gått över från C till assembler men du gör som du vill. Du får tänka på att rektorn kanske inte har tid att skriva koden åt dig som jesse gör nu.
Re: Val av microprocessor, RGB LED styrning
Ja, jag antog väl kanske inte att någon annan skulle skriva koden... 

-
- Inlägg: 144
- Blev medlem: 8 september 2010, 14:26:12
Re: Val av microprocessor, RGB LED styrning
Det har ni ju rätt i.
Men ju mer jag lär mig från grunden (lära sig med riktigt utbildningsmaterial) desto mer borde jag kanske klara att göra själv, dessutom kan han nog hjälpa om det behövs, eller så får jag hitta någon som skriver assembler. Som t.ex. Swech, och många andra på denna jord.
Att lära sig detta kommer jag ju kunna ha nytta av i framtiden också.
Skulle någon assembler programmerare kunna skriva något kort exempel på assembler?
Bara något enkelt, exempelvis med addering av något och kanske en repetitionssats, om det inte är för krångligt?
Men ju mer jag lär mig från grunden (lära sig med riktigt utbildningsmaterial) desto mer borde jag kanske klara att göra själv, dessutom kan han nog hjälpa om det behövs, eller så får jag hitta någon som skriver assembler. Som t.ex. Swech, och många andra på denna jord.
Att lära sig detta kommer jag ju kunna ha nytta av i framtiden också.
Skulle någon assembler programmerare kunna skriva något kort exempel på assembler?
Bara något enkelt, exempelvis med addering av något och kanske en repetitionssats, om det inte är för krångligt?
Re: Val av microprocessor, RGB LED styrning
Menar du assembler för AVR eller för PIC ?
Menar du kod för att göra något specifikt eller bara i största allmänhet ?
Här har du i alla fall ett par PIC exempel :
http://www.jescab.se/PIC16.html.
När det gäller PIC så finns även massor av exempel på Piclist:
http://www.piclist.com/techref/microchip/routines.htm.
Det är indelat i olika kategorier så man kan navigera runt...
Menar du kod för att göra något specifikt eller bara i största allmänhet ?
Här har du i alla fall ett par PIC exempel :
http://www.jescab.se/PIC16.html.
När det gäller PIC så finns även massor av exempel på Piclist:
http://www.piclist.com/techref/microchip/routines.htm.
Det är indelat i olika kategorier så man kan navigera runt...
-
- Inlägg: 144
- Blev medlem: 8 september 2010, 14:26:12
Re: Val av microprocessor, RGB LED styrning
Ehm.
Jag tror AVR?
Eller? Är det ena bättre än det andra?
Jag tror AVR?
Eller? Är det ena bättre än det andra?