Inhaltsverzeichnis:

Arduino Tongenerator ohne Bibliothek oder serielle Funktionen (mit Interrupts) - Gunook
Arduino Tongenerator ohne Bibliothek oder serielle Funktionen (mit Interrupts) - Gunook

Video: Arduino Tongenerator ohne Bibliothek oder serielle Funktionen (mit Interrupts) - Gunook

Video: Arduino Tongenerator ohne Bibliothek oder serielle Funktionen (mit Interrupts) - Gunook
Video: #9 AD9833 DDS & Arduino Frequenzgenerator für Sinus, Dreieck und Rechteck. 2024, Dezember
Anonim
Arduino-Tongenerator ohne Bibliothek oder serielle Funktionen (mit Interrupts)
Arduino-Tongenerator ohne Bibliothek oder serielle Funktionen (mit Interrupts)

Dies ist nicht etwas, was ich normalerweise anweisbar machen würde, ich bevorzuge meine Metallarbeiten, aber da ich ein Student der Elektrotechnik bin und eine Klasse über Mikrocontroller (Embedded Systems Design) belegen muss, dachte ich, ich würde ein anweisbares machen eines meiner Projekte. Als ich ursprünglich das Projekt und andere für diese Klasse erstellte, stellte ich fest, dass es nur sehr wenige bis keine Tutorials gibt, die die Arduino-Bibliotheksfunktionen oder seriellen Funktionen nicht verwenden, was ein weiterer Grund ist, warum ich dachte, dies wäre eine gute Anleitung.

Dieser Code ist für den Atmega 2560-Mikrocontroller konzipiert. Wenn Sie ihn also auf einem anderen Board implementieren möchten, müssen Sie die Adressregister im Code basierend auf dem Benutzerhandbuch Ihres Controllers ändern. Die Grundidee hinter dem Code ist, dass das Arduino Mega jedes Mal, wenn Sie eine Taste auf der Tastatur in den seriellen Monitor eingeben, eine bestimmte Frequenz ausgibt, basierend auf der von Ihnen gedrückten Taste, wobei "q" sie zurücksetzt. Ich habe es so gemacht, dass "a" die A-Frequenz ausgibt und "A" die A-Frequenz ausgibt, "b" B-Dur ausgibt, "c" für C-Dur, "C" für Cis und so weiter. Der vollständige Code wird am Ende hochgeladen, aber jeder Schritt wird den Code in Teile zerlegen, damit er leichter erklärt werden kann.

Schritt 1: Definieren von Registeradressen

Definieren von Registeradressen
Definieren von Registeradressen

Dieser Schritt ist einfach, wenn Sie den atmega 2560 verwenden, müssen Sie nur die Adressen verwenden, die ich verwendet habe. Wenn Sie jedoch ein Board mit einem anderen Chip verwenden, müssen Sie die Adressen für jedes dieser Register auf Ihrem finden Bedienungsanleitung der Chips. Die Definitionen oben sind nur Konstanten, die später für unsere Funktionen verwendet werden. Wir geben die Adressen als volatile unsigned an, weil wir nicht wollen, dass der Compiler mit ihnen herumspielt.

Schritt 2: Arrays und globale Variablen

Arrays und globale Variablen
Arrays und globale Variablen
Arrays und globale Variablen
Arrays und globale Variablen
Arrays und globale Variablen
Arrays und globale Variablen

Hier wollen wir das Frequenz-Array definieren, das alle Frequenzen enthält, die jede Taste ausgeben soll. Diese Werte werden aus den tatsächlichen Notenfrequenzen berechnet, und ehrlich gesagt habe ich vergessen, wie ich sie bekommen habe, aber es sind die richtigen Werte, da ich sie auf einem Oszilloskop getestet habe, um sicherzugehen. Wir definieren auch das Noten-Array, das alle Tasten enthält, die für jeden Ton zu drücken sind, sowie die Variablen, die wir für unsere späteren Funktionen benötigen.

Schritt 3: Die "serial.begin" Funktion

Die
Die

Wir rufen unsere benutzerdefinierte Funktion auf, die die Funktion "serial.begin" U0init() repliziert. Es nimmt die gewünschte Baudrate als Eingabe und startet den seriellen Port mit dieser Baudrate.

Schritt 4: Die Funktion "serial.available"

Die
Die

Wir rufen die Funktion, die "serial.available" imitiert, U0kbhit() auf. Es nimmt keine Eingaben entgegen, sondern erkennt mithilfe des RDA-Statusbits, ob eine Änderung an der Tastatur vorgenommen wurde, und gibt true zurück, wenn eine Änderung erkannt wird.

Schritt 5: Die Funktion "serial.read"

Die
Die

Wir nennen die Funktion, die die Funktion "serial.read" imitiert, U0getchar(), die keine Eingaben entgegennimmt und alle Änderungen ausgibt, die auf der Tastatur vorgenommen werden, die im UDR0-Register gespeichert sind.

Schritt 6: Die Funktion "serial.write"

Die
Die

Wir rufen die Funktion, die "serial.write" imitiert, U0putchar() auf, die die Daten aus dem UDR0-Register nimmt, während eine Änderung erkannt und gespeichert wird, und diese Änderung an den seriellen Monitor zurückgibt.

Schritt 7: Die Setup-Funktion

Die Setup-Funktion
Die Setup-Funktion

Dies ist die grundlegende Setup-Funktion, die unsere "serial.begin"-Imitation verwendet, um den seriellen Port zu initialisieren und unsere Biteinstellungen für die Timer-Register zu initialisieren und PB6 so einzustellen, dass unsere Töne ausgegeben werden.

Schritt 8: Die Loop- und ISR-Funktionen

Die Loop- und ISR-Funktionen
Die Loop- und ISR-Funktionen

Die Schleife funktioniert so: Wenn mit unserer Funktion "serial.available" eine Änderung erkannt wird, speichert unsere Funktion "serial.read" diese Änderung und unsere Funktion "serial.write" überträgt diese Änderung in den seriellen Monitor. Solange eine Variable i kleiner als die Größe des Frequenzarrays ist, wird die Ausgabe auf die Position von i in diesem Array gesetzt und die Frequenz an dieser Position ausgegeben. Der ISR fungiert als Reset, wobei, wenn die Position des Frequenz-Arrays ungleich 0 ist (dh wenn "q" nicht gedrückt wird), die Frequenz ausgegeben wird, aber wenn "q" gedrückt wird, wird es zurückgesetzt. Bitte beachten Sie: Dieser Code verwendet Interrupts, kann aber auch mit deaktivierten Interrupts ausgeführt werden. Ich werde den Code ohne Unterbrechungen posten, wenn ich Anfragen dazu bekomme, ich denke nur, dass die Unterbrechungsversion mehr Spaß macht.

Schritt 9: Verkabelung

Verdrahtung
Verdrahtung

Die Verkabelung für diesen Code ist extrem einfach, einfach ein Ausgangskabel von PB6 auf ein Steckbrett legen, einen Summer oder Lautsprecher damit in Reihe schalten und wieder mit Masse verbinden. Hinweis: Wenn Sie einen Lautsprecher verwenden, fügen Sie einen kleinen Widerstand vor den Lautsprecher ein. Wenn Sie den Ausgang nur sehen, aber nicht hören möchten, verbinden Sie PB6 einfach mit dem roten Kabel eines Oszilloskops und das schwarze Kabel mit Masse.

Schritt 10: Alles zusammenfügen

Ich habe diesem Schritt den vollständigen Code hinzugefügt, da ich alle Teile davon in den vorherigen Schritten erklärt habe. Es dauert nur eine Tastatureingabe für verschiedene Frequenzen und gibt diese Frequenz an PB6 aus. Ich hoffe, es hat Ihnen Spaß gemacht, eine andere Art des Programmierens mit der IDE zu lesen!

Bitte stimmen Sie auch dafür im Mikrocontroller-Wettbewerb ab:D

Empfohlen: