Zakres laboratorium:
- Program testowy
- Wykorzystanie przerwań wewnętrznych – praca z dokumentacją mikrokontrolera – dokumentacja
- Przerwania zewnętrzne – obsługa przycisków
- Konfiguracja układu licznikowego do pracy z zadanymi parametrami
- Obsługa wyświetlacza 7-segmentowego na przerwaniach
- Obsługa enkodera mechanicznego – impulsator
1. Program testowy
- podłączyć diody do pinów PD0 i PD1 i skonfigurować odpowiednie piny
- napisać program, który będzie migał diodą PD0 z częstotliwością 1Hz
- program w pętli while powinien zajmować tylko dwie linijki -> dwie komendy
- przemyśleć jak napisać program, który będzie migał diodą na pinie PD1 z częstotliwością 2Hz (tylko przemyśleć)
2. Przerwania wewnętrzne od licznika – konfiguracja
- podłączyć diody do pinów PD0 i PD1 i skonfigurować odpowiednie piny
- wgrać do środowiska programistycznego poniższy kod programu
- uzupełnić fragmenty aby uruchomić przerwanie na liczniku Timer1 działające z częstotliwością 2Hz
- uzupełnić przerwanie o komendę migania diodą na porcie PD1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
#include <avr/io.h> #include <stdlib.h> #include <string.h> #include <util/delay.h> #ifndef _BV #define _BV(bit) (1<<(bit)) #endif #ifndef sbi #define sbi(reg,bit) reg |= (_BV(bit)) #endif #ifndef cbi #define cbi(reg,bit) reg &= ~(_BV(bit)) #endif #ifndef tbi #define tbi(reg,bit) reg ^= (_BV(bit)) #endif void timerInit() { //Wybranie trybu pracy CTC z TOP OCR1A //Wybranie dzielnika czestotliwosci - częstotliwość Atmega328: 16 MHz //Zapisanie do OCR1A wartosci odpowiadajacej 0,5s //Uruchomienie przerwania OCIE1A } //volatile -informacja dla kompilatora aby nie optymalizował zmiennej, //zmienna bezpieczna do wykorzystania w przerwaniach volatile int zmienna=0; int main() { timerInit(); sei(); //Uruchamia przerwania globalne sbi(DDRD,PD0); sbi(DDRD,PD1); while (1) { //kod programu przełączajacy diodę LED na pinie PD0 _delay_ms(500); } } ISR(TIMER1_COMPA_vect) { //kod programu przełączajacy diodę LED na pinie PD1 } |
Pytania – zrobić notatkę:
- jak działa ten program?
- czy w pętli głównej programu możemy napisać kod blokujący (taki, który blokuje program na dłuższy czas), a dioda i tak będzie migać z dobrą częstotliwością?
- co się stanie jak zablokujemy przerwanie, np. dodamy “_delay_ms(5000)” ? Jak będą działać diody?
3. Przerwania zewnętrzne – dioda LED
- na bazie programu z zadania 2, wykonać kolejne zadanie
- dioda podłączona do PD0 ma ciągle migać w pętli głównej programu. Dioda z pinu PD1 – działa w przerwaniu od Timer1, dioda miga
- podłączyć kolejną diodę do pinu PD5 i skonfigurować odpowiednie piny
- podłączyć przycisk do pinu gdzie jest możliwość obsługi przerwania zewnętrznego (INT0)
- skonfigurować pin do obsługi przycisków (PULL-UP)
- skonfigurować przerwanie zewnętrzne dla wybranego pinu z reakcją na zbocze opadające (należy ustawić dwa bity zgodnie z dokumentacją)
- funkcja przerwania INT0-> ISR(INT0_vect)
- każde przyciśnięcie przycisku generuje przerwanie, w przerwaniu powinna być przełączana dioda podłączona do pinu PD5
Pytania – zrobić notatkę:
- co to jest zbocze opadające, zbocze narastające?
- czy program przełączy stan diody natychmiast, czy będzie opóźnienie z innego przerwania lub pętli głównej? Jak zadziała jeśli w pętli głównej będzie dłuższe zadanie?
- co się stanie jak w przerwaniu od przycisku dodamy opóźnienie 5000ms? (przerwanie należy ciągle wywoływać, naciskać przycisk)
- co się stanie jak w przerwaniu od licznika dodamy opóźnienie 5000ms?
- dlaczego dwa powyższe zadania działają inaczej, jaka jest różnica i dlaczego?
4. Wyświetlacz 7-segmentowy na przerwaniach
- przerobić program z poprzedniego laboratorium tak aby wyświetlacz 7-segmetnowy obsługiwał liczby w zakresie 0-9999,
- powinna być zmienna globalna “liczba”, której wartość jest wyświetlana na wyświetlaczu
- odświeżanie wyświetlacza (multipleksowanie) należy przenieś do przerwania wewnętrznego, należy odpowiednio skonfigurować czasy przerwania
- w wywołaniu przerwania nie wolno używać funkcji opóźniających, kod programu powinien być jak najszybszy
- w pętli głównej zrobić licznik liczący od 0 do 250 co jedną sekundę, wartość wyświetlić na wyświetlaczu
5. Enkoder mechaniczny – impulsator
- na bazie zadania 4 przygotować program, który zmienia wartość zmiennej “wartosc” za pomocą enkodera i prezentuje ją na wyświetlaczu 7-segmentowym. Skasować licznik z pętli głównej programu.
- działanie enkodera zostało zaprezentowane na rysunku poniżej
- podłączyć enkoder, piny “Enc_A” i “Enc_B” do pinów mikrokontrolera, pin “Enc_com” do GND
- skonfigurować piny jak do obsługi przycisków (PULL-UP)
- napisać program, który odczyta kierunek obrotu enkodera i będzie zwiększał, zmniejszał zmienną “wartosc”
- zmienna “wartosc” ma być wyświetlana na wyświetlaczu 7-segmentowym
- zakres liczb jakie może przyjmować zmienna “wartość” to -100 do 100. Napisać odpowiednie zabezpieczenia i wyświetlanie liczby ujemnej