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

[ATtiny261] Problem z konfiguracją rejestrów PWM.

androot 27 Sty 2011 11:01 2150 10
  • #1 9063494
    androot
    VIP Zasłużony dla elektroda
    Robię przetwornicę na ATtiny261.
    Chcę skonfigurować PWM tak, żeby miałem 2 symetryczne przebiegi na wyjściach OC1D i /OC1D (piny 7, 8) z czasem martwym ok. 200-300ns.

    Udało mi się to zrobić na ATtiny 25/45/85, ale musiałem się przesiąść na coś co ma więcej pinów. W ATtiny261 jest więcej rejestrów, które trzeba ustawić.
    Na początku włączam PLL (potrzebuję: PCK=64MHz, dla uzyskania: 250kHz, 8bit PWM).

    Nie wiem co robię źle, ale PWM na tych wyjściach "skacze" - szybko zmienia się okres przebiegu i jego wypełnienie pomimo, że nigdzie więcej w kodzie nie modyfikuję rejestrów OCR1C i OCR1D.

    Jeśli nie korzystam z wyjść OC1A i OC1B to bity PWM1A i PWM1B mają być 0 (disabled)? Czy mają jeszcze jakieś inne przeznaczenie?

    Kod jest w assemblerze, ale to chyba bez znaczenia bo chcę spytać tylko o konfigurację rejestrów.

    
    ;PLL ON --------------------------------------------------------
    ldi A, 0b00000010                  ; turn on PLL
    out PLLCSR, A                       ;
    _Waiste_us 10000                  ; delay 100us for stabilize PLL
    
    ldi A, 0b00000110                   ; turn on Timer/counter clock source
    out PLLCSR, A                        ;
    
    
    ;PWM + DEAD TIME GENERATOR -------------------------------------
    ldi A, 0b00000000                   ; COM1A1, COM1A0, COM1B1, COM1B0, FOC1A, FOC1B, PWM1A, PWM1B
    out TCCR1A, A                       ;
    
    ldi A, 0b00000001                   ; PWM1X, PSR1, DTPS11, DTPS10, CS13, CS12, CS11, CS10 (dead time - no division, clock: PCK)
    out TCCR1B, A                       ;   
             
    ldi A, 0b00000101                   ; COM1A1S, COM1A0S, COM1B1S, COM1B0S, COM1D1, COM1D0, FOC1D, PWM1D (OC1D and /OC1D, PWM1D enable)
    out TCCR1C, A                       ;
       
    ldi A, 0b00000001                   ; FPIE1, FPEN1, FPNC1, FPES1, FPAC1, FPF1, WGM11, WGM10 (Phase correct PWM)
    out TCCR1D, A                       ;
       
    ldi A, 0b01000100                   ; Configure: (7-4) dead time H, (3-0) dead time L
    out DT1, A                            ;   
             
    ldi A, 255                              ; 250kHz, 8-bit
    out OCR1C, A                         ;
    
    ldi A, 30                              ; Przkładowo
    out OCR1D, A                         ;
    
  • Pomocny post
    #2 9068384
    hotdog
    Poziom 26  
    [ATtiny261] Problem z konfiguracją rejestrów PWM.

    Wynika z tej tabelki że twój timer obecnie pracuje w trybie Normal

    Dodano po 2 [minuty]:

    Chociaż ogólnie to trochę dziwnie napisali bo w sumie nie jest napisane czy chodzi O PWM1A, PWM1B, o jakąś funkcję logiczną między nimi (OR, AND). Więc można tylko wróżyć :)
  • #3 9072332
    androot
    VIP Zasłużony dla elektroda
    Dzięki za zainteresowanie :)

    No jest to dziwne, bo jak teraz sprawdzałem to PWM1A/B nie ma znaczenia bo mam włączone PWM1D i z wyjść "D" korzystam.
    Wydaje mi się, że jest to zrobione ctrl-c ctrl-v z dokumentacji procka, który nie miał PWM1D.

    Problem chyba jest hardware'owy i leży w PLL. Na ATtiny85 miałem stabilne 250kHz, a tutaj skacze mi 200-240kHz. Zasilany jest z 3,3V - wg. dokumentacji nie powinno być problemów. Masz może pomysł co z tym zrobić? Może kupię wersję ATtiny261A. Może to bug jakiś?
  • #4 9073769
    hotdog
    Poziom 26  
    Czyli pływa cały okres? Jeżeli tak to wychodzi że PLL jest "kiepski". Sprawdź stabilność tej właśnie częstotliwości - ustaw timer w trybie normal i zrób tylko toogle w przepełnieniu timera i sprawdź czy częstotliwość jest stabilna.

    Opisz jeszcze dokładniej jak to skacze? Jak zmienisz wypełnienie, czy normalnie się zmienia przy tych samych ustawieniach w czasie?

    Pozdrawiam
  • #5 9076098
    androot
    VIP Zasłużony dla elektroda
    Tak pływ cały okres. Pomogło wyłączenie przerwania od ADC!
    Nigdzie w tym przerwaniu nie zmieniam zawartości jakiegokolwiek z rejestrów od timera 1.
    Potrzebuję ADC, więc będę musiał dojść gdzie tkwi problem.
  • #6 9076252
    hotdog
    Poziom 26  
    No możesz w ostateczności dać ADC w głównym.

    Ogólnie to cholernie ciekawe. Ja bym sprawdził w nast. kolejności czy problem wynika z PLL. Czyli przestaw timer z PLL na wewnętrzny zegar i sprawdź czy częstotliwość dalej pływa.
  • Pomocny post
    #7 9077358
    Andrzej__S
    Poziom 28  
    Atmel napisał:

    • Bit 2- PCKE: PCK Enable
    ...
    It is safe to set this bit only when the PLL is locked i.e the PLOCK bit is 1.
    ...

    Zgodnie z powyższym spróbuj może sprawdzić po:
    
    ldi A, 0b00000010                  ; turn on PLL 
    out PLLCSR, A  
    _Waiste_us 10000                  ; delay 100us for stabilize PLL
    

    czy bit PLOCK jest ustawiony, ewentualnie poczekaj na jego ustawienie przed włączeniem PCKE. Z drugiej strony nie wiem, jaki to by mogło mieć związek z przerwaniami od ADC, ale chyba nie zaszkodzi spróbować :)
  • #8 9077559
    androot
    VIP Zasłużony dla elektroda
    OK, problem chyba rozwiązany :)

    Miałem wpisany niewłaściwy adres przerwania od ADC. Był taki jak w ATtiny85 (0x0008) zamiast 0x000B. 0x0008 w ATtiny261 to przerwanie od USI_OVF.

    Teraz PWM wydaje się stabilny (jak na możliwości mojego oscyloskopu RIGOL :)

    Dziękuję za pomoc, problem był prozaiczny, ale nie zawsze takie "wałki" szybko wychodzą :)
  • Pomocny post
    #9 9077605
    LordBlick
    VIP Zasłużony dla elektroda
    I tu właśnie wyszło szydło z worka - nie wpisuje się wartości numerycznych adresów, tylko nazwy z plików nagłówkowych. Wystarczy zajrzeć do plików XXXdef.inc Tak samo asembler od Atmela przyjmuje wszystkie operatory bitowe typu :
    ldi A, 1<<PLLE                  ; turn on PLL
    out PLLCSR, A                       ;
    Czyż tak nie jest czytelniej i trudniej o pomyłkę ? Czyż dany kod bez zmian nie zadziała na dowolnym procku z tym samym peryferium ? ;)
  • #10 9078056
    androot
    VIP Zasłużony dla elektroda
    Light-I napisał:
    I tu właśnie wyszło szydło z worka - nie wpisuje się wartości numerycznych adresów, tylko nazwy z plików nagłówkowych. Wystarczy zajrzeć do plików XXXdef.inc Tak samo asembler od Atmela przyjmuje wszystkie operatory bitowe typu :
    ldi A, 1<<PLLE                  ; turn on PLL
    out PLLCSR, A                       ;
    Czyż tak nie jest czytelniej i trudniej o pomyłkę ? Czyż dany kod bez zmian nie zadziała na dowolnym procku z tym samym peryferium ? ;)


    Mało programuję (w C wogóle) - stare przyzwyczajenia z '51.
    Poprawię kod wg. Twoich rad :)
  • Pomocny post
    #11 9078180
    Andrzej__S
    Poziom 28  
    androot napisał:

    Miałem wpisany niewłaściwy adres przerwania od ADC. Był taki jak w ATtiny85 (0x0008) zamiast 0x000B. 0x0008 w ATtiny261 to przerwanie od USI_OVF.

    Dobrym rozwiązaniem jest wyznaczenie domyślnego wektora dla nieużywanych przerwań (tak jak to jest zrobione w avr-gcc). Na początku programu dla wszystkich nieobsługiwanych przerwań definiujesz skok:
    
       rjmp default_vector
    

    a później w obsłudze domyślnego wektora:
    
    default_vector:
       reti
    

    W takim przypadku, kiedy się pomylisz z adresem wektora (tak jak to zrobiłeś) lub przypadkowo włączysz jakieś niechciane przerwanie, program skoczy do domyślnego wektora, wyzeruje flagę tego przerwania i powróci do normalnego wykonywania programu. Dzięki temu łatwiej jest znaleźć źródło problemu. bo program się nie resetuje. W Twoim przypadku, po zdeklarowaniu obsługi przerwania pod nieprawidłowym adresem, po prostu nie działałaby Ci prawidłowo obsługa ADC, dzięki czemu prawdopodobnie szybciej zlokalizowałbyś źródło problemu.
REKLAMA