logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ATmega8 - [Bascom] Timer1 i generacja 2 różnych częstotliwości

FastProject 30 Lip 2012 19:24 3166 26
  • #1 11158950
    FastProject
    Poziom 28  
    Witam,
    potrzebuje zbudować generator z 2 częstotliwosciami rzędu kilku 1-2kHz.

    Do tego celu przeznaczyłem Timer1 i rejestry OCR1A i OCR1B i tryb CTC.

    Generator będzie miał dodatkowo zmieniane wypełniania impulsów, wiec zbudowałem sobie taki odo program:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Zaplanowałem sobie, że w przykładowym programie będę generował częstotliwość 1,2kHz i 1,4kHz jednak w praktyce mimo poprawnie obliczonych zawartości rejestrów dla wybranych częstotliwości program nie generuje poprawnie częstotliwości.

    Objawia się to tym, że gdy:
    - Ocr1a = 2857 (1,4kHz), a w Ocr1b = 3333(1,2kHz) to układ generuje tylko pierwszą częstotliwość z OCR1A, no bo 2957 taktów przychodzi szybciej i TIMER1 się zeruje, a wiec nigdy nie ma przerwania z OCR1B,przez co nigdy nie zmiana się stan końcówki PB.2
    - Ocr1a = 3333(1,2kHz), a w Ocr1b = 2857(1,4kHz), to oba układy generują mniejszą częstotliwość 1,2kHz.

    Czy jest więc możliwa generacja dwóch różnych częstotliwości za pomocą timera1 i rejestrów OCR1x?

    Może źle podszedłem do tego tematu i da się to zrobić ale w inny sposób?
    Proszę o podpowiedzi i drobną pomoc.
  • #2 11159009
    LordBlick
    VIP Zasłużony dla elektroda
    FastProject napisał:
    Czy jest więc możliwa generacja dwóch różnych częstotliwości za pomocą timera1 i rejestrów OCR1x?
    Nie spotkałem się z taką możliwością, tryb CTC dobrze działa tylko z OCRxA. bo tylko od tego rejestru zależy kiedy się wyzeruje.
    FastProject napisał:
    Może źle podszedłem do tego tematu i da się to zrobić ale w inny sposób?
    Albo użyć różnych timerów w trybie CTC, albo machać pinami w przerwaniu w zależności od programowej maszyny stanów i to najlepiej wstawką w asemblerze.
  • #3 11159088
    FastProject
    Poziom 28  
    A gdyby tak nie zerować timera1 i dodawać co rejestrów ORC1X wartości odpowiadające czasom poszczególnych stanów kiedy port ma być w stanie 1 lub w stanie 2. Np dla f=1,2kHz gdzie mamy OCR1A=3333, po przerwaniu dodać także 3333(dla wsp wypełnienia 50%), czyli gdy będzie pierwsze przerwanie od OCR1A, bo w tym przerwaniu do wartości 3333 dodajemy kolejne 3333 czyli ładujemy 6666.

    Podobnie dla OCR1B=2857, po 1-wszym przerwaniu załadujemy ORC1B=OCR1B+2857=5714

    Oczywiście na przy końcu przepełnienia trzeba będzie dbać aby przeładować rejestry wartością "offsetowa" nieprzekraczającą 65535??

    Później spróbuję tak to zrobić...

    Co o tym kolego myślisz?
  • #4 11159245
    LordBlick
    VIP Zasłużony dla elektroda
    Jak dla mnie to przekombinowane, raczej trudno będzie zapanować nad w miarę stabilną częstotliwością.
  • #5 11159285
    FastProject
    Poziom 28  
    LordBlick napisał:
    Jak dla mnie to przekombinowane, raczej trudno będzie zapanować nad w miarę stabilną częstotliwością.


    Masz racje..sprawdziłem to właśnie w praktyce...nie dość, że obliczanie nowych (po przepełnieniu timera1) wartości OCR1x trwa trochę, to częstotliwość nie jest stabilna i niedokładna z obliczeniami. A obliczanie i odejmowanie jakichś wartości wynikłych z tych obliczeń mija się z celem...

    Możesz powiedzieć coś więcej o tym:
    LordBlick napisał:
    ... machać pinami w przerwaniu w zależności od programowej maszyny stanów i to najlepiej wstawką w asemblerze.


    Możesz rozwinąć myśl?
  • #6 11159317
    LordBlick
    VIP Zasłużony dla elektroda
    Ustawiasz CTC na bardzo szybki, czas pomiędzy przerwaniami to będzie rozdzielczość regulacji. Reszta to wartości w pamięci(zmienne) odliczające programową syntezę częstotliwości.
  • #7 11159348
    FastProject
    Poziom 28  
    LordBlick napisał:
    Ustawiasz CTC na bardzo szybki, czas pomiędzy przerwaniami to będzie rozdzielczość regulacji. Reszta to wartości w pamięci(zmienne) odliczające programową syntezę częstotliwości.


    Aha..oki, dzięki, spróbujemy narazie coś wycisnąć z Bascoma ale czarno to widzę nawet w asemblerze, bo zależy mi na bardzo dokładnej częstotliwości, a przecież już przerwanie dla OCR1A=10 daje mi 10x mniejszą rozdzielczość a potrzebuje rozdzielczość i dokładność rzędu 1-2Hz przy częstotliwości 1kHz. Tak więc przydał by się AVR z 2 licznikami 16-bitowymi (np Atmega162) :D
  • #8 11159400
    bobeer
    Poziom 28  
    Jakie są założenia co do rozdzielczości oraz stabilności generowanej częstotliwości (jitter) ?
    Generacje częstotliwości kHz na AVR najlepiej zrobić przez zastosowanie DDS. jeden timer w ctc generuje przerwanie w równych odstępach, resztę załatwia się w przerwaniu (trochę tylko kiepsko bo bascom zmarnotrawi dużo czasu- najlepiej tę część napisać w asm).
  • #9 11159753
    FastProject
    Poziom 28  
    Dla częstotliwości od 1kHz do 3kHz potrzebuje rozdzielczość i dokładność +/- max 2Hz. Bardziej zależy mi na dokładności, bo częstotliwości będą rzadko zmieniane.

    P.S. Obliczenia i testy robię dla kwarcu 8MHz, dla 16Mhz jeszcze nie próbowałem...
  • #10 11159989
    bobeer
    Poziom 28  
    Nie wiem jak chciałeś uzyskać rozdzielczość strojenia 2Hz przy 1kHz z użyciem timera który ma 8 bit.
    Tak jak pisałem wcześniej kieruj się w stronę syntezy DDS, tylko że w bascomie raczej nie uzyskasz rewelacyjnych efektów głównie ze względu na ograniczenie prędkości wykonywania programu iteracji akumulatora fazy co przełoży się na spory jitter. Wydaje mi się, że odpowiednią precyzję można by uzyskać dopiero dla 3 bajtowego słowa programującego oraz częstotliwości iteracji co najmniej 20x większej od max użytej częstotliwości.(Wszystko to można dokładnie policzyć). Obliczanie DDS przy 60kHz w bascomie może być cięzko. Jeśli jednak odchyłki fazy sygnału nie będą miały znaczenia, można próbować mniejszej częstotliwości pracy programu. Jesteś pewien że potrzebujesz rozdzielczość strojenia rzędu pojedynczych Hz? W pierwszym poście piszesz o potrzebnych częstotliwościach różnych od siebie o równe 0,1kHz.
  • #11 11160045
    FastProject
    Poziom 28  
    bobeer napisał:
    Nie wiem jak chciałeś uzyskać rozdzielczość strojenia 2Hz przy 1kHz z użyciem timera który ma 8 bit.


    Używałem 16-bitowego Timera1 jak by kolega nie zauważył...

    I tak potrzebuje np wygenerować częstotliwość 1,2kHz +/-1Hz lub 1,8kHz +/- 1Hz i dla kwarcu 8MHz i timera1 z wykorzystaniem OCR1A udało mi się to osiągnąć.
    Ktoś może powiedzieć, że użycie ATmegi162 to przerost formy nad treścią, ale będzie to treść pozbawiona komplikacji i uciekającego czasu, którego nie mam.

    bobeer napisał:
    Jesteś pewien że potrzebujesz rozdzielczość strojenia rzędu pojedynczych Hz? W pierwszym poście piszesz o potrzebnych częstotliwościach różnych od siebie o równe 0,1kHz.


    Nie wiem skąd kolega wytrzasnął to 0,1kHz?
    Generalnie potrzebuje wygenerować kilka częstotliwości z zakresu od 1kHz do 3kHz z dokładnością +/-1Hz i tyle. Ale jednocześnie muszę generować np 1,2kHz (+/-1Hz) i 1,8kHz (+/- 1Hz).
  • #12 11160141
    bobeer
    Poziom 28  
    100Hz wziąłem z
    Cytat:

    - Ocr1a = 2857 (1,4kHz), a w Ocr1b = 3333(1,2kHz) to układ generuje tylko pierwszą częstotliwość z OCR1A, no bo 2957 taktów przychodzi szybciej i TIMER1 się zeruje, a wiec nigdy nie ma przerwania z OCR1B,przez co nigdy nie zmiana się stan końcówki PB.2
    - Ocr1a = 3333(1,2kHz), a w Ocr1b = 2857(1,4kHz), to oba układy generują mniejszą częstotliwość 1,2kHz.

    Że timer 16bit to przeoczyłem, niestety jeśli chcesz to załatwić przez ctc to jak zauważyłeś pozostaje up z dwoma 16bit timerami. W nagrodę będzie można wyłączyć procesor i pozostawić włączone same timerogeneratory ;).

    Przerost nie przerost, dla jednego układu można zaszaleć, ale na większą skalę, to ten problem załatwia zapewne tiny13.
  • #13 11160165
    FastProject
    Poziom 28  
    bobeer napisał:
    Przerost nie przerost, dla jednego układu można zaszaleć, ale na większą skalę, to ten problem załatwia zapewne tiny13.
    No własnie 1 moze 2sztuki takich generatorkow mi trzeba. Tak wiec postawie na Atmega162 ale temat zostawiam otwarty bo może ktos bedzie miał jakis pomysł.
    Juz pisząc na lezaco i z komureczki...doobranoc.
  • #14 11160426
    bobeer
    Poziom 28  
    W ASM rozwiązanie Twojego problemu wygląda następująco:

    Kod: Text
    Zaloguj się, aby zobaczyć kod
  • #15 11160541
    FastProject
    Poziom 28  
    No fajne, dzięki.
    Jak wspomniałem wcześniej potrzebuje jeszcze generować te częstotliwości z rożnymi współczynnikami wypełnienia 25%, 50%, 75%. Ten program w ASM w tej wersji chyba tego nie obsługuje?

    A nie już widzę...to chyba te "pwmF1" prawda?
  • #16 11160917
    LordBlick
    VIP Zasłużony dla elektroda
    bobeer napisał:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Rezonator w MHz, a w przypadku ATtiny13 zewnętrzny generator.
  • #17 11161372
    FastProject
    Poziom 28  
    Słuszna uwaga, ale i tak interpretowałem to jako MHz.
    A dlaczego 16,384MHz...nie lepiej łatwiej dostępny 16,0MHz?
  • #18 11161398
    LordBlick
    VIP Zasłużony dla elektroda
    FastProject napisał:
    A dlaczego 16,384MHz...nie lepiej łatwiej dostępny 16,0MHz?
    Użyj, jakiego chcesz, ale wtedy przelicz sobie samodzielnie, lub eksperymentalnie... ;)
  • #19 11161466
    FastProject
    Poziom 28  
    A dużą trudnością i obciążeniem dla procesora była by operacja sprawdzania 4 pinów uP (DIP-SWITCH 4 pinowy, oczywiście już nie w ATtiny13 a np w atmega8) i w zależności od tych pinów generacja rożnych częstotliwości?

    Czyli zamiast wpisywania ręcznie na początku programu:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Wybierać zawartości Freq1 i Freq2 za pomocą przełącznika DIP...
    Np:
    - DIP=0b0001... f1=1kHz , f2=2kHz
    - DIP=0b1010... f1=1.5kHz , f2=2.5kHz?
  • #20 11161494
    LordBlick
    VIP Zasłużony dla elektroda
    FastProject napisał:
    A dużą trudnością i obciążeniem dla procesora była by operacja sprawdzania 4 pinów uP (DIP-SWITCH 4 pinowy, oczywiście już nie w ATtiny13 a np w atmega8) i w zależności od tych pinów generacja rożnych częstotliwości?
    Jeśli tylko przy włączeniu zasilania lub resecie, to nieduży problem.
  • #21 11161739
    FastProject
    Poziom 28  
    No tak, a jak ograniczył by się zakres i dokładność generacji częstotliwości w przypadku ciągłego monitoringu wybranych pinów procesora i ładowanie nowych wartości obu częstotliwości w przypadku zmiany stanu tych pinów??
  • #22 11161822
    LordBlick
    VIP Zasłużony dla elektroda
    To jest dobre pytanie.. ;) Myślę, że by się to rozjechało, bo algorytm programu opiera się na czymś, co ja nazywam "cyklinowaniem", czyli planowaniem każdego kroku (cyklu) procesora.... ;)
  • #23 11161866
    FastProject
    Poziom 28  
    Może tak może nie, ale przecież zczytywanie pinów, także zajmuje określoną ilość cykli, więc może da się je uwzględnić podczas generowania przebiegu, Np sprawdzać te piny zaraz po ustawieniu portów wyjściowych generatora, a odświeżać rejestry nowymi wartościami częstotliwości w następnym cyklu programu ddsscore?
  • #24 11161936
    LordBlick
    VIP Zasłużony dla elektroda
    FastProject napisał:
    przecież zczytywanie pinów, także zajmuje określoną ilość cykli
    A także pewną ilość cykli, być może niestałą, zajmie ciągła ich interpretacja w pętli syntezy... ;)
    A niech jakiś switch będzie słabo kontaktował, to będzie stabilność...
    Skoro użytkownik ma samodzielnie zmieniać stan przełączników, to wystarczy mu wytłumaczyć, że powinien zmiany zatwierdzić odpowiednim przyciskiem, po cichu podłączonym do Reset... :P
  • #25 11167965
    Fredy
    Poziom 27  
    Ja bym uzyl duzego kwarcu np 20MHz. Zrobilbym przerwanie co 10us, a w przerwaniu dalbym 2 liczniki i 2ify sterujace 2 ma wyjsciami. Potem calosc zestroilbym dodajac nopy i ewentualnie korygujac minimalnie timer . A switche podlaczylbym na przerwania Int aby nie falszowaly mi czestotliwosci.
  • #26 11172552
    bobeer
    Poziom 28  
    Oczywiście że można umieścić ddscore w przerwaniu. Jeśli ktoś chce obsługiwać inne rzeczy poza samą syntezą, to należy ustawić timer na przerwanie np co 50 lub 100 cykli, i pozostaje czas wolny na obsługę programu, a dds sobie żyje "swoim życiem".
    Cytat:

    Potem calosc zestroilbym dodajac nopy i ewentualnie korygujac minimalnie timer

    Jak czas odmierza timer, to nop nie nadadzą się jako coś do korekcji częstotliwości.
  • #27 11177798
    Fredy
    Poziom 27  
    Cytat:

    Potem calosc zestroilbym dodajac nopy i ewentualnie korygujac minimalnie timer

    Jak czas odmierza timer, to nop nie nadadzą się jako coś do korekcji częstotliwości.[/quote]
    Nie chodzi mi o korygowanie chwili wystapienia przerwania,lecz o dokladny moment zmiany stanu portu w procedurze obslugi przerwania.
REKLAMA