Inhaltsverzeichnis:

AVR-Mikrocontroller. Schalten Sie die LEDs mit einem Druckknopfschalter um. Druckknopfentprellung. - Gunook
AVR-Mikrocontroller. Schalten Sie die LEDs mit einem Druckknopfschalter um. Druckknopfentprellung. - Gunook

Video: AVR-Mikrocontroller. Schalten Sie die LEDs mit einem Druckknopfschalter um. Druckknopfentprellung. - Gunook

Video: AVR-Mikrocontroller. Schalten Sie die LEDs mit einem Druckknopfschalter um. Druckknopfentprellung. - Gunook
Video: Arduino Atmel ATmega328 2024, November
Anonim
Image
Image

In diesem Abschnitt erfahren wir, wie Sie den Programm-C-Code für ATMega328PU erstellen, um den Status der drei LEDs entsprechend der Eingabe von einem Tastenschalter umzuschalten. Außerdem haben wir eine Lösung für das Problem von „Switch Bounce“untersucht. Wie üblich bauen wir den Stromkreis auf Basis des AVR ATmega328 zusammen, um die Arbeit des Programmcodes zu überprüfen.

Schritt 1: Schreiben und Erstellen einer AVR-Mikrocontroller-Anwendung in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7

Schreiben und Erstellen von AVR-Mikrocontroller-Anwendungen in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7
Schreiben und Erstellen von AVR-Mikrocontroller-Anwendungen in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7
Schreiben und Erstellen von AVR-Mikrocontroller-Anwendungen in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7
Schreiben und Erstellen von AVR-Mikrocontroller-Anwendungen in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7
Schreiben und Erstellen von AVR-Mikrocontroller-Anwendungen in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7
Schreiben und Erstellen von AVR-Mikrocontroller-Anwendungen in C-Code mit der integrierten Entwicklungsplattform Atmel Studio 7

Wenn Sie Atmel Studio nicht haben, sollten Sie es herunterladen und installieren.

www.microchip.com/mplab/avr-support/atmel-studio-7

Die ersten paar Zeilen haben wir einige Compiler-Definitionen.

F_CPU definiert die Taktfrequenz in Hertz und ist in Programmen üblich, die die avr-libc-Bibliothek verwenden. In diesem Fall wird es von den Verzögerungsroutinen verwendet, um zu bestimmen, wie Zeitverzögerungen berechnet werden.

#ifndef F_CPU

#define F_CPU 16000000UL // Angabe der Quarzfrequenz des Controllers (16 MHz AVR ATMega328P) #endif

#include // Header, um die Datenflusskontrolle über Pins zu ermöglichen. Definiert Pins, Ports usw.

Die erste Include-Datei ist Teil von avr-libc und wird in so ziemlich jedem AVR-Projekt verwendet, an dem Sie arbeiten. io.h ermittelt die von Ihnen verwendete CPU (weshalb Sie den Teil beim Kompilieren angeben) und fügt wiederum den entsprechenden IO-Definitionsheader für den von uns verwendeten Chip hinzu. Es definiert einfach die Konstanten für alle Ihre Pins, Ports, Sonderregister usw.

#include // Header zum Aktivieren der Verzögerungsfunktion im Programm

Die Bibliothek util/delay.h enthält einige Routinen für kurze Verzögerungen. Die Funktion, die wir verwenden werden, ist _delay_ms().

Wir verwenden Defines, um die Ports und Pins unserer Tasten und LEDs zu deklarieren. Wenn wir die defines-Anweisungen wie diese verwenden, müssen wir nur 3 leicht zu findende Zeilen ändern, wenn wir die LED auf einen anderen I / O-Pin verschieben oder einen anderen AVR verwenden.

#define BUTTON1 1 // Tastenschalter an Port B Pin 1 angeschlossen

#define LED1 0 // Led1 verbunden mit Port B Pin 0 #define LED2 1 // Led2 verbunden mit Port C Pin 1 #define LED3 2 // Led3 verbunden mit Port D Pin 2

Die letzten beiden definieren die Setup-Zeiten der Anweisungen in Millisekunden, um den Schalter zu entprellen, und die Zeit, die gewartet wird, bevor ein weiterer Tastendruck zugelassen wird. Die Entprellzeit muss an die Zeit angepasst werden, die der Schalter benötigt, um nach all dem Prellen von einem digitalen High zu einem digitalen Low zu wechseln. Das Bounce-Verhalten ist von Schalter zu Schalter unterschiedlich, aber 20-30 Millisekunden reichen normalerweise völlig aus.

#define DEBOUNCE_TIME 25 // Wartezeit beim "Entprellen"-Button

#define LOCK_INPUT_TIME 300 // Wartezeit nach einem Tastendruck

void init_ports_mcu()

{

Diese Funktion wird nur einmal zu Beginn unseres Programms aufgerufen, um die von uns verwendeten Eingangs-Ausgangs-Pins zu initialisieren.

Für die Schaltfläche verwenden wir die PORT- und PIN-Register zum Schreiben und Lesen. Bei AVRs lesen wir einen Pin mithilfe seines PINx-Registers und schreiben in einen Pin mithilfe seines PORTx-Registers. Wir müssen in das Schaltflächenregister schreiben, um die Klimmzüge zu aktivieren.

Für die LED brauchen wir nur das PORT-Register zum Schreiben zu verwenden, wir benötigen jedoch auch das Datenrichtungsregister (DDR), da die I/O-Pins standardmäßig als Eingänge eingerichtet sind.

Zuerst stellen wir die I / O-Pins der LED mit ihrem Datenrichtungsregister als Ausgang ein.

DDRB=0xFFu; // Setze alle Pins des PORTB als Ausgang.

Als nächstes legen Sie den Button-Pin explizit als Eingang fest.

DDRB &= ~(1<

Als nächstes werden die PORTB-Pins auf hoch (+5 Volt) gesetzt, um sie einzuschalten. Die Ausgangspins sind anfangs hoch, und da unsere LED aktiv-hoch verdrahtet ist, wird sie eingeschaltet, es sei denn, wir schalten sie explizit aus.

Und schließlich aktivieren wir den internen Pull-up-Widerstand am Eingangspin, den wir für unsere Taste verwenden. Dies geschieht einfach durch die Ausgabe einer Eins an den Port. Bei Konfiguration als Eingang führt dies zur Aktivierung von Pull-ups und bei Konfiguration als Ausgang würde dies einfach eine hohe Spannung ausgeben.

PORTB = 0xFF; // Setze alle Pins des PORTB auf HIGH. LED ist eingeschaltet, // auch der interne Pull-Up-Widerstand des ersten Pins PORTB ist aktiviert. DDRC=0xFFu; // Setze alle Pins des PORTC als Ausgang. PORTC=0x00u; // Setzen Sie alle Pins von PORTC auf niedrig, wodurch es ausgeschaltet wird. DDRD=0xFFu; // Setze alle Pins des PORTD als Ausgang. PORTD=0x00u; // Setzen Sie alle Pins von PORTD auf niedrig, wodurch es ausgeschaltet wird. }

unsigniertes Zeichen button_state()

{

Diese Funktion gibt einen booleschen Wert zurück, der angibt, ob die Schaltfläche gedrückt wurde oder nicht. Dies ist der Codeblock, der in der Endlosschleife ständig ausgeführt wird und somit den Zustand der Schaltfläche abfragt. Hier entprellen wir auch den Schalter.

Denken Sie daran, dass beim Drücken des Schalters der Eingangsausgangsstift auf Masse gezogen wird. Wir warten also darauf, dass der Pin niedrig wird.

/* die Taste wird gedrückt, wenn das BUTTON1-Bit gelöscht ist */

if (!(PINB & (1<

Wir tun dies, indem wir prüfen, ob das Bit klar ist. Wenn das Bit gelöscht ist, was anzeigt, dass die Taste gedrückt ist, verzögern wir zuerst die durch DEBOUNCE_TIME definierte Zeit, die 25 ms beträgt, und überprüfen dann den Zustand der Taste erneut. Wenn die Taste nach den 25 ms gedrückt wird, gilt der Schalter als entprellt und bereit, ein Ereignis auszulösen, und wir kehren 1 zu unserer Aufrufroutine zurück. Wenn die Schaltfläche nicht gedrückt wird, geben wir 0 zu unserer Aufrufroutine zurück.

_delay_ms(DEBOUNCE_TIME);

if (!(PINB & (1<

int main (void)

{

Unsere Hauptroutine. Die Hauptfunktion ist einzigartig und hebt sich von allen anderen Funktionen ab. Jedes C-Programm muss genau eine main()-Funktion haben. main ist der Ort, an dem der AVR mit der Ausführung Ihres Codes beginnt, wenn der Strom zum ersten Mal eingeschaltet wird, also der Einstiegspunkt des Programms.

unsigned char n_led = 1; // anfänglich LED-Nummer leuchtet jetzt

Aufruf der Funktion zum Initialisieren der verwendeten I/O-Pins:

init_ports_mcu();

Endlosschleife, in der unser Programm läuft:

während (1)

{

Wenn button_state einen zurückgibt, der anzeigt, dass die Taste gedrückt und entprellt wurde, dann wird der aktuelle Status der LEDs der Reihe nach gemäß dem n_led-Parameter umgeschaltet.

if (button_state()) // Wenn die Taste gedrückt wird, schalten Sie den Status der LED um und verzögern Sie um 300ms (#define LOCK_INPUT_TIME)

{ Schalter (n_led) { Fall 1: PORTB ^= (1<<LED1); PORTC ^= (1<<LED2); brechen;

Diese Anweisungen verwenden bitweise C-Operatoren. Diesmal verwendet es den exklusiven ODER-Operator. Wenn Sie den PORT mit dem Bitwert des Bits, das Sie umschalten möchten, mit einer XOR-Verknüpfung versehen, wird dieses eine Bit geändert, ohne die anderen Bits zu beeinflussen.

Fall 2:

PORTC ^= (1<<LED2); PORTD ^= (1<<LED3); brechen; Fall 3: PORTD ^= (1<<LED3); PORTB ^= (1<<LED1); n_led=0; // LED-Nummernpause zurücksetzen; } n_led++; // nächste LED wird eingeschaltet _delay_ms (LOCK_INPUT_TIME); } } zurück (0); }

Wenn Sie dieses Programm jetzt ausführen, sollten Sie den Druckknopf drücken können, um die LEDs umzuschalten. Aufgrund unserer durch LOCK_INPUT_TIME definierten Verzögerung können Sie die Taste gedrückt halten, wodurch die LEDs mit einer konstanten Geschwindigkeit (etwas mehr als alle 275 ms) aus- und eingeschaltet werden.

Die Programmierung ist abgeschlossen.

Der nächste Schritt besteht darin, das Projekt zu erstellen und die Hex-Datei mit dem avrdude-Programm in den Mikrocontroller zu programmieren.

Sie können die Datei main.c mit dem Programm im C-Code herunterladen:

Schritt 2: Übertragen der HEX-Datei des Programms in den Flash-Speicher des Chips

Übertragen der HEX-Datei des Programms in den Flash-Speicher des Chips
Übertragen der HEX-Datei des Programms in den Flash-Speicher des Chips
Übertragen der HEX-Datei des Programms in den Flash-Speicher des Chips
Übertragen der HEX-Datei des Programms in den Flash-Speicher des Chips

Laden Sie AVRDUDE herunter und installieren Sie es. Die neueste verfügbare Version ist 6.3: Laden Sie die ZIP-Datei herunter

Kopieren Sie zuerst die Hex-Datei des Programms in das AVRDUDE-Verzeichnis. In meinem Fall ist es ButtonAVR.hex

Geben Sie dann im DOS-Eingabeaufforderungsfenster den folgenden Befehl ein: avrdude –c [Name des Programmierers] –p m328p –u –U flash:w:[Name Ihrer Hex-Datei].

In meinem Fall ist es: avrdude –c ISPProgv1 –p m328p –u –U flash:w:ButtonAVR.hex

Dieser Befehl schreibt eine Hex-Datei in den Speicher des Mikrocontrollers.

Sehen Sie sich das Video mit einer detaillierten Beschreibung des Brennens des Mikrocontroller-Flash-Speichers an:

Microcontroller-Flash-Speicher brennt…

Okay! Nun arbeitet der Mikrocontroller gemäß den Anweisungen unseres Programms. Schauen wir es uns an!

Schritt 3: Hardware-Switch-Entprellung

Hardware-Switch-Entprellung
Hardware-Switch-Entprellung

Zusätzlich zur Software-Switch-Entprellung können wir die Hardware-Switch-Entprelltechnik verwenden. Die Grundidee dieser Technik besteht darin, einen Kondensator zu verwenden, um schnelle Änderungen im Schaltsignal herauszufiltern.

Welcher Wert Kondensator sollte gewählt werden? Dies hängt letztendlich davon ab, wie schlecht die Schaltfläche in Bezug auf dieses spezielle Problem abschneidet. Einige Schaltflächen können ein enormes Sprungverhalten aufweisen, andere hingegen nur sehr wenig. Ein niedriger Kondensatorwert wie 1,0 Nanofarad reagiert sehr schnell, mit geringer oder keiner Auswirkung auf das Prellen. Umgekehrt sorgt ein höherer Kondensatorwert wie 220 Nanofarad (der in Bezug auf Kondensatoren immer noch ziemlich klein ist) für einen langsamen Übergang von der Anfangs- zur Endspannung (5 Volt auf 0 Volt). Der Übergang mit einer Kapazität von 220 Nanofarad ist jedoch im realen Sinne immer noch ziemlich schnell und kann daher auf Tasten mit schlechter Leistung verwendet werden.

Schritt 4: Stromkreis

Stromkreis
Stromkreis
Stromkreis
Stromkreis
Stromkreis
Stromkreis

Komponenten gemäß Schaltplan anschließen.

Empfohlen: