Stap 3: Bit-Banging en opslaan van een paar meer klokcycli
800khz op een 16Mhz AVR is 20 klokcycli.
20 klokcycli op een AVR zit alot. Het gaat niet over PIC12 / 16C hier met 4 teken per instructie en slechts één echte register. De AVR veel per klok cyclus. Als er niet sprake was van de verplichting tot shuffle de RGB-volgorde kon dan de AVR doen deze seriële zonder een zweet te breken.
In feite is het enige wat dat de AVR doet niet schijnen op bits I/O registers wijzigen. Dit neemt twee klokcycli zoals wordt weergegeven in de details voor de SBI instructie hieronder. De CPU heeft het register lezen, wijzigen en schrijven het terug. Het is een paar niet-vertakking instructies in de AVR te nemen twee klokken. (Opmerking: de AVR XMega heeft dit probleem opgelost en nu is slechts 1 klok)
Met behulp van deze instructie in time kritieke paden is niet leuk als Alanen code toonde. Hij moest springen en hop helemaal over de plaats om het gelijk van de lengtes van het pad.
sbrc r19, 7; test beetje Hallo duidelijk
rjmp 3f ; True, overslaan pin hi-lo >
CBI % [poort], % [pin]; valse, pin hi -> lo
3: sbrc r19, 7; vertraging van beide codepaden gelijk
rjmp 4f
4: nop ; Pulse timing vertraging
Dus als de werkelijke CBI en SBI instructies willen nemen 2 klokcycli hoe dan ook, maar dan heb je te verliezen 2 klokcycli om gelijk de lengtes van het pad, waarom niet gewoon de Lees wijzigen schrijven zelf. Dit duurt 3 cycli totale.
IN R16, PortX; De huidige status van het register lezen
ORI R16, PinX; De hoge x-bit ingesteld
UIT PortX, R16; Schrijven van de nieuwe waarde uit het register
Het volgende ding dat u doen kunt om tijd te besparen is alles buiten de lus kunt verplaatsen. Omdat deze code 100% van de CPU-tijd gebruikt is, er is geen risico op iets anders gaat veranderen PortX. Ook omdat er geen andere code wordt uitgevoerd, kunnen we zoveel CPU-registers als we willen gebruiken.
Doe deze IN-ing en AND/OR-ing manier buiten de lus.
IN PinLo, PortX; Maak een kopie van de byte in PortX
ANDI PinLo, 0xFE; Wijzigen om de waarde te schrijven om pin lo
IN PinHi, PortX; Maak een kopie van de byte in PortX
ORI PinHi, 0x01; Wijzigen om de waarde te schrijven om pin hi
Lus:
bla
bla
uit PortX, PinLo; De pincode van de uitgang laag instellen
bla
bla
rjmp Loop:
Dit heeft nu de hele beetje gelijkwaardige, seriële verschuiving, beetje tellen en nemen slechts 9 klokken in een lus gemaakt. Dit laat 11 klokken gratis voor het laden van gegevens en schuifelen.
Dit zou weer afvalbergen van de tijd, zo niet voor het buiten de orde RGB-ding. Wegens het buiten de orde RGB ding kunnen we niet gewoon elke byte lezen als de volgende dia gaan behandelen. We moeten een beslissing nemen over waar op te slaan van het nieuw Lees byte naar een buffer en waar vandaan een buffer te krijgen de volgende byte te sturen.
Dit is waar de IJMP-instructie komt aan de redding. De pagina van de AVR-instructie set is hierboven weergegeven. We gebruiken het als een instructie van de zaak/switch in een software-toestandsmachine. Wij annuleerteken troep wat de volgende staat moet zonder te doen van eventuele evaluaties te maken in elke staat.
We kunnen dit doen omdat we altijd weten welke kleur de volgende byte is gonna be
Als de rode byte worden momenteel verwerkt zullen de volgende byte groen
Als de groene byte worden momenteel verwerkt zullen de volgende byte blauw
Als de BLUE byte worden momenteel verwerkt zal de volgende byte rood worden
bv. In de rode Braziliaanse kunnen we gewoon zeggen
STAAT = GROEN
We hoeven niet te zeggen
Als (iets) dan staat = groene anders staat = blauw
Dit bespaart een paar klokken hoeven te evalueren om het even wat.
De hele code wordt weergegeven als een afbeelding hier. Opnieuw Stuur me een PM als je wilt dat ik per e-mail naar u.
De opmerkingen in de code zijn hopelijk genoeg zelfs laat iemand niet vertrouwd zijn met AVR-ASM begrijpen.