Re: Val av microprocessor, RGB LED styrning
Postat: 13 september 2010, 13:31:26
Jag har inte tänkt igenom det här jättemycket. Det är inte ett färdigt fungerande förslag utan mer en idé man kan bygga vidare på. (Det är ganska mycket jobb att sitta och räkna ut alla detaljer, men det är ju inte jag som ska göra det jobbet, hade jag tänkt). Som jag tänkt nu så fungerar bara dimning av alla dioder samtidigt (eller möjligtvis rad för rad). Jag kan ju gå igenom lite grann ungefär hur jag tänkt mig:
Timing:
En diodrad åt gången ska lysa. Vilka dioder i raden som ska lysa i just den raden bestäms av innehållet i shiftregistren just då. Vilken rad det är fråga om beror på kretsarna uppe till höger i ritningen: counter - decoder.... "counter" är en binärräknare. Om man har 8 rader behövs det tre bitar i räknaren som i decodern omvandlas till 8 datalinjer... Vad som händer är då att en rad i taget stegas fram av räknaren. För att processorn ska ha koll på vilken rad den är på kan den nollställa räkanren på räknarens resetingång.
Studera list of 74 series Logic ICs.
Här kan du hitta alla logikkretsar som behövs, t.ex. 74HC393 = 4-bit Binary Counter, 74HC138 = 3 to 8-line Decoder/Demultiplexer. Shiftregistren kan vara t.ex. 74HC595. Leta upp och läs databladen för kretsarna.
För varje rad som ska lysa så skall alltså detta ske:
1) 18 bitar data skickas ut seriellt till shiftregistren. Detta kan göras "manuellt" i programvaran (bitbanging) men det smartaste är att använda det färdiga SPI - Serial interface. Se datablad för den processor du kommer att välja - t.ex här: Atmega1284P kapitel 17 - SPI (sidan 162) så kan du läsa om seriell kommunikation. Den är speciellt anpassad för att kunna skicka ut och läsa in data från shiftregister.
2) när alla bitar är på plats så skickas en signal till "latch" som överför bitarna till shiftregistrens utgångar. Nu kommer de valda lysdioderna i den raden att lysa. Denna signal bör skickas samtidigt som man byter till ny rad. Bitarna på shiftregistrens utgångar kommer att vara satta ända tills nästa gång en "latch" signal kommer - då nästa rad ska visas.
En tanke på hur man skulle kunna göra denna dimning vore kanske att man använder sig av antingen shiftregistrens "output enable" eller kanske ännu hellre den 8-bitars multiplexerns "output enable"... alltså signaler som styr om utgångarna ska vara på eller inte.
Multiplexern skulle jag välja av följande anledning:
tittar man på databladet för 74HC595 så ser man att utgångarna hamnar i tri-state-läge om man avaktiverar utgångarna med output-enable. Men multiplexern antar ett logiskt värde då utgångarna "avaktiveras" med output-enable. Tittar man lite extra på vad multiplexern gör , samt på den transistorkonstruktion jag föreslagit för att styra raderna så upptäcker man:
* för att aktivera en rad krävs en logisk etta på utgången. Alla andra rader ska då ha logisk nolla. (detta beror på transistorernas funktion - en transistor inverterar signalen, - här har vi två transistorer - en NPN och en PNP. Denna koppling fungerar bra om man driver lysdioderna med högre drivspänning än processorn - om man ska driva lysdioderna med samma spänning som processorn så behövs inte NPN-transistorn och då blir signalen inverterad bara en gång). Men 74HC138 har inverterade utgångar, dvs den valda raden får en nolla och övriga en etta. Detta skulle alltså passa utmärkt om du inte har nån NPN-transistor före. Men nu har du det (antar vi just nu) och då ser vi att det finns en motsvarande multiplexer som heter 74HC238 och som har icke-invererade utgångar. Så vi väljer en 74HC238. Denna ger logisk nolla på alla utgångar när den är "avstängd" med någon av output-enable-ingångarna.
* Här (på en av multiplexerns output-enable-ingång) kan vi alltså koppla in en dimmerfunktion. Om man för varje rad som visas bara har på utgången en viss tid.
* Detta kan man lätt styra med en timer - samma timer som då styr allt annat i programmet som har med att skicka ut data att göra.
Timern programmeras som PWM med fast frekvens. En av processorns utgångar blir PWM-utgång. (Du kan inte välja vilken pinne - den är förutbestämd och "hör till timern"). Antagligen kan man använda denna utgång med fördel att även styra klockan på räknaren (74HC393) och latch-ingången på shiftregistrena. Då får vi allt detta synkroniserat. För att även synkronisera utshiftandet av data till shiftregistren kan timern generera en interrupt, eller alternativt, sätta en flagga, som triggar att man skickar ut nästa rads data.
Detta är ganska mycket "händelsebaserad" programmering, så om man tänker sekventiell programmering här kan det ara svårt att hänga med. Men om du läst java som är objektorienterat så borde det inte vara några större problem.
Allt utgår från timern - det är den som triggar övriga händelser. Om detta görs som interrupt och även de tre byten som ska shiftas ut seriellt blir interruptstyrt så kommer processorn, när det hela väl är igång, att vara nästan helt ledig för att göra annat. Då får du gott om tid på dig att ändra dimning, bygga mönster osv...
Om någon kommer på hur man ska dimma varje enskild LED-grupp så får man nog ändra lite i tänket.
EDIT: har lagt in länken till Atmega1284P i texten. (missade det förut)
Timing:
En diodrad åt gången ska lysa. Vilka dioder i raden som ska lysa i just den raden bestäms av innehållet i shiftregistren just då. Vilken rad det är fråga om beror på kretsarna uppe till höger i ritningen: counter - decoder.... "counter" är en binärräknare. Om man har 8 rader behövs det tre bitar i räknaren som i decodern omvandlas till 8 datalinjer... Vad som händer är då att en rad i taget stegas fram av räknaren. För att processorn ska ha koll på vilken rad den är på kan den nollställa räkanren på räknarens resetingång.
Studera list of 74 series Logic ICs.
Här kan du hitta alla logikkretsar som behövs, t.ex. 74HC393 = 4-bit Binary Counter, 74HC138 = 3 to 8-line Decoder/Demultiplexer. Shiftregistren kan vara t.ex. 74HC595. Leta upp och läs databladen för kretsarna.
För varje rad som ska lysa så skall alltså detta ske:
1) 18 bitar data skickas ut seriellt till shiftregistren. Detta kan göras "manuellt" i programvaran (bitbanging) men det smartaste är att använda det färdiga SPI - Serial interface. Se datablad för den processor du kommer att välja - t.ex här: Atmega1284P kapitel 17 - SPI (sidan 162) så kan du läsa om seriell kommunikation. Den är speciellt anpassad för att kunna skicka ut och läsa in data från shiftregister.
2) när alla bitar är på plats så skickas en signal till "latch" som överför bitarna till shiftregistrens utgångar. Nu kommer de valda lysdioderna i den raden att lysa. Denna signal bör skickas samtidigt som man byter till ny rad. Bitarna på shiftregistrens utgångar kommer att vara satta ända tills nästa gång en "latch" signal kommer - då nästa rad ska visas.
En tanke på hur man skulle kunna göra denna dimning vore kanske att man använder sig av antingen shiftregistrens "output enable" eller kanske ännu hellre den 8-bitars multiplexerns "output enable"... alltså signaler som styr om utgångarna ska vara på eller inte.
Multiplexern skulle jag välja av följande anledning:
tittar man på databladet för 74HC595 så ser man att utgångarna hamnar i tri-state-läge om man avaktiverar utgångarna med output-enable. Men multiplexern antar ett logiskt värde då utgångarna "avaktiveras" med output-enable. Tittar man lite extra på vad multiplexern gör , samt på den transistorkonstruktion jag föreslagit för att styra raderna så upptäcker man:
* för att aktivera en rad krävs en logisk etta på utgången. Alla andra rader ska då ha logisk nolla. (detta beror på transistorernas funktion - en transistor inverterar signalen, - här har vi två transistorer - en NPN och en PNP. Denna koppling fungerar bra om man driver lysdioderna med högre drivspänning än processorn - om man ska driva lysdioderna med samma spänning som processorn så behövs inte NPN-transistorn och då blir signalen inverterad bara en gång). Men 74HC138 har inverterade utgångar, dvs den valda raden får en nolla och övriga en etta. Detta skulle alltså passa utmärkt om du inte har nån NPN-transistor före. Men nu har du det (antar vi just nu) och då ser vi att det finns en motsvarande multiplexer som heter 74HC238 och som har icke-invererade utgångar. Så vi väljer en 74HC238. Denna ger logisk nolla på alla utgångar när den är "avstängd" med någon av output-enable-ingångarna.
* Här (på en av multiplexerns output-enable-ingång) kan vi alltså koppla in en dimmerfunktion. Om man för varje rad som visas bara har på utgången en viss tid.
* Detta kan man lätt styra med en timer - samma timer som då styr allt annat i programmet som har med att skicka ut data att göra.
Timern programmeras som PWM med fast frekvens. En av processorns utgångar blir PWM-utgång. (Du kan inte välja vilken pinne - den är förutbestämd och "hör till timern"). Antagligen kan man använda denna utgång med fördel att även styra klockan på räknaren (74HC393) och latch-ingången på shiftregistrena. Då får vi allt detta synkroniserat. För att även synkronisera utshiftandet av data till shiftregistren kan timern generera en interrupt, eller alternativt, sätta en flagga, som triggar att man skickar ut nästa rads data.
Detta är ganska mycket "händelsebaserad" programmering, så om man tänker sekventiell programmering här kan det ara svårt att hänga med. Men om du läst java som är objektorienterat så borde det inte vara några större problem.
Allt utgår från timern - det är den som triggar övriga händelser. Om detta görs som interrupt och även de tre byten som ska shiftas ut seriellt blir interruptstyrt så kommer processorn, när det hela väl är igång, att vara nästan helt ledig för att göra annat. Då får du gott om tid på dig att ändra dimning, bygga mönster osv...
Om någon kommer på hur man ska dimma varje enskild LED-grupp så får man nog ändra lite i tänket.
EDIT: har lagt in länken till Atmega1284P i texten. (missade det förut)