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

[BASCOM][8515] a instrukcja servo

michal0408 19 Lip 2008 07:56 2587 1
  • #1 5356591
    michal0408
    Poziom 13  
    witam

    jestem poczatkujacym programista i mam maly problem a mianowicie wszedzie gdzie szukam znajduje gotowe wartosci do obslugi tej instrukcju a ja bym chcial obliczyc sam pod swoje potrzeby w ksiazce znalazlem przyklad sterowania dla kwarca 10mhz i jest tylko napisane ze taki byc powiniene bo wtedy wartosc 100 wpisana do rejestru daje nam 1ms jak obliczac cos takiego dla innych kwarcow ??
    czy to da sie jakos obliczyc czy trzeba dobierac metoda prob i bledow ??

    Proszę zapoznać się z regulaminem p.15 i poprawić treść - wielkie litery , interpunkcja.
    [zumek]
  • #2 5356642
    ZbeeGin
    Poziom 39  
    W instrukcji CONFIG SERVOS jest taki parametr jak RELOAD = xxx. Liczba xxx określa jaki czas w us będzie pomiędzy kolejnymi przerwaniami licznika taktującego generator PWM dla układów serwa. I będzie to rozdzielczość tego układu. Zatem jeśli wpiszesz 10 to SERVOS(1) = 100 da nam 100x10us = 1ms impuls powtarzający się co 20ms na wyjściu podłączonym do serwa. To jest podstawowa zasada działania.

    Aby serwa działały właściwie to taktowanie procesora powinno być dość duże i tu za dolnią graniczną częstotliwość uważa się 8MHz przy rozdzielczości 10us. Dzieje się tak, gdyż sterowanie odbywa się programowo, a kompilator biorąc częstotliwość kwarcu z wewnętrznej zmiennej _XTAL_ tak oblicza wartości licznika (preskaler, przepełnienie) by podaną w RELOAD= rozdzielczość (okres przerwań) otrzymać. Nie zawsze będzie ona prawidłowa z powodu skończonej rozdzielczości ośmiobitowego licznika.
    Potem tak dobiera czasy w PWMach (ilość zliczonych przebiegów) by impulsy powtarzały się co 20ms. W przypadku jednego serwa nie ma większego problemu. Zaś w przypadku np. 5 serwomechanizmów 10MHz może nie wystarczyć i trzeba będzie kwarc zwiększyć by procedury PWM utrzymać w reżimach czasowych.

    Obliczyć się tego z grubsza nie da, gdyż musiałbyś wiedzieć jak kompilator skompilował całe procedury obsługi serwa i obliczyć ile czasu w taktach one zajmują, a im więcej elementów teblicy SERVO tym gorzej (dłuższe przerwanie). Potem pomnożyć to przez 1.5 by mieć czas jeszcze na główny program. Wtedy mógłbyś sprawdzić czy przy danym RELOAD= i kwarcu procesor jeszcze się "wyrabia" w czasie, i przerwania się nie nakładają.
    Np. uzyskanie RELOAD = 1 (1us) przy kwarcu 1MHz jest niemożliwe, gdyż przerwania musiałyby być zgłaszane co każdą instrukcję!
    Dlatego też, im mniejsza wartość RELOAD= lub ilość serw to częstotliwość rezonatora powinna być większa. Przy czym ilość serw ma nieco mniejsze znaczenie niż wartość RELOAD=. Nie warto jednak zmniejszać rozdzieczości poniżej 5 gdyż może braknąć możliwości co do granicznej częstotliwości taktowania danego układu.


    Muszę w tym miejscu napisać, że procedura obsługi SERVOS ma drobny, ale brzemienny w skutkach błąd. Przeładowanie Timera odbywa się nie na początku procedury przerwania tylko na jej końcu. Zatem po każdym przerwaniu czas impulsu się wydłuża i nie ma on dokładnie takiego czasu jak zakładany. :cry: Nawet korekta czasu jaka jest przeprowadzana nie eliminuje całkowicie problemu.
    Dla chcących przeanalizować to dokładnie:

    
    ******* BASCOM *******
    
    $regfile = "m8535.dat"
    $crystal = 10000000
    
    Config Servos = 2 , Servo1 = Portb.0 , Servo2 = Portb.1 , Reload = 10
    'Używamy 2 serwomechanizmy sterowane z precyzją 10 mikrosekund
    
    ******* ASM *******:
    
            .org    TOV0addr
            
            push    r16              ; najpierw zabezpieczymy rejestry na stosie
            push    r24              
            in      r24, SREG        
            push    r24              
            push    r26              
            push    r27              
            push    r25              
            ldi     Xl, 0x60         ; adres licznika SERVOSCNT (zmienna wewnętrzna)
            ldi     Xh, 0x00         ; załaduj do rejestru X
            ld      r24, x+          ; załaduj jego zawartość do pary R24:R25
            ld      r25, x           
            adiw    r24, 1           ; zwiększ o jeden
            st      x, r25           ; i zapisz do zmiennej
            st      -x, r24          
            clr     r16              ; sprawdź czy licznik zawiera wartość BOTTOM
            cpi     r24, 0x01        
            cpc     r25, r16         
            brne    _servos1         ; jeśli nie to omiń procedurę ustawiania stanów
        ;------------- ten obszar rośnie wraz z ilością serwomechanizmów ---
            sbi     PORTB, PB0       ; inaczej ustaw końcówki portów w stan H
            sbi     PORTB, PB1       
        ;-------------------------------------------------------------------
            rjmp    _servos4         ; i kończymy to przejście licznika SERVOSCNT
    
    _servos1:
            cpi     r25, 0           ; czy licznik zliczył już co najmniej 256?
            breq    _servos2         ; nie więc czas sprawdzić i skorygować stany 
            cpi     r24, 0xd0        ; sprawdź czy licznik doliczył już do TOP
            ldi     r16, 0x07        ; (0x07d0 = 2000*9,90us = 19,80ms)
            cpc     r25, r16         
            brcs    _servos4         ; jeśli nie to wychodzimy
            clr     r16              ; inaczej wyzeruj licznik
            st      x+, r16
            st      x, r16
            rjmp    _servos4         ; i koniec tego przejścia
    
        ;------------- ten obszar rośnie wraz z ilością serwomechanizmów ---
    
    _servos2:
            adiw    r26, 2           ; ustaw się na początek tablicy SERVOS()
            ld      r25, x+          ; załaduj pierwszy element
            cp      r24, r25         ; porównaj z młodszą częścią SERVOSCNT
            brcs    _servos3         ; jeżeli nie większe to następny element
            cbi     PORTB, PB0       ; inaczej ustaw PB0 w stan L
    
    _servos3:
            ld      r25, x+          ; załaduj następny element
            cp      r24, r25         ; porównaj z młodszą częścią SERVOSCNT
            brcs    _servos4         ; jeśli nie większe to koniec
            cbi     PORTB, PB1       ; inaczej ustaw PB1 w stan L
        ;-------------------------------------------------------------------
    
    _servos4:
            ldi     r24, 157         ; załaduj stałą do licznika
            out     TCNT0, r24       ; da to okres przerwań 9,90us przy prekalerze = 1
            pop     r25              ; przywróć stan rejestrów
            pop     r27              
            pop     r26              
            pop     r24              
            out     SREG, r24        
            pop     r24              
            pop     r16              
            reti                     ; koniec przerwania
REKLAMA