Spisu treści:
- Krok 1: Opis
- Krok 2: Stwierdzenie problemu 1: Migajmy najpierw diodę LED (zieloną) co 50 ms
- Krok 3: Opis problemu 2: Migajmy drugą diodę LED (niebieską) co 1 s
- Krok 4: Opis problemu 3: Migajmy trzecią diodę LED (czerwoną) co 16 ms
- Krok 5: Pisanie kodu programu w C. Ładowanie pliku HEX do pamięci Flash mikrokontrolera
- Krok 6: Tworzenie obwodu elektrycznego
Wideo: Mikrokontroler AVR. Migacz diod LED za pomocą timera. Przerwania timerów. Tryb timera CTC: 6 kroków
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:31
Cześć wszystkim!
Timery to ważna koncepcja w dziedzinie elektroniki. Każdy element elektroniczny działa na podstawie czasu. Ta podstawa czasu pomaga zsynchronizować całą pracę. Wszystkie mikrokontrolery pracują z określoną częstotliwością zegara, wszystkie mają możliwość ustawienia timerów. AVR może pochwalić się bardzo dokładnym, precyzyjnym i niezawodnym timerem. Oferuje mnóstwo funkcji, dzięki czemu jest obszernym tematem. Najlepsze jest to, że zegar jest całkowicie niezależny od procesora. W ten sposób działa równolegle do procesora i nie ma interwencji procesora, co sprawia, że zegar jest dość dokładny. W tej sekcji wyjaśniam podstawowe pojęcia Timerów AVR. Piszę prosty program w kodzie C do sterowania flasherem LED za pomocą timerów.
Krok 1: Opis
W ATMega328 istnieją trzy rodzaje timerów:
Timer/Counter0 (TC0) - jest 8-bitowym modułem Timer/Counter ogólnego przeznaczenia, z dwoma niezależnymi jednostkami OutputCompare i obsługą PWM;
Timer/Licznik1 (TC1) – 16-bitowy Timer/Licznik umożliwia dokładne synchronizowanie czasu wykonywania programu (zarządzanie zdarzeniami), generowanie fali i pomiar czasu sygnału;
Timer/Counter2 (TC2) - jest uniwersalnym, kanałowym, 8-bitowym modułem Timer/Counter z PWM i pracą asynchroniczną;
Krok 2: Stwierdzenie problemu 1: Migajmy najpierw diodę LED (zieloną) co 50 ms
Metodologia:
- użycie preskalera Timer0 do redukcji sygnału elektrycznego o wysokiej częstotliwości do niższej częstotliwości przez dzielenie liczb całkowitych;
- używanie przerwania za każdym razem, gdy Timer0 się przepełni;
Timer0 (8 bitów) odlicza od 0 do 255 po czym się przepełniają, wartość ta zmienia się przy każdym impulsie zegara.
F_CPU=16MHz: Okres zegara = 1000ms / 16000000Hz = 0,0000625ms
Licznik timera = (Wymagane opóźnienie / Okres czasu zegara)-1 = (50ms / 0,0000625ms) = 799999
Zegar tyka już 799999 razy, co daje opóźnienie tylko 50 ms!
Do zmniejszenia licznika timerów możemy wykorzystać technikę dzielenia częstotliwości, nazywaną prescalingiem. AVR oferuje nam do wyboru następujące wartości preskalerów: 8, 64, 256 i 1024. Zobacz tabelę podsumowującą wyniki zastosowania różnych preskalerów.
Wartość licznika powinna zawsze być liczbą całkowitą. Wybierzmy preskaler 256!
W większości mikrokontrolerów istnieje coś, co nazywa się przerwaniem. To przerwanie może zostać uruchomione, gdy zostaną spełnione określone warunki. Teraz za każdym razem, gdy uruchamiane jest przerwanie, AVR zatrzymuje się i zapisuje wykonanie głównej procedury, obsługuje wywołanie przerwania (wykonując specjalną procedurę, zwaną Interrupt Service Routine, ISR) i po jej zakończeniu powraca do główną rutynę i kontynuuje ją.
Ponieważ wymagane opóźnienie (50ms) jest większe niż maksymalne możliwe opóźnienie: 4, 096ms = 1000ms / 62500Hz * 256, oczywiście timer się przepełni. A ilekroć licznik się przepełni, wywoływane jest przerwanie.
Ile razy powinno być wywoływane przerwanie?
50ms / 4,096ms = 3125 / 256 = 12,207 Jeśli zegar przekroczyłby 12 razy, minęłoby 12 * 4,096 ms = 49,152 ms. W 13. iteracji potrzebujemy opóźnienia 50ms – 49,152ms = 0,848ms.
Przy częstotliwości 62500 Hz (preskaler = 256) każdy tik trwa 0,016 ms. Tak więc, aby osiągnąć opóźnienie 0,848ms, wymagałoby to 0,848ms / 0,016ms = 53 tików. Tak więc w 13. iteracji pozwalamy, aby timer zliczył tylko do 53, a następnie go zresetował.
Zainicjuj Timer0/Licznik (patrz zdjęcie):
TCCR0B |= (1 << CS02) // ustawienie timera z preskalerem = 256 TCNT0 = 0 // inicjalizacja licznika TIMSK0 |= (1 << TOIE0) // włączenie przerwania przepełnienia sei() // włączenie przerwań globalnych tot_overflow = 0 // zainicjuj zmienną licznika przepełnienia
Krok 3: Opis problemu 2: Migajmy drugą diodę LED (niebieską) co 1 s
Metodologia:
- użycie preskalera Timer1 do redukcji sygnału elektrycznego o wysokiej częstotliwości do niższej częstotliwości przez dzielenie liczb całkowitych;
- używanie Clear Timer w trybie porównania (CTC);
- korzystanie z przerwań w trybie CTC;
Timer1 (16 bitów) liczy od 0 do 65534 po czym się przepełnia. Wartość ta zmienia się z każdym impulsem zegara.
F_CPU=16MHz: Okres zegara = 1000ms / 16000000Hz = 0,0000625msLicznik timera = (Wymagane opóźnienie / Okres zegara)-1 = (1000ms / 0,0000625ms) = 15999999
Zegar odmierzył już 15999999 razy, dając opóźnienie 1s!
Do zmniejszenia licznika timerów możemy wykorzystać technikę dzielenia częstotliwości, nazywaną prescalingiem. AVR oferuje nam do wyboru następujące wartości preskalerów: 8, 64, 256 i 1024. Zobacz tabelę podsumowującą wyniki zastosowania różnych preskalerów. Wartość licznika powinna zawsze być liczbą całkowitą. Wybierzmy preskaler 256!
W trybie Clear timer on Compare(CTC) rejestr OCR1A lub ICR1 jest używany do manipulowania rozdzielczością licznika. W trybie CTC licznik jest wyzerowany, gdy wartość licznika (TCNT1) pasuje do OCR1A lub ICR1. OCR1A lub ICR1 określają górną wartość licznika, stąd też jego rozdzielczość. Ten tryb pozwala na większą kontrolę nad częstotliwością wyjściową porównywania wyników. Upraszcza również operację zliczania zdarzeń zewnętrznych. Musimy powiedzieć AVR, aby zresetował Timer1/Licznik, gdy tylko jego wartość osiągnie wartość 62500, aby uzyskać opóźnienie 1s.
Zainicjuj Timer1/Licznik (patrz zdjęcie):
TCCR1B |= (1 << WGM12)|(1 << CS12) // ustawienie timera z preskalerem = 256 i trybem CTC TCNT1 = 0 // inicjalizacja licznika TIMSK1 |= (1 << OCIE1A) // włączenie porównania przerwań OCR1A = 62500 // zainicjuj porównywaną wartość
Krok 4: Opis problemu 3: Migajmy trzecią diodę LED (czerwoną) co 16 ms
Metodologia:
- użycie preskalera Timer2 do redukcji sygnału elektrycznego o wysokiej częstotliwości do niższej częstotliwości przez dzielenie liczb całkowitych;
- używanie Clear Timer w trybie porównania (CTC);
- korzystanie ze sprzętowego trybu CTC bez przerwań;
Timer2 (8 bitów) liczy od 0 do 255 po czym się przepełnia. Wartość ta zmienia się z każdym impulsem zegara.
F_CPU=16MHz: Okres zegara = 1000ms / 16000000Hz = 0,0000625ms
Licznik timera = (Wymagane opóźnienie / okres czasu zegara)-1 = (16ms / 0,0000625ms) = 255999
Zegar odmierzył już 255999 razy, dając opóźnienie 16ms!
Zobacz tabelę podsumowującą wyniki stosowania różnych preskalerów. Wartość licznika powinna zawsze być liczbą całkowitą. Wybierzmy preskaler 1024!
W trybie CTC licznik jest wyzerowany, gdy wartość licznika (TCNT2) odpowiada OCR2A lub ICR2. Pin PB3 jest również pinem Output Compare TIMER2 - OC2A (patrz schemat).
Rejestr kontrolny timera/licznika 2 A – TCCR2A Bit 7:6 – COM2A1:0 – Tryb porównania wyjścia dla jednostki porównania A. Ponieważ musimy przełączyć diodę LED, wybieramy opcję: Przełącz OC2A na porównanie Pin OC2A jest automatycznie przełączany. Nie ma potrzeby sprawdzania żadnego bitu flagi, nie ma potrzeby zajmowania się przerwaniami.
Zainicjuj Timer2/Licznik
TCCR2A |= (1 << COM2A0)|(1 << WGM21) // ustaw pin OC2A timera w trybie przełączania i trybie CTC TCCR2B |= (1 << CS22)|(1 << CS21)|(1 << CS20) //ustaw licznik czasu z preskalerem = 1024 TCNT2 = 0 //inicjalizuj licznik OCR2A = 250 //inicjalizuj porównywaną wartość
Krok 5: Pisanie kodu programu w C. Ładowanie pliku HEX do pamięci Flash mikrokontrolera
Napisanie i zbudowanie aplikacji mikrokontrolera AVR w kodzie C z wykorzystaniem Zintegrowanej Platformy Programistycznej - Atmel Studio.
F_CPU definiuje częstotliwość zegara w hercach i jest powszechny w programach korzystających z biblioteki avr-libc. W tym przypadku jest używany przez procedury opóźniające do określenia sposobu obliczania opóźnień czasowych.
#ifndef F_CPU
#define F_CPU 16000000UL // mówienie częstotliwości kryształu kontrolera (16 MHz AVR ATMega328P) #endif
#include // nagłówek, aby włączyć kontrolę przepływu danych przez piny. Definiuje piny, porty itp.
Pierwszy plik dołączany jest częścią avr-libc i będzie używany w prawie każdym projekcie AVR, nad którym pracujesz. io.h określi, jakiego procesora używasz (dlatego określasz część podczas kompilacji), a następnie dołączy odpowiedni nagłówek definicji IO dla używanego przez nas układu. Po prostu definiuje stałe dla wszystkich twoich pinów, portów, rejestrów specjalnych itp.
#include // nagłówek, aby włączyć przerwanie
nietrwały uint8_t tot_overflow; // zmienna globalna do zliczania przepełnień
Metodologia rozwiązywania problemów: Najpierw miga dioda (zielona) co 50 ms
- użycie preskalera Timer0 do redukcji sygnału elektrycznego o wysokiej częstotliwości do niższej częstotliwości przez dzielenie liczb całkowitych;
- używanie przerwania za każdym razem, gdy Timer0 się przepełni;
void timer0_init() //zainicjuj timer0, przerwanie i zmienną
{ TCCR0B |= (1 << CS02); // ustaw timer z preskalerem = 256 TCNT0 = 0; // zainicjuj licznik TIMSK0 |= (1 << TOIE0); // włącz przepełnienie nterrupt sei(); // włącz globalne przerwania tot_overflow = 0; // zainicjuj zmienną licznika przepełnienia }
Metodologia rozwiązywania problemów: Miga druga dioda LED (niebieska) co 1 s
- użycie preskalera Timer1 do redukcji sygnału elektrycznego o wysokiej częstotliwości do niższej częstotliwości przez dzielenie liczb całkowitych;
- używanie Clear Timer w trybie porównania (CTC);
- korzystanie z przerwań w trybie CTC;
void timer1_init() // zainicjuj timer1, przerwanie i zmienną{ TCCR1B |= (1 << WGM12)|(1 << CS12); // ustaw timer z preskalerem = 256 i trybem CTC TCNT1 = 0; // inicjalizacja licznika OCR1A = 62500; // zainicjuj porównywaną wartość TIMSK1 |= (1 << OCIE1A); // włącz przerwanie porównania}
Metodologia rozwiązywania problemów: Migaj trzecią diodą LED (czerwoną) co 16 ms
- użycie preskalera Timer2 do redukcji sygnału elektrycznego o wysokiej częstotliwości do niższej częstotliwości przez dzielenie liczb całkowitych;
- używanie Clear Timer w trybie porównania (CTC);
- korzystanie ze sprzętowego trybu CTC bez przerwań;
void timer2_init() // zainicjuj timer2{ TCCR2A |= (1 << COM2A0)|(1 << WGM21); // ustaw pin timera OC2A w trybie przełączania i trybie CTC TCCR2B |= (1 << CS22)|(1 << CS21)|(1 << CS20); // ustaw timer z preskalerem = 1024 TCNT2 = 0; // inicjalizacja licznika OCR2A = 250; // zainicjuj porównywaną wartość }
Procedura obsługi przerwań przepełnienia TIMER0 wywoływana za każdym razem, gdy przepełnia się TCNT0:
ISR(TIMER0_OVF_vect)
{ tot_przepełnienie++; // śledź liczbę przepełnień }
Ten ISR jest uruchamiany za każdym razem, gdy pojawia się mecz, dlatego przełącz tutaj sam:
ISR (TIMER1_COMPA_vect){ PORTC ^= (1 << 1); // przełącz tutaj prowadzoną}
int główny (unieważniony)
{ DDRB |= (1 << 0); // podłącz 1 (zielony) led do pinu PB0 DDRC |= (1 << 1); // podłącz 2 (niebieski) led do pinu PC1 DDRB |= (1 << 3); // podłącz 3 (czerwone) diody led do pinu PB3 (OC2A) timer0_init(); // zainicjuj timer0 timer1_init(); // zainicjuj timer1 timer2_init(); // zainicjuj timer2 while(1) // zapętl na zawsze {
Jeśli Timer0 przepełnił się 12 razy, minęłoby 12 * 4,096 ms = 49,152 ms. W 13. iteracji potrzebujemy opóźnienia 50ms – 49,152ms = 0,848ms. Tak więc w 13. iteracji pozwalamy, aby timer zliczył tylko do 53, a następnie go zresetował.
if (tot_overflow >= 12) // sprawdź, czy nie. przepełnień = 12 UWAGA: stosuje się '>='
{ if (TCNT0 >= 53) // sprawdź, czy licznik licznika osiągnął 53 { PORTB ^= (1 << 0); // przełącza diodę TCNT0 = 0; // zresetuj licznik tot_overflow = 0; // zresetuj licznik przepełnienia } } } }
Wgrywanie pliku HEX do pamięci flash mikrokontrolera:
wpisz w oknie wiersza poleceń DOS polecenie:
avrdude –c [nazwa programisty] –p m328p –u –U flash:w:[nazwa twojego pliku hex]W moim przypadku jest to: avrdude –c ISPProgv1 –p m328p –u –U flash:w:Timers.hex
To polecenie zapisuje plik hex do pamięci mikrokontrolera. Obejrzyj film ze szczegółowym opisem wypalania pamięci flash mikrokontrolera:
Nagrywanie pamięci flash mikrokontrolera…
Ok! Teraz mikrokontroler pracuje zgodnie z instrukcjami naszego programu. Sprawdźmy to!
Krok 6: Tworzenie obwodu elektrycznego
Połącz elementy zgodnie ze schematem ideowym.
Zalecana:
Programowalny migacz policyjny LED za pomocą STM8 [72 diody]: 9 kroków
Programowalny migacz policyjnych diod LED za pomocą STM8 [72 diody]: STM8S001J3 to 8-bitowy mikrokontroler, który oferuje 8 KB pamięci programowej Flash oraz zintegrowaną pamięć EEPROM z prawdziwymi danymi. Jest określany jako urządzenie o niskiej gęstości w rodzinie mikrokontrolerów STM8S. Ten MCU oferowany w małym pakiecie SO8N
Dub Siren Synth - 555 timerów: 14 kroków (ze zdjęciami)
Dub Siren Synth - 555 Timerów: Dub Siren! Człowieku – nawet nie wiedziałem, że takie istnieją, dopóki przyjaciel DJ nie poprosił mnie, żebym go zrobił. Musiałem trochę kopać (właściwie dużo kopania – zaskakująco niewiele jest w sieci), aby poznać historię dubowej syreny i to
Jak zrobić migacz LED za pomocą LM555 IC: 10 kroków
Jak zrobić migacz LED za pomocą układu LM555 IC: Cześć przyjacielu, Dzisiaj zamierzam zrobić obwód migacza LED za pomocą układu LM555 IC. To jest układ scalony z zegarem. Aby wykonać ten obwód, będziemy potrzebować bardzo mniej komponentów. Zacznijmy
Migacz LED i oscylator PWM przy użyciu timera 555: 3 kroki
Migacz LED i oscylator PWM Korzystanie z timera 555: Każdy był początkujący w elektronice i dla początkujących czasami może być trudno zbudować funkcjonalne obwody. Dlatego postanowiłem opublikować taki projekt. Ten obwód jest uproszczoną wersją prostego obwodu, którego schematy
Jasność diody LED przerwania Arduino w USA: 6 kroków
USA Arduino Interrupt LED Brightness: W tym projekcie stworzymy czerwony, biały i niebieski wyświetlacz LED z potencjometrem i przyciskiem. Brzmi prosto, ale do tego będziemy też używać przerwań. Czyli po naciśnięciu przycisku wartość z potencjometru ustawi