Skocz do zawartości

ATTiny2313A Licznik ma częstotliwość różną od CPU


Oskar_Zaremba

Pomocna odpowiedź

Dzień Dobry,
 
Mam pytanie odnośnie programowania mikro kontrolerów.
 
Zajmuję się akurat ATTINY2313A.
Mam ustawiony wewnętrzny oscylator na częstotliwość 4 MHz bez wewnętrznego podziału zegara przez 8.

Poniżej mój krótki kod w 😄
 

#include <avr/io.h>
 
int main(void) {
                 DDRB = _BV(DDB0);  // ustawienie pinu PB0 w stan wyjścia
                 TCCR0A = _BV(WGM01); // ustawienie generatora w tryb CTC
                 TCCR0B = _BV(CS00); // wybór zegara z skalowaniem przez 1
                 OCR0A = 1; // ustawienie górnej wartości licznika
                 while (1) {
                                 if (TIFR & _BV(OCF0A)) { // sprawdzenie czy w rejestrze TIFR ustawiona została flaga OCF0A po przepełnieniu licznika OCR0A
                                                  TIFR |= _BV(OCF0A); // wyzerowanie flagi OCF0A poprzez ustawienie logicznej jedynki
                                                  PORTB ^= _BV(DDB0); // przełączenie bitu na pinie PB0
                                 }
                 }
}

 
W moim przypadku według dokumentacji czyli wzoru poniżej:

fOC0A=fclk_I/O/(2·N·(1+OCR0A))

fOC0A=4000000/(2·1·(1+1))

fOC0A=1000000=1MHz


A teraz do meritum:) Co robię nie tak? Częstotliwość którą uzyskuję to -->  207.4KHz. W załączniku przesyłam zdjęcie z oscyloskopu z widocznym przebiegiem na pinie PB0.
 
Pozdrawiam,
Oskar Zaremba

 

20200911_104708.jpg

Link do komentarza
Share on other sites

Nie ma określonej szybkości działania pętli while. Mikrokontroler wykonuje instrukcje maszynowe tak, jak kompilator je wygenerował. Prędkość wykonania każdej instrukcji możesz znaleźć w nocie katalogowej mikrokontrolera, ale w przypadku AVR jest dość prosto, bo większość instrukcji zajmuje jeden takt procesora. Uzyskana szybkość będzie zależeć od tego jaki kod się w w tej pętli wykonuje.

Aby uzyskać wyższe prędkości, należy użyć trybu PWM timera — wówczas nóżka jest przełączana bezpośrednio przez układ timera, bez udziału reszty mikrokontrolera, więc prędkość nie zależy od szybkości wykonywania kodu. O trybach timera możesz przeczytać w nocie katalogowej w dziale o timerach.

W szczególności przeczytaj sekcje 12.8.2 i 12.8.3 noty katalogowej.

Edytowano przez deshipu
  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

PWM to dobry pomysł, ale z tego co pamiętam to można sterować w nim tylko współczynnikiem wypełnienia a ja potrzebuję wysterować konkretną wartość częstotliwości😊

Rozumiem, że częstotliwość taktowania licznika jest wyrażona przez wzór, który podałem natomiast wykonanie instrukcji warunkowej plus czyszczenie flagi i przełączenie bitu portu zajmuje dodatkowe takty licznika. Te dodatkowe takty sprawiają, że przegapiam kilka przepełnień licznika, a więc przełączam port kilkukrotnie wolniej aniżeli częstotliwość zegara dobrze to rozumiem?

Czy jest zatem jakiś sposób, żeby uzyskać na pinie PB0 częstotliwości wynikające z wzoru, który podałem? Chciałbym sterować wartością prescalera i wartością OCR0A tak żeby uzyskiwać wynikające z wzoru częstotliwości.

W dalszym ciągu czytam datasheet tego mikrokontrolera i widzę, że w przypadku licznika 16bit tryb fast PWM można najprawdopodobniej sterować częstotliwością PWM. Za chwilkę spróbuję to wytestować😊

Link do komentarza
Share on other sites

Widzę, że jedynym sposobem sterowania częstotliwością PWM jest używanie prescalera (1, 8, 64, 256, 1024) co w moim przypadku jest niewystarczające, ponieważ potrzebuję większej precyzji.

W mojej głowie rodzi się teraz pytanie… Po co w trybie CTC jest możliwość tak dokładnego sterowania częstotliwością, skoro nie ma możliwości realnego tego wykorzystania?? Za każdym razem, kiedy sprawdzę którąś z flag i wykonam instrukcję tracę takty zegara więc czynności wykonywane przez program nie będą zgodne z częstotliwością (powyżej pewnej granicznej wartości) z podanego wzoru…:/

Link do komentarza
Share on other sites

Nie doczytałeś. PWM to nie jedyny tryb pracy pinów sprzęgniętych z modułem generacji sygnałów (Waveform Generation Mode). Popatrz na bity WGMxx. Jeśli odpowiednio je ustawisz, stan pinu będzie odwracany w chwili przeładowania timera. To idealnie pasuje do Twoich potrzeb: rejestrem OCRxx ustawiasz okres, timer puszczasz w CTC a WGM ustawiasz na odwracanie. Wydaje mi się, że dla 4MHz, właśnie 1MHz będzie maksem jaki możesz z tego wyciągnąć.

Link do komentarza
Share on other sites

To rozwiązało mój problem:)

#include <avr/io.h>

int main(void) {
    DDRB = _BV(DDB2);  // ustawienie pinu PB0 w stan wyjścia
    TCCR0A = _BV(COM0A0) | _BV(WGM01); // ustawienie generatora w tryb CTC
    TCCR0B = _BV(CS00); // wybór zegara z skalowaniem przez 1
    OCR0A = 1; // ustawienie górnej wartości licznika
}

Dziękuje za odpowiedzi.

Link do komentarza
Share on other sites

1 godzinę temu, Oskar_Zaremba napisał:

jedynym sposobem sterowania częstotliwością PWM jest używanie prescalera (1, 8, 64, 256, 1024)

To też nie jest prawdą. Nawet tiny ma timery wyposażone w tryb PWM, gdzie okres ustawiasz jednym z rejestrów OCRxx. Tracisz w ten sposób jeden kanał sprzętowego wyjścia, ale za to w drugim masz ustawialny zarówno okres jak i wypełnienie. Poza tym bardziej rozbudowany, 16-bitowy  timer1 ma tryby PWM z predefiniowanymi okresami 256, 512 i 1024, co daje rozdzielczości odpowiednio 8, 9 i 10 bitów a także można mu ustawiać okres w rejestrze ICR, nie tracąc kanału PWM. No i masz wreszcie pin CKOUT, na którym możesz poprzez odpowiednie zaprogramowanie fuse-bitów dostać zegar CPU wprost z generatora, bez marnowania jakiegokolwiek timera. Dla 4MHz to będzie oczywiście 4MHz, ale może wystarczy prędkość 1MHz?

Link do komentarza
Share on other sites

4 godziny temu, marek1707 napisał:

Nie doczytałeś. PWM to nie jedyny tryb pracy pinów sprzęgniętych z modułem generacji sygnałów (Waveform Generation Mode). Popatrz na bity WGMxx. Jeśli odpowiednio je ustawisz, stan pinu będzie odwracany w chwili przeładowania timera. To idealnie pasuje do Twoich potrzeb: rejestrem OCRxx ustawiasz okres, timer puszczasz w CTC a WGM ustawiasz na odwracanie. Wydaje mi się, że dla 4MHz, właśnie 1MHz będzie maksem jaki możesz z tego wyciągnąć.

Nie twierdziłem, że PWM to jedyny tryb pracy pinów. Pisałem tylko że częstotliwością sygnału PWM można sterować tylko przy użyciu prescalera. Teraz widzę, że rzeczywiście, jeśli ustawię WGM00 i WGM01 to mam np. generator ustawiony na fast PWN, a jeśli dodam do tego WGM02 i COM0A0 to będę miał fastPWM z przełączaniem przy przepełnieniu licznika po uzyskaniu wartości OCRnx tyle tylko że wtedy nie mam już możliwości sterowania wypełnieniem sygnału a skoro steruje i tak tylko samą częstotliwością to po co mi wtedy PWM z stałym wypełnieniem 50%. Przy ustawieniach, które podałem, czyli wykorzystaniu CTC mam mniej kodu. Tak jak pisałeś timer w trybie CTC, czyli WGM01 ustawiony a do przełączania wystarczy COM0A0 zamiast dodatkowych WGMów.

Link do komentarza
Share on other sites

4 godziny temu, marek1707 napisał:

To też nie jest prawdą. Nawet tiny ma timery wyposażone w tryb PWM, gdzie okres ustawiasz jednym z rejestrów OCRxx. Tracisz w ten sposób jeden kanał sprzętowego wyjścia, ale za to w drugim masz ustawialny zarówno okres jak i wypełnienie. Poza tym bardziej rozbudowany, 16-bitowy  timer1 ma tryby PWM z predefiniowanymi okresami 256, 512 i 1024, co daje rozdzielczości odpowiednio 8, 9 i 10 bitów a także można mu ustawiać okres w rejestrze ICR, nie tracąc kanału PWM. No i masz wreszcie pin CKOUT, na którym możesz poprzez odpowiednie zaprogramowanie fuse-bitów dostać zegar CPU wprost z generatora, bez marnowania jakiegokolwiek timera. Dla 4MHz to będzie oczywiście 4MHz, ale może wystarczy prędkość 1MHz?

Eh:/ Tutaj przyznam się, że nie do końca wszystko rozumiem:/ Pisząc szczerze to jeszcze 3 tygodnie temu zaczynałem od 0 czytając o elementach biernych typu rezystor i widzę, że jeszcze ogrom wiedzy do zdobycia mnie czeka…☹Wracając do tematu. Tracę jeden kanał sprzętowego wyjścia tzn. pin przełączany przy przepełnieniu licznika zapewne, ale o co chodzi z tym drugim, gdzie mam okres i wypełnienie?? Widzę, że timer 16 bitowy ma różne rozdzielczości, ale czy można mu ustawić i okres, i wypełnienie jednocześnie? Widzę w tabeli generatora fali dla np. PWM, Phase and Freq Correct, że jako TOP jest podane albo ICR1 albo OCR1A, ale czy można ustawić oba tak żeby jeden rejestr trzymał wartość ustalająca częstotliwość a drugi wypełnienie? Trochę to wszystko zagmatwane:/ Czy mógłby Pan podpowiedzieć w jaki sposób mogę ustawić zarówno okres jak i wypełnienie PWM??

Z góry uprzejmie dziękuje😊

Link do komentarza
Share on other sites

Okay:/ Już wiem jak zrobić i okres i wypełnienie:)

#include <avr/io.h>

int main(void) {
    DDRB = _BV(DDB2);  // ustawienie pinu PB0 w stan wyjścia
    TCCR0A = _BV(COM0A0) | _BV(WGM01); // ustawienie generatora w tryb CTC
    TCCR0B = _BV(CS00); // wybór zegara z skalowaniem przez 1
    OCR0A = 5; // ustawienie górnej wartości licznika
    DDRB |= _BV(DDB3) | _BV(DDB4);
    TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1B0);
    TCCR1B = _BV(WGM13) | _BV(CS10);
    OCR1A = 5;
    OCR1B = 8;
    ICR1 = 10;
}

Przepraszam za przedwczesne pytania...Dopiero się uczę:/

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.