Spisu treści:

Samouczek asemblera AVR 7: 12 kroków
Samouczek asemblera AVR 7: 12 kroków

Wideo: Samouczek asemblera AVR 7: 12 kroków

Wideo: Samouczek asemblera AVR 7: 12 kroków
Wideo: Лекция 4. Архитектура AVR. Ассемблер 2024, Lipiec
Anonim
Samouczek asemblera AVR 7
Samouczek asemblera AVR 7

Witamy w samouczku 7!

Dzisiaj najpierw pokażemy, jak oczyścić klawiaturę, a następnie pokażemy, jak używać portów wejścia analogowego do komunikacji z klawiaturą. Zrobimy to za pomocą przerwań i pojedynczego przewodu jako wejścia. Podłączymy klawiaturę tak, aby każde naciśnięcie klawisza wysyłało unikalne napięcie na wejście analogowe, które pozwoli nam odróżnić po napięciu, który klawisz został naciśnięty. Następnie wyślemy numer wciśnięty do naszego analizatora rejestrów, aby pokazać, że wszystko dzieje się tak, jak powinno. Istnieje wiele pułapek, na które można natknąć się podczas korzystania z przetwornika analogowo-cyfrowego (ADC) w ATmega328p, więc będziemy zrób kilka etapów po drodze, aby spróbować i dowiedzieć się, jak ich uniknąć. Zobaczymy również, dlaczego używanie konwertera analogowo-cyfrowego nie jest najlepszym sposobem sterowania klawiaturą, mimo że używa on mniejszej liczby portów w mikrokontrolerze. W tym samouczku będziesz potrzebować:

  1. klawiatura. Możesz go kupić lub zrobić to, co ja, i zgarnąć jednego.
  2. 2 żeńskie nagłówki na klawiaturę (jeśli oczyszczasz jeden)
  3. przewody łączące
  4. deska do krojenia chleba
  5. Rezystory 4 1 Kohm
  6. 1 rezystor 15 Kohm
  7. 1 3.3 Rezystor Kohm
  8. 1 rezystor 180 omów
  9. Rezystor 1 680 omów,
  10. multimetr cyfrowy
  11. Twój analizator z samouczka 5

Możesz pominąć kilka pierwszych kroków, jeśli masz już klawiaturę i nie musisz jej usuwać.

Oto link do pełnej kolekcji moich samouczków asemblera AVR:

Krok 1: Oczyść klawiaturę 1

Oczyść klawiaturę 1
Oczyść klawiaturę 1
Oczyść klawiaturę 1
Oczyść klawiaturę 1
Oczyść klawiaturę 1
Oczyść klawiaturę 1
Oczyść klawiaturę 1
Oczyść klawiaturę 1

Dawno temu, kiedy nawet twoi dziadkowie byli tylko dziećmi, ludzie używali tych dziwnie wyglądających urządzeń, które miały długie kable podłączone do ściany, aby komunikować się ze sobą. Nazywano je „telefonami” i zwykle były to tanie plastikowe przedmioty, które wydawały irytujący dźwięk, gdy ktoś do ciebie dzwonił (nie żeby dzisiejsze dzwonki „Justin Bieber” nie były równie irytujące). W każdym razie urządzenia te miały na sobie klawiatury, które były bardzo proste w okablowaniu, a więc są łatwe do wyczyszczenia i mają na sobie 2 dodatkowe klawisze ("ponowne wybieranie" i "flash") z klawiatur, które możesz kupić, które możesz chcieć zmienić jako „klawisze strzałek”, „klawisze menu” lub coś innego. Zaczniemy więc od usunięcia klawiatury ze starego telefonu. Najpierw weź telefon (ja używam GE, jak pokazano na zdjęciach) i podważ go, aby odsłonić okablowanie. Następnie weź dłuto i odłam małe plastikowe gałki, które trzymają klawiaturę, i wyjmij klawiaturę.

Krok 2: Oczyść klawiaturę 2

Zbierz klawiaturę 2
Zbierz klawiaturę 2
Zbierz klawiaturę 2
Zbierz klawiaturę 2
Zbierz klawiaturę 2
Zbierz klawiaturę 2

Teraz weź piłę do PCV i wytnij plastik wokół dziurek od klucza, a następnie wytnij wokół krawędzi, aby uzyskać odpowiednią głębokość, pozostawiając cienką klawiaturę.

Następnie włóż klawiaturę z powrotem za pomocą małych kołków, które pozostały po odcięciu ich wierzchołków w ostatnim kroku i użyj lutownicy, aby po prostu wsunąć gorące żelazko w każdy otwór kołka, co spowoduje stopienie plastiku i rozłożenie go na spód klawiatury, tworząc nowe „pokrętła”, które utrzymają klawiaturę w miejscu, jak poprzednio.

Lubię wygrzebywać trzy głośniki i może inne rzeczy, takie jak przełączniki i inne rzeczy, które są na płycie. Jednak tym razem nie zamierzam grzebać w przełącznikach i innych rzeczach, ponieważ w tej chwili mamy inne cele. Jest tam również liniowy układ scalony TA31002, który jest dzwonkiem telefonicznym. Arkusz danych można łatwo znaleźć i pobrać online, podając pinout i funkcje. Więc zostawię to na razie przylutowane do płytki, a później się z tym pobawę. Chciałbym go podpiąć do oscyloskopu i zobaczyć jakie fajne sygnały mogę z niego wyciągnąć. Może nawet zrobić z tego dzwonek do drzwi. Kto wie.

W każdym razie, gdy skończysz niszczyć telefon i usuwać części, zakończymy tworzenie naszej klawiatury.

Krok 3: Oczyść klawiaturę 3

Oczyść klawiaturę 3
Oczyść klawiaturę 3
Oczyść klawiaturę 3
Oczyść klawiaturę 3
Oczyść klawiaturę 3
Oczyść klawiaturę 3

Użyj knota do rozlutowywania i usuń kable taśmowe z dolnej części klawiatury, upewniając się, że otwory w płytce drukowanej są czyste, a następnie przymocuj dwa żeńskie nagłówki do płytki, w której znajdują się otwory. Prawdopodobnie będziesz musiał przyciąć swoje nagłówki, aby były to 4-stykowe nagłówki.

Teraz, gdy nagłówki są przymocowane, możesz podłączyć je do płytki stykowej, wziąć multimetr i przetestować klucze, przyklejając multimetr do losowych pinów i mierząc rezystancję. To pozwoli ci zmapować klucze. Trudno jest zobaczyć, jak klucze są podłączone do wyjść patrząc na obwód, ale jeśli używasz multimetru, możesz podłączyć go do dowolnych dwóch pinów, a następnie naciskać przyciski, aż zobaczysz numer na ekranie zamiast otwartego obwodu. To będzie pinout dla tego klucza.

W ten sposób zmapuj wszystkie klawisze na piny wyjściowe.

Krok 4: Podłącz klawiaturę

Podłącz klawiaturę
Podłącz klawiaturę
Podłącz klawiaturę
Podłącz klawiaturę

Teraz postępuj zgodnie ze schematem okablowania i podłącz klawiaturę do płytki stykowej.

Jak to będzie działać, to włożymy 5V z lewej strony, a z prawej strony do GND. Pierwszy pin po prawej na schemacie przechodzi do pierwszego z naszych pinów analogowych w mikrokontrolerze Atmega328p. Gdy nie ma wciśniętych żadnych przycisków, sygnał będzie wynosił 0V, a po naciśnięciu każdego z różnych przycisków wejście do portu analogowego będzie mieściło się w zakresie od 0V do 5V z różną wartością w zależności od tego, który klawisz został naciśnięty. Wybraliśmy wartości rezystorów tak, aby każda ścieżka zawierała rezystancję inną niż reszta. Port analogowy na mikrokontrolerze pobiera sygnał analogowy i dzieli go na 1024 różne kanały od 0V do 5V. Oznacza to, że każdy kanał ma szerokość 5V/1024 = 0,005 V/kanał = 5 mV/kanał. Tak więc port analogowy może rozróżniać napięcia wejściowe, o ile różnią się one o więcej niż 5 mV. W naszym przypadku dobraliśmy wartości rezystorów tak, aby każde dwa naciśnięcia klawiszy wysłały sygnał napięcia różniący się o więcej niż to, aby mikrokontroler mógł łatwo zdecydować, który klawisz został naciśnięty. Dużym problemem jest to, że cały system jest bardzo głośny, więc będziemy musieli wybrać zakres napięć do mapowania dla każdego naciśnięcia przycisku – ale zajmiemy się tym nieco później.

Zauważ, że jesteśmy w stanie sterować 14-przyciskową klawiaturą za pomocą tylko jednej linii wejściowej do kontrolera. To jeden z przydatnych aspektów wejść analogowych.

Teraz nasza pierwsza próba kontrolowania klawiatury będzie polegać na tym, że naciśnięcie klawisza spowoduje przerwanie, podprogram przerwania odczyta port wejścia analogowego i zdecyduje, który klawisz został naciśnięty, a następnie wyśle ten numer do naszego podprogramu analizatora rejestrów, który wyświetli wartość klucza w postaci binarnej na naszych 8 diodach LED, które ustawiliśmy w samouczku 5.

Krok 5: Podłącz klawiaturę do analizatora

Podłącz klawiaturę do analizatora
Podłącz klawiaturę do analizatora
Podłącz klawiaturę do analizatora
Podłącz klawiaturę do analizatora

Zdjęcia pokazują, jak chcemy podłączyć klawiaturę do mikrokontrolera, aby móc zobaczyć wyjście na wyświetlaczu naszego analizatora. Zasadniczo po prostu podłączamy wyjście z klawiatury do styku 0 PortC, który w ATmega328P jest również nazywany ADC0.

Jest jednak kilka dodatkowych rzeczy. Zamierzamy również podłączyć przycisk do PD2. Tj. weź przewód z szyny 5V do przycisku i z drugiej strony przycisku do PD2, a na koniec chcemy odłączyć pin AREF od naszej szyny 5V i zamiast tego pozostawić go odłączony. Jeśli chcielibyśmy, moglibyśmy wstawić kondensator odsprzęgający 0,1 mikrofaradów. To kondensator ceramiczny z napisem 104. Pierwsze dwie cyfry to liczba, a ostatnia to potęga 10 mnożymy ją przez, aby otrzymać odpowiedź w pikofaradach (pico oznacza 10^-12), więc 104 oznacza 10 x 10^4 pikofaradów, czyli to samo co 100 nanofaradów (nano oznacza 10^-9), czyli tyle samo, co 0,1 mikrofaradów (mikro oznacza 10^-6). W każdym razie wszystko to stabilizuje pin AREF, kiedy możemy go użyć jako naszego pinu referencyjnego.

Potrzebujemy również rezystora 1 MΩ między PD2 a masą. Ustawimy PD2 jako pin wyjściowy na 0V i będziemy wyzwalać na dodatnim zboczu tego pinu. Chcemy, aby krawędź zniknęła natychmiast po zwolnieniu przycisku, więc wstawimy ten rezystor „pull down”.

Powodem, dla którego chcemy ten przycisk, jest to, że chcemy wyzwolić nasz konwerter analogowo-cyfrowy z pinu INT0 na chipie, który jest również PD2. W końcu chcielibyśmy, aby naciśnięcie klawisza zarówno wyzwalało ADC, jak i zapewniało konwertowanie sygnału wejściowego bez osobnego przycisku, ale ze względu na sposób działania czasu zaczniemy od osobnego przycisku do wyzwalania ADC i kiedy już wszystko wyprasujemy błędy i jesteśmy pewni, że wszystko działa poprawnie, wtedy zajmiemy się problemami z hałasem i synchronizacją, które pojawiają się przy wyzwalaniu tego samego naciśnięcia przycisku, który chcemy odczytać.

Tak więc na razie działa to tak, że przytrzymamy klawisz, a następnie wciśniemy przycisk, aby wyzwolić ADC, a następnie puścimy i miejmy nadzieję, że wartość binarna naciśniętego przycisku pojawi się w analizatorze.

Napiszmy więc kod, który to zrobi.

Krok 6: Które przełączniki powinniśmy ustawić?

Które przełączniki powinniśmy ustawić?
Które przełączniki powinniśmy ustawić?

Zastanówmy się najpierw, jak to zakodujemy, aby sterownik mógł odczytać dane wejściowe z klawiatury i zamienić je na wartość liczbową odpowiadającą wciśniętemu przyciskowi. Będziemy używać konwertera analogowo-cyfrowego (ADC) który jest wbudowany w Atmega328p. Będziemy używać AREF jako naszego napięcia odniesienia, a nasze wyjście klawiatury zostanie podłączone do PortC0 lub PC0. Zauważ, że ten pin jest również nazywany ADC0 dla konwertera analogowo-cyfrowego 0. Dobrym pomysłem może być przeczytanie sekcji 12.4 o przerwaniach dla ATmega328P, a także rozdziału 24 o konwerterze analogowo-cyfrowym, zanim przejdziemy do zacząć lub przynajmniej mieć te sekcje gotowe do odniesienia. Aby skonfigurować mikrokontroler tak, aby wiedział, co zrobić z analogowym sygnałem wejściowym i jak współdziałać z naszym programem, najpierw musimy ustawić kilka różnych ADC powiązane bity rejestru. Są to zasadniczo odpowiedniki starych przełączników na pierwszych komputerach. Albo włączasz lub wyłączasz przełącznik, albo jeszcze dalej podłączasz kable między jednym gniazdem a drugim, tak aby elektrony docierające do tego rozwidlenia drogi znalazły jedną bramę zamkniętą, a drugą otwartą, zmuszając ją do przejścia inną ścieżką w labiryncie obwody, a tym samym wykonując inne zadanie logiczne. Podczas kodowania w języku asemblerowym mamy bliski dostęp do tych funkcji mikrokontrolera, co jest jedną z atrakcyjnych rzeczy w robieniu tego w pierwszej kolejności. Jest bardziej „za kulisami”, a znacznie mniej dzieje się „za kulisami”. Więc nie myśl o ustawianiu tych rejestrów jako żmudnym zadaniu. To właśnie sprawia, że język asemblera jest interesujący! Zyskujemy bardzo osobistą relację z wewnętrznym działaniem i logiką chipa i sprawiamy, że robi dokładnie to, czego chcemy - ni mniej, ni więcej. Żadnych zmarnowanych cykli zegara. Oto lista przełączników, które musimy ustawić:

  1. Wyłącz bit Power Reduction ADC, PRADC, który jest bitem 0 rejestru PRR, ponieważ jeśli ten bit jest włączony, wyłączy ADC. Rejestr redukcji mocy jest zasadniczo sposobem na odcięcie różnych rzeczy, które zużywają energię, gdy ich nie potrzebujesz. Ponieważ używamy ADC, chcemy się upewnić, że nie jest on wyłączony w ten sposób. (Patrz PRADC na stronie 46)
  2. Wybierz analogowy kanał wejściowy jako ADC0, wyłączając MUX3…0 w rejestrze ADC Multiplexer Selection (ADMUX) (patrz tabela 24-4 na stronie 249), są one domyślnie wyłączone, więc tak naprawdę nie musimy tego robić. Jednak włączam to, ponieważ jeśli kiedykolwiek użyjesz portu innego niż ADC0, będziesz musiał odpowiednio przełączyć te przełączniki. Różne kombinacje MUX3, MUX2, MUX1, MUX0 pozwalają używać dowolnego portu analogowego jako wejścia, a także możesz je zmieniać w locie, jeśli chcesz jednocześnie oglądać kilka różnych sygnałów analogowych.
  3. Wyłącz bity REFS0 i REFS1 w rejestrze ADMUX tak, że będziemy używać AREF jako naszego napięcia odniesienia, a nie wewnętrznego odniesienia (patrz strona 248).
  4. Włącz bit ADLAR w ADMUX, aby wynik był „dopasowany w lewo”, omówimy ten wybór w następnym kroku.
  5. Ustaw bit ADC0D w rejestrze dezaktywacji wejścia cyfrowego (DIDR0), aby wyłączyć wejście cyfrowe na PC0. Używamy tego portu jako wejścia analogowego, więc równie dobrze możemy wyłączyć dla niego wejście cyfrowe.
  6. Ustaw ISC0 i ISC1 w zewnętrznym rejestrze kontroli przerwań A (EICRA), aby wskazać, że chcemy wyzwalać na zboczu narastającym sygnału napięciowego na styku INT0 (PD2), patrz strona 71.
  7. Wyczyść bity INT0 i INT1 w rejestrze zewnętrznej maski przerwań (EIMSK), aby wskazać, że nie używamy przerwań na tym pinie. Gdybyśmy mieli włączyć przerwania na tym pinie, potrzebowalibyśmy obsługi przerwań pod adresem 0x0002, ale zamiast tego konfigurujemy go tak, aby sygnał na tym pinie wyzwalał konwersję ADC, której zakończenie jest obsługiwane przez pełne przerwanie konwersji ADC o adres 0x002A. Patrz strona 72.
  8. Ustaw bit ADC Enable (ADEN) (bit 7) w ADC Control and Status Register A (ADCSRA), aby włączyć ADC. Patrz strona 249.
  9. Moglibyśmy rozpocząć pojedynczą konwersję, ustawiając bit rozpoczęcia konwersji ADC (ADSC) za każdym razem, gdy chcieliśmy odczytać sygnał analogowy, jednak na razie wolelibyśmy, aby był odczytywany automatycznie za każdym razem, gdy ktoś naciśnie przycisk, więc zamiast tego włączymy ADC Bit automatycznego wyzwalania (ADATE) w rejestrze ADCSRA, dzięki czemu wyzwalanie jest wykonywane automatycznie.
  10. Ustawiliśmy również bity ADPS2..0 (bity preskalarne AD) na 111, aby zegar ADC był zegarem procesora podzielonym przez współczynnik 128.
  11. Jako źródło wyzwalania ADC wybierzemy PD2, który jest również nazywany INT0 (External Interrupt Request 0). Robimy to, przełączając różne bity w rejestrze ADCSRB (patrz Tabela 24-6 na stronie 251). Widzimy w tabeli, że chcemy, aby ADTS0 było wyłączone, ADTS1 włączone i ADTS2 wyłączone, aby ADC wyzwolił ten pin. Zwróć uwagę, że jeśli chcielibyśmy stale próbkować port analogowy, tak jak gdybyśmy odczytywali ciągły sygnał analogowy (np. Próbkowanie dźwięku lub coś takiego), ustawilibyśmy to w trybie Free Running Mode. Stosowana przez nas metoda ustawiania wyzwalania na PD2 wyzwala odczyt ADC portu analogowego PC0 bez powodowania przerwania. Przerwanie nastąpi po zakończeniu konwersji.
  12. Włącz bit ADC Interrupt Enable (ADIE) w rejestrze ADCSRA, aby po zakończeniu konwersji analogowo-cyfrowej wygenerował przerwanie, dla którego możemy napisać obsługę przerwań i umieścić w.org 0x002A.
  13. Ustaw bit I w SREG, aby włączyć przerwania.

Ćwiczenie 1: Upewnij się, że przeczytałeś odpowiednie sekcje w arkuszu danych dla każdego z powyższych ustawień, aby zrozumieć, co się dzieje i co by się stało, gdybyśmy zmienili je na alternatywne ustawienia.

Krok 7: Napisz procedurę obsługi przerwań

W ostatnim kroku widzieliśmy, że ustawiliśmy to tak, aby zbocze narastające wykryte na PD2 wyzwoliło konwersję analogowo-cyfrową na PC0, a kiedy ta konwersja zostanie zakończona, wygeneruje przerwanie ADC Conversion Complete. Teraz chcemy coś zrobić z tym przerwaniem. Jeśli przejrzysz Tabelę 12-6 na stronie 65, zobaczysz listę możliwych przerwań. Widzieliśmy już przerwanie RESET pod adresem 0x0000 i przerwanie Timer/Counter0 Overflow pod adresem 0x0020 w poprzednich samouczkach. Teraz chcemy spojrzeć na przerwanie ADC, które widzimy w tabeli pod adresem 0x002A. Tak więc na początku naszego kodu języka asemblerowego będziemy potrzebować linii, która brzmi:

.org 0x002Arjmp ADC_int

który przeskoczy do naszego programu obsługi przerwań oznaczonego ADC_int za każdym razem, gdy ADC zakończy konwersję. Jak więc napisać nasz program obsługi przerwań? Sposób działania ADC polega na wykonaniu następujących obliczeń:

ADC = Vin x 1024 / Vref

Zobaczmy więc, co się stanie, jeśli nacisnę przycisk „ponownego wybierania” na klawiaturze. W takim przypadku napięcie na PC0 zmieni się na pewną wartość, powiedzmy 1,52 V, a ponieważ Vref wynosi 5 V, będziemy mieli:

ADC = (1,52 V) x 1024 / 5 V = 311.296

więc pojawi się jako 311. Gdybyśmy chcieli przekonwertować to z powrotem na napięcie, po prostu odwrócilibyśmy obliczenia. Nie będziemy jednak musieli tego robić, ponieważ nie jesteśmy zainteresowani rzeczywistymi napięciami tylko w celu ich rozróżnienia. Po zakończeniu konwersji wynik jest zapisywany w 10-bitowej liczbie umieszczonej w rejestrach ADCH i ADCL i spowodowaliśmy, że został on „dopasowany w lewo”, co oznacza, że 10-bity zaczynają się od bitu 7 ADCH i schodzą do bit 6 ADCL (w tych dwóch rejestrach jest łącznie 16 bitów, a my używamy tylko 10 z nich, czyli 1024 kanały). Moglibyśmy mieć wynik „prawo wyrównany”, jeśli chcielibyśmy, usuwając bit ADLAR w rejestrze ADMUX. Powodem, dla którego wybraliśmy wyrównanie lewostronne, jest to, że nasze sygnały są wystarczająco daleko od siebie, że ostatnie dwie cyfry numeru kanału nie są istotne i są prawdopodobnie tylko szumem, więc rozróżnimy naciśnięcia klawiszy używając tylko górnych 8 cyfr, innymi słowy, będziemy musieli tylko spojrzeć na ADCH, aby dowiedzieć się, który przycisk został naciśnięty. Więc nasz program obsługi przerwań powinien po prostu odczytać liczbę z ADCH rejestru, przekonwertuj tę liczbę na wartość z klawiatury, a następnie wyślij tę wartość do naszych diod LED analizatora rejestrów, abyśmy mogli sprawdzić, czy naciśnięcie „9” spowoduje zaświecenie diody odpowiadającej „00001001”. jednak musimy najpierw zobaczyć, co pojawia się w ADCH, gdy naciskamy różne przyciski. Napiszmy więc prosty program obsługi przerwań, który po prostu wysyła zawartość ADCH do wyświetlacza analizatora. Oto czego potrzebujemy:

ADC_int: analizator lds, ADCH;załaduj wartość ADCH do naszych analizatorówbi EIFR, 0; wyczyść flagę przerwania zewnętrznego, aby była gotowa do ponownego uruchomienia reti

Do tej pory powinieneś być w stanie po prostu skopiować kod z naszego analizatora w samouczku 5 i dodać to przerwanie oraz ustawienia przełączania i uruchomić je. Ćwiczenie 2: Napisz kod i uruchom go. Zobacz, że na wyświetlaczu analizatora wyświetlany jest ADCH. Spróbuj kilkakrotnie nacisnąć to samo naciśnięcie klawisza. Czy zawsze otrzymujesz tę samą wartość w ADCH?

Krok 8: Mapuj wartości naciśnięć klawiszy

Mapuj wartości naciśnięć klawiszy
Mapuj wartości naciśnięć klawiszy

Teraz musimy przekonwertować wartości w ADCH na liczby odpowiadające wciśniętemu klawiszowi. Robimy to, wypisując zawartość ADCH dla każdego naciśnięcia klawisza, a następnie konwertując ją na liczbę dziesiętną, tak jak to zrobiłem na obrazku. W naszej procedurze obsługi przerwań rozważymy cały zakres wartości jako odpowiadający każdemu naciśnięciu klawisza, tak aby ADC mapował wszystko w tym zakresie do danego naciśnięcia klawisza.

Ćwiczenie 3: Zrób to mappng, a następnie napisz ponownie procedurę przerwania ADC.

Oto, co dostałem za moje (twój najprawdopodobniej będzie inny). Zauważ, że ustawiłem to z zakresem wartości dla każdego naciśnięcia klawisza.

ADC_int:; Analizator obsługi przerwań zewnętrznych; przygotuj się na nowe numery przycisk H, ADCH; ADC aktualizuje się po odczytaniu ADCH clccpi buttonH, 240brlo PC+3; jeśli ADCH jest większy, to jest to analizator 1ldi, 1; więc analizator obciążenia z powrotem 1rjmp; i powróć przycisk clccpi H, 230; jeśli ADCH jest większy niż 2brlo PC+3ldi analizator, 2rjmp powrót clccpi buttonH, 217brlo PC+3ldi analizator, 3rjmp powrót clccpi buttonH, 203brlo PC+3ldi analizator, 4rjmp powrót clccpi buttonH, 187brlo PC+3ldi analizator, 5ccpi buttonH powrót, 155brlo PC+analizator 3ldi, 6rjmp powrót clccpi buttonH, 127brlo PC+analizator 3ldi, 255; ustawimy flash jako wszystkie onrjmp powrót clccpi buttonH, 115brlo PC+3ldi analizator, 7rjmp powrót clccpi buttonH, 94brlo PC+3ldi analizator, 8rjmp powrót clccpi buttonH, 62brlo PC+3ldi analizator, 9rjmp powrót clccpi buttonH, 37brlo PC+3ldi analizator 0b11110000; gwiazdka to górna połowa włrjmp powrót clccpi buttonH, 28brlo PC+3ldi analizator, 0rjmp powrót clccpi buttonH, 17brlo PC+3ldi analizator, 0b00001111; znak hash to dolna połowa onrjmp return clccpi buttonH, 5brlo PC+3ldi analizator, 0b11000011; ponowne wybieranie jest góra 2 dół 2rjmp return analizator ldi, 0b11011011; w przeciwnym razie wystąpił błąd return:reti

Krok 9: Kod i wideo dla wersji 1

Załączam kod do tej pierwszej wersji sterownika klawiatury. W tym przypadku należy nacisnąć klawisz, a następnie nacisnąć przycisk, aby ADC odczytał wejście z klawiatury. To, co wolelibyśmy, to brak przycisku, ale sygnał do wykonania konwersji pochodzi z samego naciśnięcia klawisza. Ćwiczenie 3: Złóż, prześlij ten kod i wypróbuj go. Być może będziesz musiał zmienić różne progi konwersji, aby odpowiadały napięciu naciśnięć klawiszy, ponieważ prawdopodobnie różnią się one od moich. Co się stanie, jeśli spróbujesz użyć wejścia z klawiatury zarówno dla ADC0, jak i dla zewnętrznego pinu przerwań zamiast przez przycisk? Dołączę również wideo z działania tej pierwszej wersji naszego sterownika naciśnięć klawiszy. Zauważysz, że w moim kodzie znajduje się sekcja inicjująca wskaźnik stosu. Istnieją różne rejestry, które możemy chcieć wypchnąć i zdjąć ze stosu, gdy manipulujemy zmiennymi i czym nie, a są też rejestry, które możemy chcieć zapisać i przywrócić później. Na przykład SREG jest rejestrem, który nie jest zachowywany przez przerwania, więc różne flagi, które są ustawiane i usuwane w wyniku operacji, mogą zostać zmienione, jeśli przerwanie wystąpi w środku czegoś. Więc najlepiej jest, jeśli wepchniesz SREG na stos na początku obsługi przerwań, a następnie zdejmiesz go ponownie na końcu procedury obsługi przerwań. Umieściłem go w kodzie, aby pokazać, jak jest zainicjowany i przewidzieć, jak będziemy go później potrzebować, ale ponieważ nie obchodzi nas, co dzieje się z SREG podczas przerwań w naszym kodzie, nie użyłem do tego stosu. że użyłem operacji przesunięcia do ustawienia różnych bitów w rejestrach podczas inicjalizacji. Na przykład w linii:

ldi temp, (1<> st. EICRA, temp

Polecenie "<<" w pierwszym wierszu powyższego kodu jest operacją przesunięcia. Zasadniczo przyjmuje liczbę binarną 1, czyli 0b00000001 i przesuwa ją w lewo o liczbę ISC01. Jest to pozycja bitu o nazwie ISC01 w rejestrze EICRA. Ponieważ ISC01 jest bitem 1, liczba 1 jest przesuwana na lewą 1 pozycję, aby uzyskać wartość 0b00000010. Podobnie drugi, ISC00, jest bitem 0 EICRA, a więc przesunięcie liczby 1 wynosi zero pozycji w lewo. Jeśli spojrzysz ponownie na plik m328Pdef.inc, który pobrałeś w pierwszym samouczku i od tego czasu używasz evrr, zobaczysz, że jest to tylko długa lista instrukcji ".equ". Przekonasz się, że ISC01 jest równe 1. Asembler zastępuje każdą jego instancję wartością 1, zanim zacznie cokolwiek asemblować. Są to tylko nazwy bitów rejestru, które pomagają nam, ludziom, czytać i pisać kod. Teraz pionowa linia między dwoma powyższymi operacjami przesunięcia jest logiczną operacją „lub”. Oto równanie:

0b0000010 | 0b00000001 = 0b00000011

i to właśnie ładujemy (używając "ldi") do temp. Powodem, dla którego ludzie używają tej metody do ładowania wartości do rejestru, jest to, że pozwala ona na użycie nazwy bitu zamiast tylko liczby, a to sprawia, że kod jest znacznie łatwiejszy do odczytania. Istnieją również dwie inne techniki, których używaliśmy. Używamy instrukcji „ori” i „andi”. Pozwalają nam one odpowiednio ustawiać i usuwać bity bez zmiany innych bitów w rejestrze. Na przykład, kiedy używałem

temperatura ori, (1

to „lub” temp z 0b0000001, które umieszcza 1 w zerowym bicie i pozostawia całą resztę bez zmian. Również kiedy pisaliśmy

Andi temp, 0b11111110

to zmienia zerowy bit temp na 0 i pozostawia całą resztę bez zmian.

Ćwiczenie 4: Powinieneś przejść przez kod i upewnić się, że rozumiesz każdy wiersz. Może zainteresować Cię znalezienie lepszych metod robienia rzeczy i napisanie lepszego programu. Istnieje sto sposobów kodowania rzeczy i jestem przekonany, że można znaleźć o wiele lepszy sposób niż mój. Możesz także znaleźć (nie daj Boże!) błędy i pominięcia. W takim razie na pewno chciałbym o nich usłyszeć, aby można je było naprawić.

Dobra, teraz zobaczmy, czy możemy pozbyć się tego zbędnego przycisku…

Krok 10: Kod dla wersji 2

Najprostszym sposobem na pozbycie się przycisku jest po prostu jego całkowite usunięcie, zapomnienie wejścia do PB2 i po prostu przełączenie ADC w tryb „Free Running Mode”.

Innymi słowy, po prostu zmień rejestr ADCSRB tak, aby ADTS2, ADTS1 i ADTS0 były zerami.

Następnie ustaw bit ADSC w ADCSRA na 1, co rozpocznie pierwszą konwersję.

Teraz wgraj go do swojego mikrokontrolera, a zobaczysz, że właściwy numer pojawia się na wyświetlaczu podczas naciskania przycisku i tylko podczas naciskania przycisku. Dzieje się tak, ponieważ ADC stale próbkuje port ADC0 i wyświetla wartość. Kiedy zdejmiesz palec z przycisku, "odbicie przycisku" spowoduje bardzo szybkie pojawienie się kilku losowych wartości, a następnie powrót do wejścia 0V. W naszym kodzie mamy to 0V pojawiające się jako 0b11011011 (ponieważ naciśnięcie klawisza `0' już używa wyświetlanej wartości 0b00000000)

Nie jest to rozwiązanie, którego chcemy z dwóch powodów. Po pierwsze nie chcemy przytrzymywać przycisku. Chcemy nacisnąć go raz i wyświetlić numer (lub użyć go w jakimś nowym kodzie w późniejszym samouczku). Po drugie, nie chcemy ciągle próbkować ADC0. Chcemy, aby wykonał pojedynczy odczyt, przekonwertował go, a następnie uśpił, aż nowe naciśnięcie klawisza wywoła nową konwersję. Tryb swobodnej pracy jest najlepszy, jeśli jedyną rzeczą, którą chcesz, aby mikrokontroler robił, jest ciągłe odczytywanie niektórych wejść analogowych - na przykład, gdybyś chciał wyświetlać temperatury w czasie rzeczywistym lub coś takiego.

Znajdźmy więc jeszcze inne rozwiązanie…

Krok 11: Jak pozbyć się przycisku? Wersja 3

Jak pozbyć się przycisku? Wersja 3
Jak pozbyć się przycisku? Wersja 3

Możemy postąpić na wiele sposobów. Najpierw możemy dodać sprzęt, aby pozbyć się przycisku. Na przykład możemy spróbować umieścić tranzystor w obwodzie na linii wyjściowej naciśnięcia klawisza, aby pobierał niewielką strużkę prądu z wyjścia i wysyłał impuls 5 V do styku przerwania PD2.

Jednak prawdopodobnie byłoby to co najmniej zbyt hałaśliwe, a w najgorszym nie zapewniłoby wystarczająco dużo czasu na dokładny odczyt naciśnięcia klawisza, ponieważ napięcie wyjściowe klawiatury nie miałoby czasu na ustabilizowanie się przed przechwyceniem odczytu ADC.

Więc wolelibyśmy wymyślić rozwiązanie programowe. To, co chcielibyśmy zrobić, to dodać przerwanie na pinie PD2 i napisać dla niego procedurę obsługi przerwań, która wywołuje pojedynczy odczyt pinu klawiatury. Innymi słowy, pozbywamy się przerwania automatycznego wyzwalania z ADC i dodajemy zewnętrzne przerwanie, które wywołuje ADC wewnątrz niego. W ten sposób sygnał do odczytu ADC pojawia się po tym, jak sygnał PD2 już wystąpił, co może dać wystarczająco dużo czasu na ustabilizowanie się do dokładnego napięcia, zanim pin PC0 zostanie odczytany i przekonwertowany. Nadal mielibyśmy przerwanie zakończenia ADC, które wyświetla wynik na wyświetlaczu analizatora na końcu.

Ma sens? Cóż, zróbmy to…

Spójrz na załączony nowy kod.

Widzisz następujące zmiany:

  1. Dodaliśmy rjmp pod adresem.org 0x0002 do obsługi zewnętrznego przerwania INT0
  2. Zmieniliśmy rejestr EIMSK, aby wskazać, że chcemy przerwać na pinie INT0
  3. Zmieniliśmy pin ADATE w rejestrze ADCSRA, aby wyłączyć automatyczne wyzwalanie
  4. Pozbyliśmy się ustawień ADCSRB, ponieważ są one nieistotne, gdy funkcja ADATE jest wyłączona
  5. Nie musimy już resetować flagi wyzwalacza zewnętrznego, ponieważ procedura przerwania INT0 robi to automatycznie po zakończeniu -- wcześniej nie mieliśmy procedury przerwania, po prostu wyzwoliliśmy ADC z sygnału na tym styku, więc musieliśmy wyczyść tę flagę ręcznie.

Teraz w obsłudze przerwań po prostu wywołujemy pojedynczą konwersję z ADC.

Ćwiczenie 5: Uruchom tę wersję i zobacz, co się stanie.

Krok 12: Kod i wideo dla wersji roboczej

Jak widzieliśmy w ostatniej wersji, przerwanie przycisku nie działa zbyt dobrze, ponieważ przerwanie jest wyzwalane na zboczu narastającym, aby przypiąć PD2, a następnie obsługa przerwań wywołuje konwersję ADC. Jednak ADC otrzymuje odczyt napięcia, zanim się ustabilizuje, więc odczytuje bzdury.

To, czego potrzebujemy, to wprowadzenie opóźnienia między przerwaniem na PD2 a odczytem ADC na PC0. Zrobimy to przez dodanie timera/licznika, przerwania przepełnienia licznika i procedury opóźnienia. Na szczęście wiemy już, jak to zrobić z samouczka 3! Więc po prostu skopiujemy i wkleimy odpowiedni kod stamtąd.

Podałem otrzymany kod i film pokazujący go w działaniu.

Zauważysz, że odczyty nie są tak dokładne, jak można by się spodziewać. Jest to prawdopodobnie spowodowane kilkoma źródłami:

  1. stukamy z napięcia wyjściowego klawiatury, aby wyzwolić PD2, co wpływa na odczyt w PC0.
  2. tak naprawdę nie wiemy, jak długo czekać po spuście, aby uzyskać najlepszy odczyt.
  3. ukończenie konwersji ADC zajmuje kilka cykli, co oznacza, że nie możemy szybko odpalić klawiatury.
  4. prawdopodobnie jest szum w samej klawiaturze.
  5. itp…

Tak więc, chociaż udało nam się uruchomić klawiaturę i możemy teraz używać jej w aplikacjach, używając wartości naciśnięć klawiszy w inny sposób, zamiast po prostu wyprowadzać je na wyświetlacz analizatora, nie jest to zbyt dokładne i jest bardzo denerwujące. Dlatego uważam, że najlepszym sposobem na okablowanie klawiatur jest po prostu włożenie każdego wyjścia z klawiatury do innego portu i decydowanie, który klawisz jest wciskany przez które porty widzą napięcie. To jest łatwe, bardzo szybkie i bardzo dokładne.

W rzeczywistości są tylko dwa powody, dla których ktoś chciałby sterować klawiaturą tak, jak to zrobiliśmy tutaj:

  1. Używa tylko 2 pinów na naszym mikrokontrolerze zamiast 8.
  2. To świetny projekt, aby pokazać różne aspekty ADC na mikrokontrolerze, który różni się od standardowych rzeczy, które można tam znaleźć, takich jak odczyty temperatury, obracanie potencjometrów itp. Chciałem przykładu wyzwalanych pojedynczych odczytów i automatycznego wyzwalania zewnętrznego pinu a nie tylko wolny tryb pożerania procesora.

W każdym razie, oto kilka ostatnich ćwiczeń dla Ciebie:

Ćwiczenie 6: Przepisz procedurę obsługi przerwań konwersji ADC, aby używała tabeli przeglądowej. Tj. Aby przetestować wartość analogową z pierwszą pozycją w tabeli i jeśli jest większa, wraca z przerwania, jeśli nie, to inkrementuje Z do następnego elementu w tabeli i ponownie rozgałęzia się do testu. To skróci kod i wyczyści procedurę przerwań i sprawi, że będzie wyglądał ładniej. (W następnym kroku podam możliwe rozwiązanie) Ćwiczenie 7: Podłącz klawiaturę do 8 pinów mikrokontrolera i napisz do niego prosty sterownik i przekonaj się, o ile jest ładniejszy. Czy możesz wymyślić kilka sposobów na ulepszenie naszej metody?

To wszystko w tym samouczku. Załączam ostateczną wersję ze wskazówkami. Gdy zbliżamy się do naszego ostatecznego celu, ponownie użyjemy klawiatury w samouczku 9, aby pokazać, jak sterować za jej pomocą wyświetlaczy siedmiosegmentowych (i zbudować coś ciekawego, co wykorzystuje dodatkowe klawisze na klawiaturze telefonu), a następnie zamiast tego przełącz się na kontrolowanie rzeczy za pomocą naciśnięć przycisków (ponieważ ta metoda lepiej pasuje do produktu końcowego, do którego dążymy za pomocą tych samouczków), a my po prostu odłożymy klawiaturę na półkę.

Do zobaczenia następnym razem!

Zalecana: