Inhaltsverzeichnis:

AVR-Assembler-Tutorial 6: 3 Schritte
AVR-Assembler-Tutorial 6: 3 Schritte

Video: AVR-Assembler-Tutorial 6: 3 Schritte

Video: AVR-Assembler-Tutorial 6: 3 Schritte
Video: AVR Assembly Tutorial: Part 3 (Inputs and Outputs) 2024, Juli
Anonim
AVR-Assembler-Tutorial 6
AVR-Assembler-Tutorial 6

Willkommen bei Tutorial 6!

Das heutige Tutorial wird kurz sein, in dem wir eine einfache Methode entwickeln, um Daten zwischen einem atmega328p und einem anderen über zwei Ports zu kommunizieren, die sie verbinden. Wir nehmen dann den Würfelroller aus Tutorial 4 und den Register Analyzer aus Tutorial 5, verbinden sie miteinander und verwenden unsere Methode, um das Ergebnis der Würfelwürfe von der Rolle an den Analyzer zu übermitteln. Wir werden die Rolle dann binär mit den LEDs ausdrucken, die wir für den Analysator in Tutorial 5 konstruiert haben. Sobald wir diese Funktion haben, können wir im nächsten Tutorial das nächste Stück unseres Gesamtprojekts konstruieren.

In diesem Tutorial benötigen Sie:

  1. Ihr Prototyping-Board
  2. Dein Würfelroller aus Tutorial 4
  3. Ihr Registeranalysator aus Tutorial 5
  4. Zwei Anschlussdrähte
  5. Eine Kopie des vollständigen Datenblatts (Revision 2014):

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

  6. Eine Kopie der Bedienungsanleitung (Revision 2014):

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

Hier ist ein Link zur vollständigen Sammlung meiner AVR-Assembler-Tutorials:

Schritt 1: Wie können wir zwei Mikrocontroller dazu bringen, miteinander zu kommunizieren?

Wie können wir zwei Mikrocontroller dazu bringen, miteinander zu sprechen?
Wie können wir zwei Mikrocontroller dazu bringen, miteinander zu sprechen?

Da wir damit beginnen, unser Projekt so zu erweitern, dass unser einzelnes Endprodukt aus einer Sammlung kleinerer Teile besteht, werden wir mehr Pins benötigen, als ein einzelner Atmega328P bereitstellen kann. Daher werden wir jeden Teil des Gesamtprojekts auf einem separaten Mikrocontroller durchführen und dann die Daten zwischen ihnen teilen. Das Problem, das wir lösen müssen, ist also, wie wir eine einfache Methode finden können, mit der die Controller miteinander kommunizieren und Daten zwischen ihnen übertragen können? Nun, eine Sache dieser Controller ist, dass sie jeweils 16 Millionen Befehle pro Sekunde ausführen. Dies ist zeitlich sehr genau und so können wir dieses Timing für die Datenübertragung nutzen. Wenn wir Millisekunden-Verzögerungen verwenden, um die Daten zu erstellen, müssen wir nicht wirklich genau sein, da die CPU 16.000 Anweisungen in einer einzigen Millisekunde ausführt. Mit anderen Worten, eine Millisekunde ist für die CPU eine Ewigkeit. Versuchen wir es also mit den Würfeln. Ich möchte das Ergebnis eines Würfelwurfs vom Würfelwürfel-Chip an den Analyse-Chip übertragen. Angenommen, Sie stehen auf der anderen Straßenseite und ich möchte Ihnen das Ergebnis meines Würfelwurfs signalisieren. Eine Sache, die ich tun könnte, wenn wir beide eine Uhr hätten, wäre, ich könnte eine Taschenlampe einschalten. Wenn Sie dann bereit sind, meine Daten zu empfangen, schalten Sie Ihre Taschenlampe ein und wir beide starten unsere Uhren. Dann lasse ich meine Taschenlampe für die genaue Anzahl von Millisekunden während des Würfelns an und schalte sie dann aus. Wenn ich also eine 12 gewürfelt hätte, würde ich mein Licht 12 Millisekunden lang eingeschaltet lassen. Das Problem mit dem oben Gesagten ist, dass wir für Sie und mich keine Möglichkeit haben, die Dinge genau genug zu messen, um zwischen 5 Millisekunden und 12. zu unterscheiden Millisekunden. Aber was ist damit: Angenommen, wir würden entscheiden, dass ich für jede Zahl auf dem Würfel ein Jahr lang mein Licht anlasse? Wenn ich dann eine 12 würfele, würde ich Sie 12 Jahre lang beleuchten, und ich denke, Sie werden mir zustimmen, dass es keine Möglichkeit gibt, dass Sie beim Herausfinden der Zahl einen Fehler machen, oder? Sie könnten eine Pause machen und Baseball spielen gehen, Sie könnten sogar 6 Monate lang Craps in Vegas spielen, solange Sie irgendwann im Jahr über die Straße blicken, um zu sehen, ob das Licht an ist, würden Sie keine Zählung verpassen. Genau das tun wir für die Mikrocontroller! Eine einzige Millisekunde für die CPU ist wie ein Jahr. Wenn ich das Signal also für 12 Millisekunden einschalte, besteht fast keine Chance, dass der andere Mikrocontroller es für 10 oder 11 verwechselt, egal was in der Zwischenzeit passiert und was nicht. Für die Mikrocontroller ist eine Millisekunde eine Ewigkeit. Also hier ist, was wir tun werden. Zuerst werden wir zwei Ports auf dem Controller als unsere Kommunikationsports auswählen. Ich werde PD6 zum Empfangen von Daten verwenden (wir könnten es Rx nennen, wenn wir möchten) und ich werde PD7 zum Übertragen von Daten wählen (wir könnten es Tx nennen, wenn wir möchten). Der Analysator-Chip überprüft periodisch seinen Rx-Pin und wenn er ein Signal sieht, wird er zu einer "Kommunikationsunterroutine" fallen und dann ein Rücksignal an die Würfelwalze senden, das besagt, dass er empfangsbereit ist. Beide beginnen mit der Zeitmessung und der Würfelroller sendet ein Signal (d. h. 5 V) für eine Millisekunde pro Zahl auf dem Würfel. Wenn der Wurf also eine Doppelsechser oder eine 12 war, dann würde der Würfelroller seine PD7 für 12 Millisekunden auf 5 V setzen und dann auf 0 V zurücksetzen. Der Analysator überprüft seinen PD6-Pin jede Millisekunde, zählt jedes Mal, und wenn er auf 0 V zurückgeht, gibt er die resultierende Zahl an das Analysator-Display aus und zeigt eine Zwölf in binärer Form auf den LEDs an. So ist der Plan. Mal sehen, ob wir es umsetzen können.

Schritt 2: Kommunikationsunterprogramme

Als erstes müssen wir die beiden Controller verbinden. Nehmen Sie also ein Kabel von PD6 auf einem und verbinden Sie es mit PD7 auf dem anderen und umgekehrt. Dann initialisieren Sie sie, indem Sie PD7 auf OUTPUT auf beiden und PD6 auf INPUT auf beiden setzen. Zum Schluss alle auf 0V stellen. Fügen Sie insbesondere Folgendes zum Abschnitt Init oder Reset des Codes auf jedem Mikrocontroller hinzu:

sbi DDRD, 7; PD7 auf Ausgang gestellt

cbi-PortD, 7; PD7 zunächst 0V cbi DDRD, 6; PD6 eingestellt auf Eingang cbi PortD, 6; PD6 anfänglich 0V clr total; Summe auf Würfeln anfangs 0

Lassen Sie uns nun die Kommunikations-Subroutine auf dem Würfel-Roller-Chip einrichten. Definieren Sie zuerst oben eine neue Variable namens "total", die die Gesamtzahl des Würfels speichert und auf Null initialisiert.

Schreiben Sie dann ein Unterprogramm, um mit dem Analysator zu kommunizieren:

kommunizieren:

cbi PortD, 7 sbi PortD, 7; Sendebereitschaftssignal warten: sbic PinD, 6; PinD lesen und bei 0V überspringen rjmp wait delay 8; Verzögerung zum Synchronisieren (experimentell gefunden) send: dec total delay 2; Verzögerung für jede Würfelzahl cpi total, 0; 0 bedeutet hier "gesamte" Anzahl Verzögerungen wurden gesendet breq PC+2 rjmp send cbi PortD, 7; PD7 bis 0V clr gesamt; Würfelsumme auf 0 zurücksetzen ret

Im Analysator fügen wir einen rcall aus der Hauptroutine zur Kommunikationsunterroutine hinzu:

clr-Analysator; bereiten Sie sich auf neue Nummer vor

sbic PinD, 6; PD6 auf 5V-Signal prüfen rcallcommunication; wenn 5V gehen, um mov-Analysator zu kommunizieren, gesamt; Ausgabe zum Analysator-Display rcall-Analyzer

und schreiben Sie dann das Kommunikationsunterprogramm wie folgt:

kommunizieren:

clr gesamt; Summe auf 0 zurücksetzen Verzögerung 10; Verzögerung, um Bounces loszuwerden sbi PortD, 7; PB7 auf 5V setzen, um Empfangsbereitschaft zu signalisieren: Verzögerung 2; warte auf die nächste Zahl inc total; inkrementiere Gesamtsbic PinD, 6; wenn PD6 auf 0V zurückgeht, sind wir mit dem Empfang von rjmp fertig; andernfalls Schleifenbackup für weitere Daten cbi PortD, 7; PD7 zurücksetzen, wenn fertig ret

Los geht's! Jetzt ist jeder Mikrocontroller so eingerichtet, dass er das Ergebnis des Würfelwurfs kommuniziert und dann auf dem Analysator anzeigt.

Wir werden später eine viel effizientere Art der Kommunikation implementieren, wenn wir den Inhalt eines Registers zwischen Controllern übertragen müssen, anstatt nur einen Würfelwurf zu machen. In diesem Fall verwenden wir immer noch nur zwei Drähte, die sie verbinden, aber wir verwenden 1, 1 für "Übertragung beginnen"; 0, 1 bedeutet "1"; 1, 0 bedeutet "0"; und schließlich 0, 0, um "Übertragung beenden" zu bedeuten.

Übung 1: Sehen Sie, ob Sie die bessere Methode implementieren können und verwenden Sie sie, um den Würfelwurf als 8-Bit-Binärzahl zu übertragen.

Ich füge ein Video bei, das meine in Betrieb zeigt.

Schritt 3: Fazit

Abschluss
Abschluss

Ich habe den vollständigen Code für Ihre Referenz angehängt. Es ist nicht so sauber und aufgeräumt, wie ich es gerne hätte, aber ich werde es aufräumen, wenn wir es in zukünftigen Tutorials erweitern.

Von nun an werde ich nur die Dateien mit Code anhängen, anstatt alles hier einzutippen. Wir werden nur die Abschnitte ausschreiben, die wir besprechen möchten.

Dies war ein kurzes Tutorial, in dem wir eine einfache Methode entwickelt haben, um unserem Analysator-Mikrocontroller das Ergebnis unseres Würfelwurfs von unserem Würfelroller-Mikrocontroller mitzuteilen, während wir nur zwei Ports verwenden.

Übung 2: Anstatt ein Ready-Signal zu verwenden, um anzuzeigen, wann die Würfelwalze zum Senden bereit ist, und ein anderes, wenn der Analysator zum Empfang bereit ist, verwenden Sie einen "externen Interrupt", der als "Pin Change Interrupt" bezeichnet wird. Die Pins des atmega328p können auf diese Weise verwendet werden, weshalb sie im Pinout-Diagramm neben ihnen PCINT0 bis PCINT23 haben. Sie können dies ähnlich wie beim Timer-Überlauf-Interrupt als Interrupt implementieren. In diesem Fall ist der Interrupt-"Handler" das Unterprogramm, das mit dem Würfelroller kommuniziert. Auf diese Weise müssen Sie das Kommunikationsunterprogramm nicht von main aus aufrufen: Es wird jedes Mal dorthin gehen, wenn ein Interrupt von einer Zustandsänderung an diesem Pin kommt.

Übung 3: Eine viel bessere Möglichkeit, Daten zwischen einem Mikrocontroller zu einer Sammlung anderer zu kommunizieren und zu übertragen, besteht darin, die eingebaute serielle 2-Draht-Schnittstelle am Mikrocontroller selbst zu verwenden. Versuchen Sie, Abschnitt 22 des Datenblatts zu lesen und herauszufinden, wie Sie ihn implementieren können.

Wir werden diese ausgefeilteren Techniken in Zukunft verwenden, wenn wir weitere Controller hinzufügen.

Die Tatsache, dass wir mit unserem Analysator nur die Summe des Würfelwurfs genommen und dann mit LEDs binär ausgedruckt haben, ist nicht wichtig. Tatsache ist, dass unser Analysator jetzt "weiß", was der Würfelwurf ist und ihn entsprechend verwenden kann.

Im nächsten Tutorial werden wir den Zweck unseres "Analyzers" ändern, ein paar weitere Schaltungselemente vorstellen und den Würfelwurf interessanter verwenden.

Bis zum nächsten Mal…

Empfohlen: