Microcontroller Tutorial Teil 10: Ein Spiel erstellen (The Button Game)

Mikrocontroller-Tutorial Teil 10: Erstellen eines Spiels (The Button Game): 4 Schritte

Jetzt sind wir bereit, das, was wir wissen, anzuwenden und ein tatsächliches Spiel zu machen. Das Spiel besteht aus zwei Druckknöpfen und zwei LED-Sätzen (2 Reihen zu je 7). Das Ziel des Spiels ist es, zu sehen, wer zwischen zwei Personen in kürzester Zeit am häufigsten auf den Knopf drücken kann. Beim Drücken der Taste leuchten die LEDs nacheinander auf, bis die letzte LED leuchtet und diese Seite gewinnt. Der Gewinner wird durch Blinken der LEDs auf der Seite angezeigt.

Die Schaltung besteht aus zwei LED-Stäben, 7 in jeder Reihe. Da sich auf jeder Seite sieben befinden, kann für jedes Set ein einziger Port verwendet werden, an dem ausreichend Platz für einen Druckknopf vorhanden ist. Ein Druckknopf und sieben LEDs können an acht Pins oder einen Port von Pins angeschlossen werden. Im Video wird Port B für die Tasten und LEDs eines Players und Port D für die Tasten und LEDs des anderen Players verwendet.

Zubehör:

Schritt 1: Grundlagen der Programmierung

In unserem Video wurden drei grundlegende Programmierfunktionen veranschaulicht: Arrays, Kapselung und zusätzliche Informationen zu Variablen. Arrays werden verwendet, um die für jeden Player verwendeten Variablen zu vereinfachen. Anstatt eindeutige Variablen für das Entprellen von Schaltflächen, das Drücken von Schaltflächen und das Aufleuchten von LEDs zu generieren, wurde für jede eine einzige Variable mit einem Array von "2" verwendet, eine für jeden Spieler. Dies vereinfachte auch die Verwendung von Kapselung und sich wiederholendem Code. Wenn Code mehrmals im Programm verwendet werden soll, ist es sinnvoll, diesen Code an der speziellen Stelle, die als Funktion (Methode) bezeichnet wird, abzulegen, damit er bei Bedarf beschriftet werden kann. Da es zwei Spieler gab, verwendeten wir einen identischen Code, der ursprünglich zweimal verwendet wurde, als das Drücken und Loslassen der Taste getestet wurde, und den Code, der zum Aufleuchten der LEDs verwendet wird.

Insbesondere im Programm werden Sie einige neue Dinge sehen. Mit der Erstellung neuer Funktionen können wir im Wesentlichen neue Befehle erstellen, die das Programm verstehen wird. Diese Funktionen heißen ProcessPressedButton und ProcessReleasedbutton. Mit Hilfe der Arrays muss lediglich die Array-Nummer (Player-Nummer) an diese Funktionen übergeben werden. Im Programm werden Sie als Erstes feststellen, dass es am Anfang einige Aussagen mit "void" gibt. Diese werden Funktionsprototypen genannt. Die Sprache von C oder C ++ erfordert, dass diese Funktionsprototypen den Compiler darüber informieren, dass diese im Programm verwendet werden, bevor sie tatsächlich definiert werden. Beachten Sie, dass die Funktionen im Programm (innerhalb der Hauptfunktion) vor den eigentlichen Funktionen und dem Code (nach der Hauptfunktion) verwendet werden. Eine Alternative dazu wäre, die Hauptfunktion tatsächlich am Ende des Programms zu platzieren und die Prototypen zu entfernen, aber ich persönlich möchte die Hauptfunktion aus Gründen der Klarheit am Anfang behalten. Es gibt sogar eine bessere Alternative: Sie können einige Bibliotheksdateien erstellen, die diese neuen Funktionen enthalten. Bislang haben wir diese Programmierstufe jedoch noch nicht in der Tutorial-Reihe erreicht.

Sie werden auch feststellen, dass es außerhalb der Hauptfunktion Ganzzahlen (Variablen) gibt (ignorieren Sie die Klammern und Nummer 2 vorerst). Dies erzwingt einen globalen Gültigkeitsbereich für diese Variablen. In diesem Bereich werden die deklarierten Variablen verwendet. Wenn eine Variable in einem bestimmten Codeblock wie in einer Funktion deklariert wird, lebt und stirbt die Variable in diesem Codeblock und allen Codeblöcken in diesem Block. Wenn die Variablen beispielsweise in der Hauptfunktion deklariert sind, können diese Variablen nicht in einer anderen Funktion verwendet werden, die sich außerhalb der Hauptfunktion befindet. Wenn die Variablen auf der untersten Ebene (außerhalb eines Blocks) definiert sind, werden sie global, und jeder Codeblock kann sie verwenden.

Nun die Arrays ... beachten Sie die [2] am Ende der globalen Variablen. Dies ermöglicht die Erstellung und Unterscheidung von zwei dieser Variablen mit [0] oder [1]. Warum "0"? Die Zahlen sind von 0 und nicht von 1 indexiert. Nehmen Sie also das Beispiel Gedrückt [2]. Dadurch werden eine Variable mit dem Namen "Gedrückt [0]" und eine Variable mit dem Namen "Gedrückt [1]" erstellt. Beachten Sie in den Funktionen, dass ich eine Variable in den Klammern habe. Kapselung und Arrays können einige wirklich coole Funktionen bei der Programmierung bieten.

Schritt 2: Der Code

#include #include void ProcessPressedButton (int ButtonPressed); void ProcessReleasedButton (int ButtonReleased); int Pressed_Confidence_Level [2]; int Released_Confidence_Level [2]; int Gedrückt [2]; int LEDNumber [2]; int main (void) {DDRB = 0b01111111; DDRD = 0b01111111; PORTB = 0b10000000; PORTD = 0b10000000; while (1) {if (bit_is_clear (PINB, 7)) {ProcessPressedButton (0); } else {ProcessReleasedButton (0); } if (bit_is_clear (PIND, 7)) {ProcessPressedButton (1); } else {ProcessReleasedButton (1); }}} void ProcessPressedButton (int ButtonPressed) {Pressed_Confidence_Level [ButtonPressed] ++; if (Pressed_Confidence_Level [ButtonPressed]> 500) {if (Pressed [ButtonPressed] == 0) {Pressed [ButtonPressed] = 1; if (ButtonPressed == 0) PORTB | = 1 << LEDNumber [ButtonPressed]; if (ButtonPressed == 1) PORTD | = 1 << LEDNumber [ButtonPressed]; LEDNumber [ButtonPressed] ++; if (LEDNumber [ButtonPressed]> 6) {für (int i = 0; i <10; i ++) {if (ButtonPressed == 0) PORTB = 0b11111111; if (ButtonPressed == 1) PORTD = 0b11111111; Verzögerung ms (10); if (ButtonPressed == 0) PORTB = 0b10000000; if (ButtonPressed == 1) PORTD = 0b10000000; Verzögerung ms (10); } LEDNumber [0] = 0; LEDNumber [1] = 0; PORTB = 0b10000000; PORTD = 0b10000000; }} Pressed_Confidence_Level [ButtonPressed] = 0; }} void ProcessReleasedButton (int ButtonReleased) {Released_Confidence_Level [ButtonReleased] ++; if (Released_Confidence_Level [ButtonReleased]> 500) {Pressed [ButtonReleased] = 0; Released_Confidence_Level [ButtonReleased] = 0; }}

Schritt 3: Erstellen einer Schaltflächenbibliothek

Dies ist das Programm, das den gesamten Code enthält, der den Tastenzustand bestimmt, und das Konfidenzniveau für das Drücken und Loslassen der Taste verfolgt, um den Entprellungseffekt zu beseitigen. Diese Bibliotheksdatei heißt "ButtonPress.h" und ist in der Include-Datei des Hauptprogramms enthalten. Wenn Sie diesen Code kopieren, einfügen und unter einem anderen Namen speichern, müssen Sie die Include-Datei für das Hauptprogramm ändern.

#ifndef ButtonPress

#Definiere ButtonPress

include char ButtonPressed (int buttonNumber, nicht signiertes char pinOfButton, nicht signiertes char portBit, int confidenceLevel);

char Pressed [numberOfButtons];

int Pressed_Confidence_Level [numberOfButtons]; // Taste drücken um zu messen

int Released_Confidence_Level [numberOfButtons]; // Tasterfreigabe messen

char ButtonPressed (int buttonNumber, nicht signiertes char pinOfButton, nicht signiertes char portBit, int confidenceLevel)

{

if (bit_is_clear (pinOfButton, portBit)) {Pressed_Confidence_Level [buttonNumber] ++; // Pressed Conficence erhöhen Released_Confidence_Level [buttonNumber] = 0; // Freigegebene Tastenkonfidenz zurücksetzen, da ein Tastendruck vorliegt, wenn (Pressed_Confidence_Level [buttonNumber]> confidenceLevel) // Anzeige für guten Tastendruck {if (Pressed [buttonNumber] == 0) {Pressed [buttonNumber] = 1; return 1;

} // Null es, damit ein neuer gedrückter Zustand ausgewertet werden kann Pressed_Confidence_Level [buttonNumber] = 0;

}

} else {Released_Confidence_Level [buttonNumber] ++; // Dies funktioniert genauso wie das gedrückte Pressed_Confidence_Level [buttonNumber] = 0; // Das Vertrauen der gedrückten Taste zurücksetzen, seit die Taste losgelassen wurde, wenn (Released_Confidence_Level [buttonNumber]> confidenceLevel) {Pressed [buttonNumber] = 0; Released_Confidence_Level [buttonNumber] = 0;

}

} return 0;

}

#endif

Schritt 4: Das eigentliche Programm, das wir mit der Button-Press-Bibliothek schreiben würden

#define numberOfButtons 2

umfassen

#include "ButtonPress.h"

int main (nichtig)

{

DDRB = 0b00001100;

PORTB = (1 << PINB0) | (1 << PINB1);

while (1) {if (Tastendruck (0, PINB, 0, 100)) PORTB ^ = (1 << PINB2);

if (ButtonPressed (1, PINB, 1, 100)) PORTB ^ = (1 << PINB3);

}

}

Beachten Sie, wie kurz das Hauptprogramm jetzt ist. Der größte Teil des Codes für das Drücken von Tasten und das Entprellen von Software wird in einer Bibliothek zusammengefasst. Sie müssen lediglich die Datei ButtonPress.h einbinden und eine define-Anweisung am Anfang des Programms verwenden, um dem Compiler mitzuteilen, wie viele Schaltflächen Sie verwenden möchten. Um festzustellen, ob eine Taste gedrückt wurde, geben Sie einfach eine "if" -Anweisung mit den Informationen zur jeweiligen Taste ab, z. B. der Tastennummer, dem Pin und dem Port sowie dem Schwellenwert des Vertrauensniveaus für das Software-Debouncing.