Spisu treści:

Generator tonów Arduino bez biblioteki lub funkcji szeregowych (z przerwaniami): 10 kroków
Generator tonów Arduino bez biblioteki lub funkcji szeregowych (z przerwaniami): 10 kroków

Wideo: Generator tonów Arduino bez biblioteki lub funkcji szeregowych (z przerwaniami): 10 kroków

Wideo: Generator tonów Arduino bez biblioteki lub funkcji szeregowych (z przerwaniami): 10 kroków
Wideo: Arduino 36: KARTY PAMIĘCI I ODTWARZANIE DŹWIĘKÓW 2024, Listopad
Anonim
Generator tonów Arduino bez biblioteki lub funkcji szeregowych (z przerwaniami)
Generator tonów Arduino bez biblioteki lub funkcji szeregowych (z przerwaniami)

To nie jest coś, na czym normalnie robiłbym instruktaż, wolę moją metaloplastykę, ale ponieważ jestem studentem elektrotechniki i muszę wziąć udział w zajęciach z mikrokontrolerów (projektowanie systemów wbudowanych), pomyślałem, że zrobię instruktaż na jeden z moich projektów. Kiedy pierwotnie stworzyłem projekt i inne dla tej klasy, odkryłem, że jest bardzo niewiele samouczków, które nie używają funkcji biblioteki arduino lub funkcji szeregowych, co jest kolejnym powodem, dla którego pomyślałem, że byłoby to dobre pouczenie.

Ten kod jest przeznaczony dla mikrokontrolera Atmega 2560, więc jeśli chcesz go zaimplementować na innej płytce, będziesz musiał zmienić rejestry adresowe w kodzie na podstawie instrukcji obsługi twojego kontrolera. Podstawową ideą kodu jest to, że za każdym razem, gdy wprowadzisz klawisz na klawiaturze do monitora szeregowego, arduino mega wygeneruje określoną częstotliwość w zależności od tego, jaki klawisz naciśniesz, z resetowaniem „q”. Zrobiłem to tak, że „a” wyprowadzi częstotliwość A-dur, „A” wyprowadzi częstotliwość krzywą A, „b” wyprowadzi B-dur, „c” dla C-dur, „C” dla C i tak dalej. Pełny kod jest przesyłany na końcu, ale każdy krok rozbija kod na kawałki, dzięki czemu łatwiej go wyjaśnić.

Krok 1: Definiowanie adresów rejestrów

Definiowanie adresów rejestru
Definiowanie adresów rejestru

Ten krok jest prosty, jeśli używasz atmega 2560, wystarczy użyć adresów, których użyłem, chociaż jeśli używasz płyty z innym układem, będziesz musiał znaleźć adresy dla każdego z tych rejestrów na swoim instrukcja obsługi chipów. Definicje na górze to tylko stałe, które będą później używane w naszych funkcjach. Określamy adresy jako volatile unsigned, ponieważ nie chcemy, aby kompilator z nimi zadzierał.

Krok 2: Tablice i zmienne globalne

Tablice i zmienne globalne
Tablice i zmienne globalne
Tablice i zmienne globalne
Tablice i zmienne globalne
Tablice i zmienne globalne
Tablice i zmienne globalne

Tutaj chcemy zdefiniować tablicę częstotliwości, która będzie zawierać wszystkie częstotliwości, które każdy klawisz powinien wyprowadzić. Te wartości są obliczane na podstawie rzeczywistych częstotliwości nut i szczerze mówiąc, zapomniałem, jak je otrzymałem, ale są to prawidłowe wartości, ponieważ testowałem je na oscyloskopie, aby się upewnić. Definiujemy również tablicę nut, która zawiera wszystkie klawisze do naciśnięcia dla każdego tonu, a także zmienne, których będziemy potrzebować do naszych późniejszych funkcji.

Krok 3: Funkcja „serial.begin”

ten
ten

Wywołamy naszą funkcję niestandardową, która replikuje funkcję „serial.begin” U0init(). Pobiera żądaną szybkość transmisji jako dane wejściowe i uruchamia port szeregowy z tą szybkością.

Krok 4: Funkcja „serial.available”

ten
ten

Wywołamy funkcję imitującą "serial.available" U0kbhit(). Nie pobiera danych wejściowych, ale zamiast tego wykrywa zmianę dokonaną na klawiaturze przy użyciu bitu stanu RDA i zwraca wartość true po wykryciu zmiany.

Krok 5: Funkcja „serial.read”

ten
ten

Wywołamy funkcję, która imituje funkcję "serial.read" U0getchar(), która nie pobiera żadnych danych wejściowych i wyprowadza każdą zmianę dokonaną na klawiaturze, która jest przechowywana w rejestrze UDR0.

Krok 6: Funkcja „serial.write”

ten
ten

Wywołamy funkcję, która imituje "serial.write" U0putchar(), która pobiera dane z rejestru UDR0, gdy zmiana jest wykrywana i zapisywana, oraz wyjścia, które zmieniają się z powrotem do monitora szeregowego.

Krok 7: Funkcja konfiguracji

Funkcja konfiguracji
Funkcja konfiguracji

Jest to podstawowa funkcja konfiguracji, która użyje naszej imitacji "serial.begin" do inicjalizacji portu szeregowego i zainicjuje nasze ustawienia bitów dla rejestrów timera i ustawi PB6 na wysyłanie naszych tonów.

Krok 8: Funkcje pętli i ISR

Funkcje pętli i ISR
Funkcje pętli i ISR

Pętla działa w ten sposób: jeśli zmiana zostanie wykryta za pomocą naszej funkcji „serial.available”, nasza funkcja „serial.read” przechowuje tę zmianę, a nasza funkcja „serial.write” umieszcza tę zmianę w monitorze szeregowym. Dopóki zmienna i jest mniejsza niż rozmiar tablicy częstotliwości, ustawi wyjście na pozycję i w tej tablicy, wysyłając częstotliwość w tej pozycji. ISR działa jako reset, gdzie jeśli pozycja tablicy częstotliwości nie jest równa 0 (innymi słowy, jeśli "q" nie jest wciśnięte), wyprowadzi częstotliwość, ale po naciśnięciu "q" zostanie zresetowana. Uwaga: ten kod używa przerwań, ale można to zrobić z przerwaniami wyłączonymi. Opublikuję kod bez przerwań, jeśli otrzymam jakieś prośby, myślę, że wersja z przerwaniami jest fajniejsza.

Krok 9: Okablowanie

Okablowanie
Okablowanie

Okablowanie dla tego kodu jest niezwykle proste, wystarczy podłączyć przewód wyjściowy z PB6 do płytki stykowej, połączyć szeregowo z nim brzęczyk lub głośnik i podłączyć go z powrotem do masy. Uwaga: jeśli używasz głośnika, umieść mały rezystor przed głośnikiem. Jeśli chcesz tylko widzieć wyjście, ale go nie słyszeć, po prostu podłącz PB6 do czerwonego przewodu oscyloskopu, a czarny przewód do masy.

Krok 10: Złóż wszystko razem

Dodałem pełny kod do tego kroku, ponieważ wyjaśniłem wszystkie jego części w poprzednich krokach. Po prostu pobiera wejście klawiatury dla różnych częstotliwości i wysyła tę częstotliwość do PB6. Mam nadzieję, że podobało Ci się czytanie innego sposobu kodowania za pomocą IDE!

Również proszę zagłosuj na to w konkursie Mikrokontroler:D

Zalecana: