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][atmega8]zegar widmowy- podział obszaru wyświetlania

zuraf 30 Lis 2009 21:59 2377 7
REKLAMA
  • #1 7329797
    zuraf
    Poziom 14  
    Witam.

    Projektuje właśnie zegar widmowy i mam do rozwiązania następujący problem... Wyświetlanie zamierzam zrealizować dzieląc "obszar rysowania" na n równych częsci. Stabilizację obrazu zrobiłem za pomocą halotronu podłączonego do INT0. W przerwaniu ustawiana jest flaga rozpoczęcia wyświetlania a opóźnienia generowane są fukncją waitms... Właśnie to chcę zmienić. W przerwaniu INT0 chcę mierzyć okres obrotu. To akurat jest banalne, ale w jaki sposób podzielić ten czas na n równych odcinków i generować przerwania? Próbowałem zaprządz do tego drugi Timer, ale nie mogłem go zmusić do współpracy. Próba przeliczenia danych z pomiaru obrotu i przeliczenia ich do ms też kiepsko wypada...


    Jaknarazie naklepałem coś takiego:

    $crystal = 16000000
    $regfile "m8def.dat"
    
    
    Config Timer0 = Timer , Prescale = 1024
    
    Config Int0 = Rising
    On Int0 Poz
    Enable Int0
    Enable Interrupts
    Enable Timer0
    
    Config Portc = Output
    Config Portb.2 = Output
    Config Portb.1 = Output
    Config Portd.2 = Input
    Config Portb.0 = Output
    Set Portd.2
    
    Dim A As Byte
    Dim T As Word
    Dim W As Single
    Dim U As Word
    A = 1
    Do
    
    
    If T = 1 Then
    T = 0
    Do
    
    
    
    
    Portc = Lookup(a , Tab)
    Portb = Lookup(a , Tab2)
    
    Waitms 1
    Incr A
    If A = 10 Then
    A = 0
    Portb = 0
    Portc = 0
    
    End If
    Loop Until A = 0
    End If
    
    
    Loop
    
    Poz:
    Stop Timer0
    U = Timer0
    Timer0 = 0
    T = 1
    Start Timer0
    Return
    
    
    
    
    
    
    Tab:
    Data &B00000001 , &B00000011 , &B00000011 , &B00000101 , &B00000101
    Data &B00001001 , &B00001001 , &B00010001 , &B00111111 , &B00000001
    
    Tab2:
    Data &B00000000 , &B00000000 , &B00000000 , &B00000000 , &B00000000
    Data &B00000000 , &B00000000 , &B00000000 , &B00000110 , &B00000000


    Co byscie radzili?
  • REKLAMA
  • #2 7329959
    Pittt
    Poziom 32  
    Operuj cały czas na zliczonych taktach, nie przeliczaj ich na ms. Licz takty i odliczaj takty.
  • REKLAMA
  • #3 7330265
    zuraf
    Poziom 14  
    No właśnie jak odliczać te takty... Próbowałem za pomocą timera1 generować odpowiednie odcinki, ale już od pewnego czasu, nie wiedzieć czemu, wpisywanie wartości do licznika nie działa jak powinno. Ogólnie chodzi o to że przy zmierzonej częstotliwości obrotów np 10hz, wygenerować np 1000Hz...
  • REKLAMA
  • #4 7331661
    11111olo
    Poziom 42  
    A nie prościej liczyć to za pomocą Timera1 czyli na sekundę ma być np. wyświetlonych 50 obrazów i każdy z nich zawiera np. 10 części.
    Daje nam to 500 przerwań na sekundę.
    W przerwaniu Timer1 ustawiasz za każdym razem początkową wartość timera i ustawiasz jakąś flagę. Możesz również dodać zwiększanie licznika od tego co ma być wyświetlane.
    W programie głównym za pomocą Lookup wpisujesz wartości na odpowiednie porty to co ma być wyświetlane, korzystając ze zmiennej umieszczonej w przerwaniu Timer1.
  • REKLAMA
  • #5 7333587
    zuraf
    Poziom 14  
    Problem właśnie polega na tym że to nie nie chce działać jak powinno. Timer jakoś dziwnie reaguje na zmienne wpisywane do niego.

    Dodano po 49 [minuty]:

    Problem rozwiązałem wykorzystując rejestr porównania, teraz tylko zmusić oba timery do współpracy:)

    $crystal = 16000000
    $regfile "m8def.dat"
    
    
    Config Timer0 = Timer , Prescale = 8
    Config Timer1 = Timer , Prescale = 8 , Compare A = Toggle , Clear Timer = 1
    Compare1a = 15000
    
    
    Config Int0 = Rising
    On Int0 Poz
    Enable Int0
    Enable Interrupts
    Enable Timer0
    
    Config Portc = Output
    Config Portb.2 = Output
    Config Portb.1 = Output
    Config Portd.2 = Input
    Config Portb.0 = Output
    Set Portd.2
    
    Dim A As Byte
    Dim T As Word
    Dim W As Single
    Dim U As Word
    A = 1
    Do
    
    
    If T = 1 Then
    T = 0
    Do
    
    
    
    
    Portc = Lookup(a , Tab)
    Portb = Lookup(a , Tab2)
    
    
    
    Incr A
    If A = 10 Then
    A = 0
    Portb = 0
    Portc = 0
    
    End If
    Loop Until A = 0
    End If
    
    
    
    
    
    
    Loop
    
    Poz:
    Stop Timer0
    U = Timer0
    Timer0 = 0
    T = 1
    Start Timer0
    Return
    
    
    
    
    
    
    Tab:
    Data &B00000001 , &B00000011 , &B00000011 , &B00000101 , &B00000101
    Data &B00001001 , &B00001001 , &B00010001 , &B00111111 , &B00000001
    
    Tab2:
    Data &B00000000 , &B00000000 , &B00000000 , &B00000000 , &B00000000
    Data &B00000000 , &B00000000 , &B00000000 , &B00000110 , &B00000000
  • #6 7334057
    landy13
    Poziom 31  
    Spróbuj tak:
    Założenia:
    1. Obroty silnika 1500/min. czyli 25/s. czyli jeden obrót=40ms
    2. Wyświetlanie trwa na 90° wycinku koła czyli 10ms
    3. Obszar wyświetlania podzielony na 10 stref, każda 1ms
    4. Kwarc 16MHz

    Wtedy konfigurujesz
    Config Timer1 = Timer , Prescale = 1 
    i natychmiast go zatrzymujesz:W przerwaniu od Int0 tylko go uruchamiasz
    Poz
       Timer1 = 49536
       Start Timer1
    Return
    Potem w obsłudze przerwania od Timer1:
    Obs_przerw_Timer1
       Timer1 = Timer1 + 49536
       Incr Sektor
       If Sektor > 9 Then
          Sektor = 0
          Stop Timer1
       End If
    Return
    a w pętli głównej zależnie od wartości flagi Sektor wyświetlasz co potrzeba.
  • #7 7334609
    zuraf
    Poziom 14  
    Nie wiem czy dobrze rozumiem, bo już pora późnawa, ale to chyba nie przejdzie. Nie można założyć że obroty są stałe, i właśnie wartość wpsywana do timera, czy też rejestru porównania musi być zależna od prędkości obrotowej. Przerwanie od INT0 ma dwojaką fukcję- służy do pomiaru prędkości obrotowej i stabilizacji obrazu, by nie "pływał".
  • #8 7336334
    landy13
    Poziom 31  
    zuraf napisał:
    Nie można założyć że obroty są stałe
    No cóż - sądziłem. że można. Nie wiem jaki masz silnik ani jakie zasilanie, ale przy stałym obciążeniu i stabilnym zasilaniu wahania prędkości są znikome. Także duży moment bezwładności "śmigła" z układem działa jak koło zamachowe - stabilizująco. Ale jeśli cyfry na wyświetlaczu muszą "dokładnie trzymać wymiar" nic nie stoi na przeszkodzie by czasem jednego obrotu - zmienna U - korygować wartość ładowaną do Timera1 (zapewne po przeskalowaniu).
REKLAMA