Bits bonzen stapsgewijze: controle van de Arduino voor WS2811, WS2812 en WS2812B RGB LED's (5 / 5 stap)

Stap 5: Bitbanging een Pulse Wave op een ATMega328p Microcontroller


Een van de voordelen van het gebruik van een microcontroller in tegenstelling tot, zeggen een computer CPU's, hebben wij een zeer strakke controle over de timing van de instructies die we in het programma.  In feite, om te laten zien hoe nauwkeurig het besturingselement kan worden, we gebruiken montage-instructies in plaats van de typische high-level functies zoals digitalWrite.  Het gebruik van assembly kan wij weten precies hoeveel klokcycli worden overgenomen tijdens de uitvoering van iedere instructie.

Aangezien de Arduino Uno R3 ontwikkeling van bestuur een 16MHz externe kloksignaal op de on-board ATMega328p handhaaft, voert de microcontroller een 1 klokcyclus instructie in precies 62.5ns (1/16 MHz = 62.5ns).  Aangezien we hoeveel klokcycli elke instructie vinden kunnen, kunnen we exact bepalen hoeveel instructies we moeten genereren ons signaal.

Zoals we eerder zagen, om te verzenden een 1 tot en met de WS281X-chip moeten we een signaal dat blijft bij een maximale (hoge) waarde voor 0.8μs, en vervolgens blijft bij een minimumwaarde (laag) voor 0.45μs doorgeeft.  Dus we willen schrijven een lijst van instructies die:

-Set digitale pin op hoog
-Wacht 0.8μs
-De digitale pin sets op laag
-Wacht 0.45μs

In assembler, kan dit worden bereikt door de volgende code:

ASM vluchtige (
Instructie klok beschrijving fase bits verzonden
"sbi %0, %1\n\t" / / 2 PIN HIGH (T = 2)
"rjmp. + 0\n\t" / / 2 nop nop (T = 4)
"rjmp. + 0\n\t" / / 2 nop nop (T = 6)
"rjmp. + 0\n\t" / / 2 nop nop (T = 8)
"rjmp. + 0\n\t" / / 2 nop nop (T = 10)
"rjmp. + 0\n\t" / / 2 nop nop (T = 12)
"nop\n\t"               // 1      nop                (T = 13)
'cbi %0, %1\n\t' / / 2 PIN laag (T = 15)
"rjmp. + 0\n\t" / / 2 nop nop (T = 17)
"rjmp. + 0\n\t" / / 2 nop nop (T = 19)
"nop\n\t"               // 1      nop                (T = 20)      1
::
Input operanden
"I" (_SFR_IO_ADDR(PORT)), //%0
"I" (PORT_PIN) //%1
);

Instructie
De eerste kolom bevat de instructie van de vergadering gevolgd door een regelinvoer en tab-tekens, waardoor de uiteindelijke assembler listing gegenereerd door de compiler beter leesbaar.

Klok
De tweede kolom toont het aantal klokcycli die elke instructie.  Voor deze set van eenvoudige instructies is er slechts één mogelijke waarde, we zullen zien hoe sommige instructies (bijvoorbeeld voorwaardelijke) wellicht 1, 2 of 3 mogelijke waarden.  Vergeet niet dat elke klokcyclus op de 16 MHz Arduino Uno 62.5ns is.

Beschrijving
De derde kolom geeft een zeer korte beschrijving van wat elke bewerking doet.

Fase
De term een beetje losjes, we gebruiken het om aan te geven de cumulatieve som van klokcycli genomen door de instructies die tot nu toe zijn uitgevoerd.

Om het verzenden van een enkele 255 waarde — 11111111 in binaire — naar de WS281X moeten we herhalen deze set van instructies 8 keer.  Bovendien, als we een 50μs (of hoger) invoegen pauze tussen de verzending van de 8-bit-reeks, de WS281X zakken de toegezonden gegevens aan het register van de uitvoer.  Zodra de gegevens zijn vergrendeld, moet de eerste LED (groen) van de WS281X inschakelen op het niveau van een maximale helderheid.  De Arduino schets binnen bitbang_255.zip toont deze bewerking.

We moeten veranderen van de code die een 1 produceert door het verminderen van de tijd gedurende welke het signaal een hoge (maximale) waarde heeft en de intensivering van de tijd gedurende welke het signaal op een laag (minimaal is) voor het verzenden van een 0.  Bovendien moeten we constateren dat de waarden voor elke LED altijd moeten worden opgegeven met behulp van 8 bits.  Bijvoorbeeld, als we wilden een waarde van 105 verzenden — 1101001 in binaire — wij zou moeten voor het verzenden van de 8 bits 01101001 met inbegrip van de eerste 0.  De code die een 0 produceert ziet er als:

ASM vluchtige (
Instructie klok beschrijving fase bits verzonden
"sbi %0, %1\n\t" / / 2 PIN HIGH (T = 2)
"rjmp. + 0\n\t" / / 2 nop nop (T = 4)
"rjmp. + 0\n\t" / / 2 nop nop (T = 6)
'cbi %0, %1\n\t' / / 2 PIN laag (T = 8)
"rjmp. + 0\n\t" / / 2 nop nop (T = 10)
"rjmp. + 0\n\t" / / 2 nop nop (T = 12)
"rjmp. + 0\n\t" / / 2 nop nop (T = 14)
"rjmp. + 0\n\t" / / 2 nop nop (T = 16)
"rjmp. + 0\n\t" / / 2 nop nop (T = 18)
"rjmp. + 0\n\t" / / 2 nop nop (T = 20) 0
::
Input operanden
"I" (_SFR_IO_ADDR(PORT)), //%0
"I" (PORT_PIN) //%1
);

We kunnen de Arduino schets binnen bitbang_105.zip gebruiken voor het genereren van het signaal wiens beeld kan worden gezien op de oscilloscoop scherm vangt die zijn gekoppeld aan deze stap.

Nu, voor de WS281X om weer te geven van de witachtig kleur die wij willen, moeten we niet één maar drie 255 waarden verzenden — in welk geval ons signaal bestaat uit 24 degenen — voordat op de 50μs voor de gegevens om in te haken.  We kunnen dit doen door kopiëren-plakken de elf montage-instructies boven 23 keer (kunt u het een poging geven de schets van de bitbang_255.ino wijzigen).  Maar de code zou onpraktisch voor het verzenden van waarden aan meer dan één WS281X chips.  Een betere oplossing zou zijn om te schrijven een lus die de 8-bits waarden doorlopen zou totdat alle drie van hen zijn verzonden.

De schets binnen bitbang_whitish.zip bevat een duidelijke beschrijving van de stappen om het gewenste resultaat te bereiken.  De main-sectie, geschreven in de logica hierboven beschreven, vergadering ziet er als volgt uit:

ASM vluchtige (
Instructie klok beschrijving fase
"nextbit:\n\t"              // -    label                                     (T =  0)
"sbi %0, %1\n\t" / / 2 signaal HIGH (T = 2)
"sbrc %4, 7\n\t" / / 1-2 als MSB ingesteld (T =?)
"mov %6, %3\n\t" / / 0-1 tmp zult signaal hoog ingesteld (T = 4)
"dec %5\n\t" / / 1 afname bitcount (T = 5)
"nop\n\t" / / 1 nop (stationair 1 klokcyclus) (T = 6)
"st % a2, %6\n\t" / / 2 set PORT aan tmp (T = 8)
"mov %6, %7\n\t" / / 1 reset tmp lage (standaard) (T = 9)
"breq nextbyte\n\t" / / 1-2 als bitcount == 0 -> nextbyte (T =?)
"rol %4\n\t" / / 1 verschuiven MSB zijde (T = 11)
"rjmp. + 0\n\t" / / 2 nop nop (T = 13)
'cbi %0, %1\n\t' / / 2 signaal laag (T = 15)
"rjmp. + 0\n\t" / / 2 nop nop (T = 17)
"nop\n\t"                  // 1    nop                                        (T = 18)
"rjmp nextbit\n\t" / / 2 bitcount! = 0 -> nextbit (T = 20)
"nextbyte:\n\t"          // -    label                                       -
"ldi %5, 8\n\t" / / 1 reset bitcount (T = 11)
"ld   %4, %a8+\n\t" // 2    val = *p++                             (T = 13)
'cbi %0, %1\n\t' / / 2 signaal laag (T = 15)
"rjmp. + 0\n\t" / / 2 nop nop (T = 17)
"nop\n\t"                 // 1    nop                                        (T = 18)
"dec %9\n\t" / / 1 afname bytecount (T = 19)
"Brně nextbit\n\t" / / 2 als bytecount! = 0 -> nextbit (T = 20)
::
);

De beste manier om te begrijpen van de werking van deze sectie is te overwegen verschillende case scenario's, en de montage-code regel voor regel te volgen.  We weten bijvoorbeeld dat om te verzenden een waarde van 255, we afgeven van 8 bits moeten met een tijdschema dat overeenkomt met een 1.  Met andere woorden, de digitale Pin verbonden met de WS281X hoog moet blijven voor 13 cycli (0.8125μs), en laag voor 7 (0.4375μs).  De bovenstaande code bereiken?  Laten we eens kijken wat er gebeurt wanneer we voor het eerst verzenden:

ASM vluchtige (
"nextbit:\n\t" / / Dit is alleen een label voor de regie van de sprongen hieronder.
"sbi %0, %1\n\t" / / het signaal is ingesteld op hoog, instructie gebruikt 2 cycli.
"sbrc %4, 7\n\t" / / True. Verzenden 255 impliceert huidige MSB is 'set' (= 1).
"mov %6, %3\n\t" / / Dit is uitgevoerd. "tmp" is ingesteld op hoog.
"dec %5\n\t" / / Bit wordt overgebracht, verlagen van de bit-teller.
"nop\n\t" / / moet actief om de 13 klokcycli.
"st % a2, %6\n\t" / / de waarde "tmp" schrijven naar de poort (pin nog hoog).
"mov %6, %7\n\t" / / Set "tmp" te laag voor de volgende pass door de lus.
"breq nextbyte\n\t" / / False. Beetje teller is niet 0, 1 cyclus gebruiken en wilt doorgaan.
"rol %4\n\t" / / verschuiven de bytewaarde MSB zijde.
"rjmp. + 0\n\t" / / Idle voor 2 klokcycli. Fase bereikt T = 13.
'cbi %0, %1\n\t' / / signaal is ingesteld op laag.
"rjmp. + 0\n\t" / / Idle voor 2 klokcycli.
"nop\n\t" / / Idle voor 1 klokcyclus.
"rjmp nextbit\n\t" / / Bit teller was niet 0 zo ga naar volgende beetje. T = 20.
);

Dus de instructies die daadwerkelijk worden uitgevoerd genereren een signaal op de data pin thats 13 cycli hoog (0.8125μs) en 7 LOW (0.4375μs), dus een beetje sturen met een waarde van 1 naar de WS281X.  Als we blijven bestuderen wat de code doet als de rest van de bits worden verzonden, en wat het doet als andere waarden dan 255 worden gebruikt, zullen we een dieper begrip van deze specifieke uitvoering van bitbanging.

Persoonlijk hoop ik dat u deze tutorial nuttig vinden om aan de slag met uw eigen communicatie protocollen telkens wanneer het noodzakelijk is bitbanging!

Gerelateerde Artikelen

Controle van de Arduino met behulp van android app

Controle van de Arduino met behulp van android app

In deze instructables ga ik uit te leggen hoe de controle van de arduino IO pinnen met behulp van een android app, die we hier schrijven.De mededeling zal via ethernet en gebruiken we het GET-verzoek voor het activeren van de IO.Laten we beginnen!Sta
Controle van een Arduino met PHP

Controle van een Arduino met PHP

hier is hoe te maken van je Arduino doen meer dan het internet zonder een ethernet of wifi schild. Dit is een eenvoudige manier om uw project bestuurbaar overal in de wereld!Stap 1: Platform CompatabilityDeze methode werkt niet onder Windows. Ik kan
Controle van de Arduino van Unity3d

Controle van de Arduino van Unity3d

Hallo jongens. In deze snelle tutorial ik "ll tonen u de eenvoudigste en meest efficiënte manier om controle van de Arduino met behulp van Unity3d. Uitsluitend volgen naar de opvoeden en vergeet niet te graag en schrijf u in voor meer video's.
Stapsgewijze LCD bedrading (4 Bit modus) en voorbeelden van de programmering voor Arduino

Stapsgewijze LCD bedrading (4 Bit modus) en voorbeelden van de programmering voor Arduino

dit instructable zal gids een gebruiker stapsgewijze in bedrading en programmering van een Hitachi HD44780 (of compatibele) chipset LCD-scherm aan een Arduino, met behulp van de LiquidCrystal-bibliotheek. Programmering voorbeelden gegeven voor alle o
Controle van de Arduino met Gamepad

Controle van de Arduino met Gamepad

Laatste tijd ik heb nieuwsgierig geweest over befriending Arduino of elke andere microcontroller met een gamepad om fysieke interactie met de dingen die ik maak, maar er leek te zijn geen snel of goedkope manier om te doen.De meeste oplossingen zijn
Met behulp van de Intel Edison op een koud gassysteem voor de controle van de reactie voor een raket klinkende

Met behulp van de Intel Edison op een koud gassysteem voor de controle van de reactie voor een raket klinkende

Wat is het doel van het maken van een controlesysteem reactie?Conventionele houding controlesystemen voor amateur-raketten gebruikt bijgevoegde vinnen, die stabiliteitscontrole van de passieve bieden. Voor het uitvoeren van actieve stabilisatie en ma
Controle van een arduino project via een aanpasbare android / Iphone app met Blynk en Wemos D1: de 2016 SUPER NOOB vriendelijke manier

Controle van een arduino project via een aanpasbare android / Iphone app met Blynk en Wemos D1: de 2016 SUPER NOOB vriendelijke manier

Het doel van dit instructable is om je te leren hoe wifi aangesloten arduino projecten de eenvoudigste en snelste manier mogelijk te maken. Als u een arduino project die u wilt vanaf beheren kunt uw smartphone en dat kostte slechts 4 eurs in hardware
Controle van de Arduino met visual basic 6.0

Controle van de Arduino met visual basic 6.0

Dit instructable is onderdeel van mijn boek Arduino + visual basic 6.0 (aanbrengen in uw eigen software controle arduino Robot.Visual basic 6.0 is een zeer oude versie sommigen kunnen vragen waarom we gebruik wilt maken van visual basic 6.0. Visual b
Controle van uw Arduino met een afstandsbediening

Controle van uw Arduino met een afstandsbediening

benieuwd over hoe om te controleren alles in uw huis met een eenvoudige afstandsbediening? Het is vrij eenvoudig en goedkoop.Stap 1: Verzamel spullen Hier is wat u nodig heeft:-Arduino (ik gebruik UNO)-Solderless breadboard-Een infrarood ontvanger-So
Controle van uw arduino vanaf uw PC met de Qt Gui

Controle van uw arduino vanaf uw PC met de Qt Gui

voor mijn eerste instructable ik zal u tonen het gebruik van Qt voor grafische interfaces voor je arduino (of elk apparaat rs232) makenDus als u maken van uw eigen grafische interfaces wilt, u bepalen spullen gewoon door te klikken op knoppen van uw
Controle van een Arduino met uw telefoon.

Controle van een Arduino met uw telefoon.

In dit Instructable zal ik laten zien hoe om te controleren uw spullen met uw telefoon en de arduino board. Ik heb alles gecontroleerd uit rookmachines ook Kerstmis licht is met dit programma.Video:Sorry dat de video is nogal vreemd, want mijn camera
Controle van de arduino met behulp van Blynk via usb

Controle van de arduino met behulp van Blynk via usb

Dit is mijn tweede instructable. In dit instructable zal ik laten zien hoe u kunt besturen LED met behulp van Blynk.Blynk is een applicatie die ons dashboard, evenals connectiviteit biedt. die u kunt downloaden van google play store (voor Android). &
Hoe de controle van de arduino met een mail

Hoe de controle van de arduino met een mail

Er zijn een heleboel oplossingen waarmee een Arduino board: web oplossingen, desktop applicatie oplossingen, hardwareoplossingen. Maar hoe zit het met e-mail? Ja, vind je iets op het web, maar ze nodig hebben voor ethernet schilden en vaak is Arduino
Controle van een Arduino met een horloge (TI eZ430 Chronos)

Controle van een Arduino met een horloge (TI eZ430 Chronos)

het horlogeDe Texas Instruments eZ430 Chronos is een coole gadget. Het heeft bidirectionele radiocommunicatie, en een gehele bos van sensoren: temperatuur, druk, versnelling.Het is in feite een development kit voor de MSP-430 (een low-power microcont