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

[bascom] PWM jak obliczyć czas

xamrex 13 Sty 2011 20:25 2597 12
REKLAMA
  • #1 9001590
    xamrex
    Poziom 28  
    Witam,
    Mam taki kod: (dokładnie on jest użytkownika manekinen)

    $regfile = "attiny2313.dat"
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Portd.6 = Output
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.1 , Rs = Portd.0
    
    Config Timer0 = Timer , Prescale = 1
    Enable Timer0
    
    
    
    On Timer0 Software_pwm
    Enable Interrupts
    
    Dim B As Byte
    Dim Reference As Byte
    
    
    Do
    
    
    Cls
    Lcd B
    Waitms 20
    Incr B
    Loop
    
    
    Software_pwm:
    Incr Reference
    If Reference < B Then
    Set Portd.6
    Else
    Reset Portd.6
    End If
    
    Return
    
    
    


    Mniej więcej wiem w jaki sposób jest rozwiązany PWM.
    Mając taki kod, dioda powoli się rozjaśnia, i gdy świeci już na maxa, szybko gaśnie i znowu się rozjaśnia.. i tak w kółko.
    Chciałbym się dowiedzieć w jaki sposób można policzyć czas w którym wypełnienie osiągnie wartość 255(czyli dioda będzie świecić pełną mocą)
    ; czas od wyłączenia diody do jej max. świecenia
    Myślałem, że to zależy od tego:

    Do
    Waitms 20
    Incr B
    Loop

    Dokładnie od polecenia Waitms 20, bo za każdym razem jest zwiększane B, i gdy dojdzie do 255 (to wtedy ma max wartość)


    Lecz zrobiłem sobie testy:
    Że na wyświetlaczu wyświetlam wartość B,
    i jak się okazało, jeśli zamienię
    Config Timer0 = Timer , Prescale = 1
    na
    Config Timer0 = Timer , Prescale = 8
    to wartość B zmienia się szybciej!

    Dlaczego tak się dzieje?
    Przecież działanie programu, powinno być takie samo.
    waitms 20, powinno być za każdym razem 20ms,
  • REKLAMA
  • Pomocny post
    #2 9001778
    piotrva
    VIP Zasłużony dla elektroda
    przerwanie timera wpływa na polecenia z rodziny Wait - powodują one, w zależności od częstości wydłużenie czasu oczekiwania, dlatego trzeba w takim wypadku odmierzać czas używając timera ;-)
  • #3 9001957
    xamrex
    Poziom 28  
    A da się w jakiś sposób policzyć teraz
    jaki czas upłynie od świecenie diody bardzo słabo (B=0), do świecenia diody na 100% (B=255)
    Czy jest to niemożliwe?
  • REKLAMA
  • REKLAMA
  • Pomocny post
    #5 9007200
    slawko_k
    Poziom 35  
    Cytat:
    Lecz zrobiłem sobie testy:
    Że na wyświetlaczu wyświetlam wartość B,
    i jak się okazało, jeśli zamienię
    Config Timer0 = Timer , Prescale = 1
    na
    Config Timer0 = Timer , Prescale = 8
    to wartość B zmienia się szybciej!

    Dlaczego tak się dzieje?

    Może dlatego że jest jest prescale =1 to przerwanie jest wykonywane co 32us czyli w czasie tego waitams 20 trafia się 625 razy podprogram obsługi przerwania. Nie jest on długi ale należy pamietać że na jego początku procek odkłada wszystko na stos a przy zakończeniu wszystko wraca co zajmuje dużo czasu.
    Jeśli dasz prescale=8 to przerwanie masz 8 razy rzadziej czyli w czasie tych 20ms zdarzy się tylko ok 78 ci mniej wydłuża instrukcje waitms 20
  • #6 9008962
    xamrex
    Poziom 28  
    A da się jakoś ustawić te stosy, aby przy prescale =1,
    20ms to było 20ms?
  • #7 9009703
    Quaki
    Poziom 20  
    xamrex juz ci koledzy napisali ze instrukcja typu waitms to instrukcja ktora powinna sie nazywac wait(mniej wiecej)ms bo tak tez dziala wykorzystuje sie ja jesli czas odmierzany ma byc mniej wiecej i nie jest krytyczny dla twojego programu na przyklad mruganie dioda nie wazne czy dioda bedzie mrugac z czasem 200ms czy 202ms i tak tego nie zauwazysz . Jesli chcesz zeby wartosc byla wyliczana dokladnie wykorzystaj drugi timer do podbijania wartosci zmiennej B
    Pozdrawiam
  • #8 9009910
    slawko_k
    Poziom 35  
    zamrex a do czego ty ten pwm chcesz zastosować? bo przy prescale=1 mi ok 31khz wychodzi.
    wiec jeśli do sterowania jakiegoś silnika no to jest to raczej zdecydowanie za dużo.
  • REKLAMA
  • #9 9010298
    xamrex
    Poziom 28  
    slawko, ja PWM używam do sterowania jasnością diody (patrz post1)
    Nie muszę mieć dokładnego czasu (dlatego nie używam jeszcze jednego timera), tylko zastanawaiłem się dlaczego tak się dzieje
    Ddlaczego zmieniając prescaler, wydłuża mi się czas,
    Ale tak jak pisałeś dzieje się tak przez stos?

    Dałoby coś zmienienie opcji HW stack,Soft Stack czy Framesize
  • #10 9010726
    slawko_k
    Poziom 35  
    można wyłączyć odkładanie na stos ale trzeba wtedy ręcznei zadbać o używane rejestry a w przypadku waita to kilka ana pewno jest używanych.

    Jeżeli ty tylko jasnością diody chcesz sterować to daj prescale =64. w zupełności ci to wystarczy i prockowi kupa czasu zostanie na inne bajerki.

    Ogólnie to strasznie skomplikowałeś bardzo prosta sprawę.
    Mogłeś to nawet bez przerwań zrobić
  • #11 9013129
    xamrex
    Poziom 28  
    slawko_k napisał:

    Jeżeli ty tylko jasnością diody chcesz sterować to daj prescale =64. w zupełności ci to wystarczy i prockowi kupa czasu zostanie na inne bajerki.

    O nie,
    Prescale 8 nawet nie starcza

    Gdybym dał 8
    Przy zegarze 8MHz i liczniku Timer0 zliczającym do 256 i prescalerze równym 8, otrzymujemy 3906 przerwań na sekundę do obsługi programowego PWM. 3906 przerwań podzielonych przez 256 bitową rozdzielczość PWM, daje ~14Hz

    I to widać..
    Więc jedynym rozwiązaniem jest ustawienie prescalera na 1.
  • #12 9013636
    slawko_k
    Poziom 35  
    Nie wiem co ty liczysz ale na pewno nie masz o tym zbyt wielkiego pojęcia.

    Cytat:

    Więc jedynym rozwiązaniem jest ustawienie prescalera na 1.

    Skoro się uparłeś no to my tu nic nie poradzimy.

    Oczywiście rozróżniasz gołym okiem każdy z tych 256 poziomów świecenia.
  • #13 9013680
    xamrex
    Poziom 28  
    Ah..
    Jeśli napiszemy taki program (który rozjaśnia diodę)
    $regfile = "attiny2313.dat"
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Portd.6 = Output
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.1 , Rs = Portd.0
    
    Config Timer0 = Timer , Prescale = 1
    Enable Timer0
    
    
    
    On Timer0 Software_pwm
    Enable Interrupts
    
    Dim B As Byte
    Dim Reference As Byte
    
    
    Do
    
    
    Cls
    Lcd B
    Waitms 20
    Incr B
    Loop
    
    
    Software_pwm:
    Incr Reference
    If Reference < B Then
    Set Portd.6
    Else
    Reset Portd.6
    End If
    
    Return 
    

    I prescaler ustawimy ma 8, to będziemy widzieć miganie diody (a tego nie chcemy widzieć) więc prescaler musi być ustawiony na 1

    A liczyłem to na podstaiwe tej storny:
    http://diy.elektroda.eu/lampa-rgb-mylonit-3w/
REKLAMA