Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 22 lis 2024, o 21:16


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
PostNapisane: 29 sty 2016, o 20:10 
Offline
Nowy

Dołączył(a): 29 sty 2016
Posty: 20
Pomógł: 0

Witam. Mam takie pytanie odnośnie korzystania z trybu CTC na atmega8. W dokumentacji na stronie 97 jest napisane że ten tryb zlicza do rejestru porównania OCR1A. Natomiast na stronie 98 jest coś wspomniane o OCR1B. Jak to z tym jest? Które z nich należy wpisać jako rejestr porównania? Z góry dziękuję za odpowiedź, i przepraszam jeżeli umieściłem w złym dziale i/lub nazwałem źle temat, ale jest to mój pierwszy post.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 sty 2016, o 20:55 
Offline
Nowy

Dołączył(a): 29 sty 2016
Posty: 20
Pomógł: 0

To w takim razie mam pytanie do takiego kodu
Kod:
#include <avr/io.h>
            #include <avr/interrupt.h>
            #define LED (1<<PC1)
            #define LED1 (1<<PC2)
            #define LED2 (1<<PC3)
        volatile uint8_t timer;
        uint8_t flaga, flaga2;

            int main (void)
            {
            DDRC |= LED|LED1|LED2;
            PORTC |= LED|LED1|LED2;
            TCCR1B |= (1<<WGM12);
            TCCR1B |= (1<<CS12);
            OCR1A = 31249;
            TIMSK |= (1<<OCIE1A);
            sei();
    while(1)
            {
                    if (timer==0)
                    {
                     PORTC &= ~LED;
                    }
                else if (timer==5)
                {
                PORTC |= LED;
                PORTC &= ~LED1;
                flaga=1;
                }
                else if (timer==10 && flaga==1)
                        {
                            PORTC |= LED1;
                            PORTC &= ~LED2;

                            flaga2=1;
                        }
                else if (timer==15 && flaga2==1)
                {
                    PORTC |= LED2;
                    flaga=0;
                    flaga2=0;
                    PORTC &= ~LED;
                }

            }


    }
    ISR(TIMER1_COMPA_vect)
    {
    timer++;
    if (timer>15) timer=0;

Czy jeżeli korzystam z TCCR1B to w tym rejestrze porównania nie powinno się wpisać OCR1B zamiast OCR1A i w TIMSK |= (1<<OCIE1B);?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 sty 2016, o 21:39 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

marek2012r napisał(a):
Czy jeżeli korzystam z TCCR1B to w tym rejestrze porównania nie powinno się wpisać OCR1B zamiast OCR1A ?

Nie.

Popełniasz błąd prawie wszystkich początkujących wg których rejestr TCCR1A jest od kanału OCR1A a rejestr TCCR1B - od kanału OCR1B. Timer1 w Atmega8 ma tak dużo trybów pracy, że bity konfiguracyjne nie zmieściły by się w ośmiu bitach jednego rejestru. Aby je pomieścić potrzeba kolejnych ośmiu bitów w kolejnym rejestrze. I dlatego Timer1 ma dwa rejestry konfiguracyjne - TCCR1A i TCCR1B.

Co do trybu CTC.
Obrazek
W tabeli widać, że aby włączyć tryb CTC należy ustawić bit WGM12.

A ten bit leży w rejestrze TCCR1B
Obrazek

W tabeli widać również, że rejestrem porównania jest rejestr OCR1A. I do tego rejestru należy wpisać liczbę, do której będzie liczył Timer1.

Aby Timer zaczął pracować należy jeszcze ustawić m.in. preskaler. Bity preskalera znajdują się w TCCR1B.

Podsumowując. Podstawowy tryb CTC korzysta z rejestru porównania OCR1A. Ale żeby go włączyć należy ustawić bity z rejestru TCCR1B. Bo w tym rejestrze bity te umieścił producent.

Przeanalizuj dobrze podrozdział "16-bit Timer/Counter Register Description" z noty pdf. A zwłaszcza to jakie bity znajdują się w rejestrach konfiguracyjnych.

------------------------ [ Dodano po: 6 minutach ]

W trybie CTC można również korzystać z rejestru OCR1B i z przerwania od porównania licznika TCNT1 z tym rejestrem. Ale wartość wpisana do OCR1B musi być mniejsza od wartości w OCR1A.

Licznik TCNT1, po zrównaniu się z OCR1A, zostaje wyzerowany i zaczyna zliczać od zera do wartości w OCR1A. Jeśli w OCR1A będzie wartość np. 1000 to TCNT1 do liczy do tej wartości i ani jednego impulsu dalej. Więc jeśli w OCR1B byłaby wartość np. 1005 to licznik nigdy by do niej nie doliczył.


Autor postu otrzymał pochwałę


Ostatnio edytowano 29 sie 2016, o 19:33 przez jacekk232, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 sty 2016, o 21:51 
Offline
Nowy

Dołączył(a): 29 sty 2016
Posty: 20
Pomógł: 0

Bardzo fajnie wszystko wytłumaczone. Temat to zamknięcia. :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 sty 2016, o 15:36 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

1Yokoon napisał(a):
Pomyliłeś z trybem PWM.
W trybie CTC licznik TCNT1A po zrównaniu z rejestrem OCR1A zeruje się i liczy od nowa.

A w którym miejscu napisałem, że po zrównaniu się licznika TCNT1 z OCR1A licznik liczy dalej?

Przecież napisałem
Kod:
Licznik TCNT1, po zrównaniu się z OCR1A, zostaje wyzerowany i zaczyna zliczać od zera do wartości w OCR1A.

Czyli to samo co ty.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sty 2016, o 09:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

To co napisałem dotyczy trybu CTC.

Spójrz na poniższy program
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Timer1 pracuje w trybie CTC. Wartość w OCR1A została tak dobrana aby przy zegarze 16MHz i preskalerze 1024, przerwanie wywoływało się co jedną sekundę. Dioda LED1 zmienia stan co sekundę.

Wartość w OCR1B jest o połowę mniejsza niż wartość w OCR1A. Dioda LED2 również zmienia swój stan co sekundę ale w połowie czasu pomiędzy mignięciami LED1. Obydwie diody migają co sekundę.

Natomiast w poniższym programie miga tylko dioda LED1 co pół sekundy bo wartość w OCR1B jest większa niż w OCR1A.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Przerwanie Compare Match B nie wywołuje się bo licznik TCNT1 zostaje wyzerowany przy zrównaniu się OCR1A (7812) i nie ma możliwości aby doliczył do wartości równej OCR1B (15624).


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sty 2016, o 10:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

Napiszę jeszcze kilka słów o tym dlaczego obydwa przerwania wykonują się co sekundę skoro wartość w OCR1B jest mniejsza niż w OCR1A.

Spójrzmy na poniższy rysunek
Obrazek

Licznik TCNT1 liczy sobie od punktu A do punktu C. W punkcie C zostaje wyzerowany i znów zaczyna liczyć od A do C. W tym czasie mija jedna sekunda i przerwanie Compare Match A zostaje wywoływane co sekundę.

A jak działa przerwanie Compare Match B?
Licznik TCNT1 zaczyna liczyć w punkcie A. W punkcie B jego wartość jest równa wartości w OCR1B. Minęło pół sekundy. Zostaje wywołane przerwanie. Licznik liczy dalej. Od punktu B do punktu C mija pół sekundy. TCNT1 zostaje wyzerowany i zaczyna liczyć od nowa. Od punktu A do punktu B mija też pół sekundy.

Od B do C - pół sekundy i od A do B również pół sekundy. Czyli pierwsze przerwanie Compare Match B wywoła się po upływie pół sekundy ale już każde następne po upływie sekundy.

Obydwa przerwania wywołują się co sekundę ale są przesunięte względem siebie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sty 2016, o 12:22 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

1Yokoon napisał(a):
Dlaczego licznik liczy dalej skoro TCNT1 = OCR1B, TCNT1=0 liczy od początku


Licznik liczy dalej bo w trybie CTC jego wartość jest zerowana przy zrównaniu się z rejestrem OCR1A. Zrównanie się z OCR1B nie zeruje TCNT1. Licznik jest jeden a rejestry porównania dwa. Więc może się zerować przy zrównaniu się tylko z jednym z nich.

I tym ważniejszym rejestrem jest OCR1A. To ten rejestr określa wartość TOP czyli maksymalną do jakiej może zliczać TCNT1.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lut 2016, o 00:32 
Offline
Nowy

Dołączył(a): 07 gru 2015
Posty: 13
Pomógł: 0

Dziękuję za ten artykuł, ponieważ wiele mi wyjaśnił, jednak w celu utrwalenia informacji chciałem powyższy kod trochę zmodyfikować. Założenia były takie, aby dwie diody mrugały co jedną sekundę:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Tutaj pojawia się zapewne mój błahy błąd. Otóż pierwsza dioda świeci cały czas, natomiast druga zgodnie z oczekiwaniami. Czy ktoś jest wstanie nakierować mnie na tenże błąd?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lut 2016, o 01:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

W jednym i drugim przerwaniu używasz tej samej zmiennej licznik. A przez to warunek w przerwaniu TIMER0_COMPB nigdy się nie wykona. Dioda LED_1 powinna migać a dioda LED_2 - nie.

Jeśli zmienna licznik będzie miała wartość równą 29 to warunki w obydwóch przerwaniach się nie wykonają. Przy następnym przerwaniu COMPA zmienna licznik zostanie zwiększona o jeden. Warunek się wykona. Stan diody zostanie zmieniony na przeciwny i zmienna zostanie wyzerowana. I tym sposobem warunek w przerwaniu COMPB znów się nie wykona bo przecież zmienna licznik ma wartość zero.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lut 2016, o 19:10 
Offline
Nowy

Dołączył(a): 07 gru 2015
Posty: 13
Pomógł: 0

Dzięki za pomoc, faktycznie problem był związany ze zmienną licznik ;) .



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO