Inhoudsopgave:

AVR Assembler Tutorial 6: 3 stappen
AVR Assembler Tutorial 6: 3 stappen

Video: AVR Assembler Tutorial 6: 3 stappen

Video: AVR Assembler Tutorial 6: 3 stappen
Video: Видеокурс по AVR микроконтроллерам - Урок 3 2024, Juli-
Anonim
AVR-montagehandleiding 6
AVR-montagehandleiding 6

Welkom bij les 6!

De tutorial van vandaag zal een korte tutorial zijn waarin we een eenvoudige methode zullen ontwikkelen om gegevens tussen de ene atmega328p en de andere te communiceren met behulp van twee poorten die ze verbinden. We nemen dan de dobbelsteenroller uit Tutorial 4 en de Register Analyzer uit Tutorial 5, verbinden ze met elkaar en gebruiken onze methode om het resultaat van de dobbelstenen van de roller naar de analyzer te communiceren. We zullen de rol dan binair afdrukken met behulp van de LED's die we voor de analysator hebben geconstrueerd in Tutorial 5. Als dit eenmaal werkt, kunnen we het volgende stuk van ons algehele project in de volgende tutorial construeren.

In deze tutorial heb je nodig:

  1. Uw prototypebord
  2. Je dobbelsteenroller uit Tutorial 4
  3. Uw Register Analyzer uit Tutorial 5
  4. Twee aansluitdraden
  5. Een kopie van het volledige gegevensblad (revisie 2014):

    www.atmel.com/images/Atmel-8271-8-bit-AVR-M…

  6. Een kopie van de handleiding van de instructieset (revisie 2014):

    www.atmel.com/images/atmel-0856-avr-instruc…

Hier is een link naar de volledige verzameling van mijn AVR-assembler-tutorials:

Stap 1: Hoe kunnen we twee microcontrollers met elkaar laten praten?

Hoe kunnen we twee microcontrollers met elkaar laten praten?
Hoe kunnen we twee microcontrollers met elkaar laten praten?

Aangezien we ons project beginnen uit te breiden, zodat ons enkele eindproduct bestaat uit een verzameling kleinere onderdelen, hebben we meer pinnen nodig dan een enkele Atmega328P kan leveren. Daarom gaan we elk onderdeel van het totale project op een aparte microcontroller doen en ze vervolgens de gegevens laten delen. Dus het probleem dat we moeten oplossen, is hoe we een eenvoudige methode kunnen bedenken waarmee de controllers met elkaar kunnen praten en gegevens tussen hen kunnen uitwisselen? Een ding over deze controllers is dat ze elk 16 miljoen instructies per seconde uitvoeren. Dit is zeer nauwkeurig getimed en dus kunnen we deze timing gebruiken om gegevens over te dragen. Als we millisecondenvertragingen gebruiken om de gegevens samen te stellen, hoeven we niet zo precies te zijn, aangezien de CPU 16.000 instructies in één milliseconde uitvoert. Met andere woorden, een milliseconde is een eeuwigheid voor de CPU. Dus laten we het proberen met de dobbelstenen. Ik wil het resultaat van een dobbelsteenworp van de dobbelsteenrolchip naar de analysatorchip sturen. Stel dat u aan de overkant van de straat staat en ik u het resultaat wil laten weten van mijn worp met een paar dobbelstenen. Een ding dat ik zou kunnen doen, als we allebei een horloge hadden, is dat ik een zaklamp zou kunnen aandoen, en als je klaar bent om mijn gegevens te ontvangen, zet je je zaklamp aan en we starten allebei onze klokken. Dan houd ik mijn zaklamp aan voor het exacte aantal milliseconden terwijl de dobbelstenen rollen en zet hem dan uit. Dus als ik een 12 zou rollen, zou ik mijn licht 12 milliseconden aanhouden. Het probleem met het bovenstaande is dat, voor jou en mij, we op geen enkele manier in staat zouden zijn om dingen nauwkeurig genoeg te timen om onderscheid te maken tussen 5 milliseconden en 12 milliseconden. Maar hoe zit dit: stel dat we zouden besluiten dat ik mijn licht een jaar lang zou laten branden voor elk nummer op de dobbelsteen? Als ik dan een 12 gooi, zou ik 12 jaar lang het licht op je schijnen en ik denk dat je het ermee eens zult zijn dat er geen mogelijkheid is dat je een fout maakt bij het uitzoeken van het getal, toch? Je zou een pauze kunnen nemen en gaan honkballen, je zou zelfs 6 maanden craps kunnen gaan spelen in Vegas, zolang je op een bepaald moment in het jaar naar de overkant van de straat keek om te zien of het licht aan was, je geen tel zou missen. Nou, dat is precies wat we doen voor de microcontrollers! Een enkele milliseconde voor de CPU is als een jaar. Dus als ik het signaal 12 milliseconden aanzet, is er bijna geen kans dat de andere microcontroller het 10 of 11 in de war brengt, ongeacht wat er in de tussentijd wordt onderbroken en wat er niet gebeurt. Voor de microcontrollers is een milliseconde een eeuwigheid. Dus hier is wat we zullen doen. Eerst zullen we twee poorten op de controller kiezen als onze communicatiepoorten. Ik zal PD6 gebruiken voor het ontvangen van gegevens (we zouden het Rx kunnen noemen als we dat willen) en ik zal PD7 kiezen voor het verzenden van gegevens (we zouden het Tx kunnen noemen als we dat willen). De analysatorchip zal periodiek zijn Rx-pin controleren en als hij een signaal ziet, valt hij naar een "communicatiesubroutine" en zendt dan een retoursignaal naar de dobbelsteenroller die zegt dat hij klaar is om te ontvangen. Ze beginnen allebei met de timing en de dobbelsteenroller zendt een signaal (d.w.z. 5V) voor een milliseconde per nummer op de dobbelsteen. Dus als de worp dubbele zessen was, of een 12, dan zou de dobbelsteenroller zijn PD7 12 milliseconden op 5V zetten en dan terugzetten naar 0V. De analysator controleert elke milliseconde zijn PD6-pin, waarbij hij elke keer telt, en wanneer hij teruggaat naar 0V, voert hij het resulterende getal uit naar het display van de analysator, waarbij een twaalf in binair getal op de LED's wordt weergegeven. Dus dat is het plan. Eens kijken of we het kunnen implementeren.

Stap 2: Communicatiesubroutines

Het eerste dat we moeten doen, is de twee controllers aansluiten. Dus neem een draad van PD6 op de ene en sluit deze aan op PD7 op de andere, en vice versa. Initialiseer ze vervolgens door PD7 op OUTPUT op beide in te stellen en PD6 op INPUT op beide. Stel ze tenslotte allemaal in op 0V. Voeg in het bijzonder het volgende toe aan het gedeelte Init of Reset van de code op elke microcontroller:

sbi DDRD, 7; PD7 ingesteld op uitvoer

cbi PoortD, 7; PD7 aanvankelijk 0V cbi DDRD, 6; PD6 ingesteld op ingang cbi PortD, 6; PD6 aanvankelijk 0V clr totaal; totaal op dobbelstenen aanvankelijk 0

Laten we nu de communicatie-subroutine instellen op de dice-roller-chip. Definieer eerst een nieuwe variabele bovenaan genaamd "totaal", die het totale aantal geworpen op het paar dobbelstenen zal opslaan en initialiseren op nul.

Schrijf vervolgens een subroutine om met de analysator te communiceren:

communiceren:

cbi PoortD, 7 sbi PoortD, 7; Verzend gereed signaal wacht: sbic PinD, 6; lees PinD en sla over als 0V rjmp wachtvertraging 8; vertraging om te synchroniseren (vond dit experimenteel) verzenden: dec totale vertraging 2; vertraging voor elke dobbelsteentelling cpi totaal, 0; 0 betekent hier "totaal" aantal vertragingen verzonden breq PC+2 rjmp send cbi PortD, 7; PD7 tot 0V clr totaal; reset dobbelstenen totaal naar 0 ret

In de analysator voegen we een rcall van de hoofdroutine toe aan de communicerende subroutine:

clr-analysator; bereid je voor op een nieuw nummer

sbic PinD, 6; controleer PD6 voor een 5V signaal rcall communiceren; als 5V naar de mov-analysator gaat, totaal; uitvoer naar analysatorweergave rcall-analysator

en schrijf vervolgens de communicatie-subroutine als volgt:

communiceren:

clr totaal; reset totaal naar 0 vertraging 10; vertraging om bounces kwijt te raken sbi PortD, 7; stel PB7 in op 5V om signaal gereed te ontvangen: vertraging 2; wacht op het volgende nummer incl. totaal; verhoging totaal sbic PinD, 6; als PD6 teruggaat naar 0V zijn we klaar met rjmp ontvangen; loop anders een back-up voor meer gegevens cbi PortD, 7; reset PD7 wanneer klaar ret

Daar ga je! Nu is elke microcontroller ingesteld om het resultaat van de dobbelsteenworp te communiceren en vervolgens weer te geven op de analysator.

We zullen later een veel efficiëntere manier van communiceren implementeren wanneer we de inhoud van een register tussen controllers moeten overdragen in plaats van alleen een dobbelsteenworp. In dat geval zullen we nog steeds slechts twee draden gebruiken om ze met elkaar te verbinden, maar we zullen 1, 1 gebruiken om "begin met verzenden" te betekenen; 0, 1 betekent "1"; 1, 0 betekent "0"; en ten slotte 0, 0 om "eindtransmissie" te betekenen.

Oefening 1: Kijk of je de betere methode kunt implementeren en deze kunt gebruiken om de dobbelsteenworp over te dragen als een 8-bits binair getal.

Ik zal een video bijvoegen die de mijne in werking laat zien.

Stap 3: Conclusie

Conclusie
Conclusie

Ik heb de volledige code voor uw referentie bijgevoegd. Het is niet zo schoon en netjes als ik zou willen, maar ik zal het opruimen als we het in toekomstige tutorials uitbreiden.

Vanaf nu zal ik alleen de bestanden met code bijvoegen in plaats van alles hier te typen. We zullen gewoon de secties typen die we willen bespreken.

Dit was een korte zelfstudie waarin we een eenvoudige methode bedachten om onze analysator-microcontroller te vertellen wat het resultaat was van onze dobbelsteenworp van onze dobbelsteen-roller-microcontroller terwijl we slechts twee poorten gebruikten.

Oefening 2: In plaats van een klaar-signaal te gebruiken om aan te geven wanneer de dobbelsteenrol klaar is om te verzenden en een ander wanneer de analysator klaar is om te ontvangen, gebruik je een "externe onderbreking", een "Pin Change Interrupt" genaamd. De pinnen op de atmega328p kunnen op deze manier worden gebruikt, daarom hebben ze PCINT0 tot en met PCINT23 naast zich in het pinout-diagram. Je kunt dit op dezelfde manier als een interrupt implementeren als bij de timer-overflow-interrupt. In dit geval zal de interrupt "handler" de subroutine zijn die communiceert met de dobbelsteenroller. Op deze manier hoeft u de communicatie-subroutine niet daadwerkelijk vanuit de hoofdroutine aan te roepen: het zal daarheen gaan wanneer er een interrupt komt van een verandering van status op die pin.

Oefening 3: Een veel betere manier om te communiceren en gegevens over te dragen tussen de ene microcontroller naar een verzameling andere is het gebruik van de ingebouwde 2-draads seriële interface op de microcontroller zelf. Probeer sectie 22 van de datasheet te lezen en kijk of u erachter kunt komen hoe u het kunt implementeren.

We zullen deze geavanceerdere technieken in de toekomst gebruiken wanneer we meer controllers toevoegen.

Het feit dat we met onze analysator alleen het totaal van de dobbelsteenworp hebben genomen en deze vervolgens binair uitprinten met behulp van LED's, is niet belangrijk. Het feit is dat onze analysator nu "weet" wat de dobbelsteenworp is en deze dienovereenkomstig kan gebruiken.

In de volgende tutorial zullen we het doel van onze "analysator" veranderen, nog een paar circuitelementen introduceren en de dobbelsteenworp op een interessantere manier gebruiken.

Tot de volgende keer…

Aanbevolen: