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

Pomiar czasu ATmega8. Dlaczego to nie działa? Listing.

adrian408 12 Lut 2011 13:56 1908 21
REKLAMA
  • #1 9140462
    adrian408
    Poziom 16  
    Witam. Chciałbym zmierzyć czas jaki występuje pomiedzy dwoma stanami tzn. Jeżeli zasłaniam transoptor to chciałbym żeby układ zaczął liczyć czas a kończy liczyć kiedy go odsłaniam. Napisałem kod ale nie chce coś działać.
    Oto ten kod:
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Rs = Portb.1 , E = Portd.0 , Db7 = Portd.1 , Db6 = Portd.2 , Db5 = Portd.7 , Db4 = Portb.0
    
    Cursor Off
    
    Dim Wynik As Single
    
    Config Timer1 = Timer , Edge = Rising
    
    
    Do
    If Pind.5 = 1 Then
    
       Timer1 = 0
       Start Timer1
    
       Do
       Loop Until Pind.5 = 0
    
       Stop Timer1
    
    
    
       Wynik = Timer1
    
    
    
       Cls
    
       Lcd Wynik ; " s"
    End If
    
    Loop
    
  • REKLAMA
  • #2 9140724
    pawel_mr
    Poziom 15  
    Nie widzę globalnego włączenia przerwań, nie pamiętam Bascoma ale chyba trzeba było użyć Enable Interrupts.
  • REKLAMA
  • #3 9140755
    adrian408
    Poziom 16  
    Użyłem teraz Enable Interrupts ale nadal nie chce ruszyć
  • #4 9140782
    pawel_mr
    Poziom 15  
    Jeszcze chyba potrzebne Enable Timer1.
    Poza tym, nie wiem po co masz ustawiane Edge, tu nie chodzi o wyzwalanie zboczem przerwania zewnętrznego. Poza tym nie definiujesz preskalera i po wyświetleniu wyniku warto byłoby wyzerować timer bo zacznie liczyć od tego co skończył, chyba, że tak chcesz.
  • #5 9140785
    tadzik85
    Poziom 38  
    zła konfiguracja timera.
  • #6 9140856
    adrian408
    Poziom 16  
    Zrobiłem coś takiego i nadal nic
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Rs = Portb.1 , E = Portd.0 , Db7 = Portd.1 , Db6 = Portc.4 , Db5 = Portd.7 , Db4 = Portb.0
    
    Cursor Off
    
    Dim Wynik As Single
    
    Config Timer1 = Timer
    
    Enable Interrupts
    
    Enable Timer1
    
    
    Do
    If Pind.5 = 1 Then
    
       Timer1 = 0
       Start Timer1
    
       Do
       Loop Until Pind.5 = 0
    
       Stop Timer1
    
    
    
       Wynik = Timer1
    
    
    
       Cls
    
    
       Lcd Wynik ; " s"
    
    End If
    
    Loop
    
  • #7 9140890
    pawel_mr
    Poziom 15  
    Dopisz jeszcze tak:
    Config Timer1 = Timer , Prescale = 1
    lub Prescale=8 lub Prescale=64
    Domyślnie chyba atmega ma wyłączony dzielnik czyli nie podaje sygnału zegarowego na licznik.
    A w ogóle działa Ci ten transoptor, program dochodzi do wyświetlania na LCD?
  • #8 9140926
    adrian408
    Poziom 16  
    Dodałem Prescaler=1 i coś ruszyło tzn zlicza mi jakieś liczby całkowite. Jak zrobić by podawało mi czas w sekundach?

    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Rs = Portb.1 , E = Portd.0 , Db7 = Portd.1 , Db6 = Portc.4 , Db5 = Portd.7 , Db4 = Portb.0
    
    Cursor Off
    
    Dim Wynik As Single
    
    Config Timer1 = Timer , Prescale = 1
    
    Enable Interrupts
    
    Enable Timer1
    
    
    Do
    If Pind.5 = 1 Then
    
       Timer1 = 0
       Start Timer1
    
       Do
       Loop Until Pind.5 = 0
    
       Stop Timer1
    
    
    
       Wynik = Timer1
    
    
    
       Cls
    
    
       Lcd Wynik ; " s"
    
    
    End If
    
    Loop
    
  • #9 9140934
    piotrva
    VIP Zasłużony dla elektroda
    1. dodaj timer programowy
    2. pomyśl, jaki jest związek wartości timera, ilości przerwań, które wystąpią, częstotliwości zegara, prescalera i czasu jaki upłynął...
  • #10 9140960
    pawel_mr
    Poziom 15  
    Poczytaj o Timer1, to jest licznik 16 bitów, wiesz jaki masz zegar, wiesz jaki ustawiasz preskaler. Możesz na tej podstawie obliczyć ile cykli przypada na jedną sekundę. Zależy ile tych sekund chcesz liczyć bo musisz dobrać tak preskaler aby licznik Ci się nie przepełniał bo będziesz miał złe wyniki.
    I nadal nie widzę zerowania timera po wyświetleniu. W takim przypadku kolejny wynik będzie sumą obecnego i poprzednich wiec na pewno licznik się przepełni.
    Link
  • #11 9140976
    adrian408
    Poziom 16  
    Z tego co wnioskuje to muszę zliczać ilość przepełnień Timera bo inaczej będzie mi się on nadpisywał tak? Czas chciałbym liczyć np do 5 sekund z dokładnością np 0,1s
  • REKLAMA
  • #12 9140994
    pawel_mr
    Poziom 15  
    Tak, możesz liczyć ilość przepełnień, musisz dodać obsługę przerwań od Timera i tam inkrementować zmienną. Licznik ustaw tak, żeby przepełniał się co 0,1s. Wtedy nie musisz przeładowywać timera.
  • #13 9141014
    adrian408
    Poziom 16  
    Czuje że nie podołam temu.. Czytam teraz coś o Timerze1 ale jak narazie to czarna magia do mnie
  • #14 9141081
    pawel_mr
    Poziom 15  
    Nie ma się co poddawać. Prędzej czy później i tak będziesz musiał używać przerwań i liczników bo bez tego większość programów robi się zagmatwana o ile nie niemożliwa do napisania. W necie jest dużo przykładów, Bascom jest o tyle prosty, że nie grzebiesz po rejestrach. Timer już masz, dodatkowa linia konfiguracji i kawałek kodu da Ci obsługę przerwania (On Timer1......). W kodzie obsługi przerwania wstawiasz zwiększanie zmiennej i już masz licznik. Z preskalerem popróbuj różnych wartości, zobacz co Ci będzie zliczał.
  • #15 9141125
    adrian408
    Poziom 16  
    Nie czekam na przykład a tym bardziej na gotowca. Poddaje się
  • #17 9141403
    adrian408
    Poziom 16  
    Transoptor działa bo napisałem sobie prosty programik który pokazuje mi aktualny stan transoptora na LCD. W linku który mi Pan podał jest to wszystko zagmatwane tak ze trudno mi to rozgryźć
  • REKLAMA
  • #18 9141694
    Fredy
    Poziom 27  
    Spróbuj tak:
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Rs = Portb.1 , E = Portd.0 , Db7 = Portd.1 , Db6 = Portc.4 , Db5 = Portd.7 , Db4 = Portb.0
    
    Cursor Off
    
    
    Dim licznik as word
    
    Config Timer1 = Timer , Prescale = 16
    On timer1 przerwanie
    
    Enable Interrupts
    
    Enable Timer1
    
    
    Do
    If Pind.5 = 1 Then
    
       Timer1 = 0
        licznik=0
       Start Timer1
    
       Do
       Loop Until Pind.5 = 0
    
       Stop Timer1
       Cls
       Lcd licznik ; " s"
    
    End If
    
    Loop
    Przerwanie:
    
    Incr licznik
    
    Return
    
    


    powinno ci zliczac prawie co sekunde, jeśli będzie zbyt mało dokładnie to należy skorygować jeszcze preskaler i wstepnie ładowac licznik.
  • #19 9141776
    adrian408
    Poziom 16  
    Zmodyfikowałem swój program i teraz tak. W moim programie jeden cykl trwa 64us tak? Czyli przepełnienie Timera1 nastąpi po 4,194304 sekundy? Dobrze rozumuje?
    Oto kod:
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Rs = Portb.1 , E = Portd.0 , Db7 = Portd.1 , Db6 = Portc.4 , Db5 = Portd.7 , Db4 = Portb.0
    
    Cursor Off
    
    Dim Wynik As Single
    
    
    Config Timer1 = Timer , Prescale = 64
    
    Enable Interrupts
    
    Enable Timer1
    
    
    Do
    If Pind.5 = 1 Then
    
       Timer1 = 0
       Start Timer1
    
       Do
       Loop Until Pind.5 = 0
    
       Stop Timer1
    
       Wynik = Timer1 * 0.000064
    
    Cls
    Lcd Wynik ; " s"
    
    End If
    
    Loop
    Return
    
  • #20 9141881
    Fredy
    Poziom 27  
    Po co uruchamiasz przerwania jak z nich nie korzystasz?
    Więc musisz sie zecydować, albo robisz przerwania w których liczysz przepłnienia, albo idziesz tą drogą co podałes u góry. W tym rozwiązaniu to zauważ że możesz mierzyć czas ale tylko do wartości gdy licznik się całkiem przpełni. Bedzie to około 5sek. Dłuższe czasy spowodują powstanie błedów.

    Zrób tak jak pisałem ci u góry i spróbuj zrozumieć co to jest przerwanie - uwierz mi warto.

    I jeszcze jedno - użycie liczb zmiennoprzecinkowych to ogromne zwiększenie kodu wynikowego. Warto tego unikać , a w Twoim przypadku da sie to zrobić bez problemu.
  • #21 9141904
    adrian408
    Poziom 16  
    Wgrałem Twój program Fredy ale nic nie rusza. Żadnej zmiany na wyświetlaczu
  • #22 9142064
    Fredy
    Poziom 27  
    a jakie czasy mierzysz? W tym programie jest rozdzielczość około 1sek .
    Dla ciekawostki zmień preskaler na 1
REKLAMA