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

[Attiny2313][Bascom] Dwa Timery na przerwaniach na raz

maciejbilu 29 Lis 2009 20:04 2275 7
REKLAMA
  • #1 7324905
    maciejbilu
    Poziom 11  
    Witam,
    Mam problem z uruchomieniem dwóch timerów.
    Timer0 ma obsługiwać przerwanie pochodzące z INT1 (Signal1), natomiast Timer1 (Signal0) z INT0 (ale może być odwrotnie). Każdy z timerów ma wykryć impuls PWM większy od 1,5ms i zapalić lub zgasić diodę / diody.
    Po wgraniu poniższego kodu, diodki migają chaotycznie, nie ma żadnej reakcji na zmianę szerokości impulsu.
    W przypadku kiedy zostaną usunięte wszelkie wzmianki dotyczące Timera0 i funkcji z nim związanych, Timer1 (Signal0) działa poprawnie.
    Kod wkleiłem już bez "wstępu"

    Biedę wdzięczny za pomoc w ukierunkowaniu i rozwiązaniu problemu.

    
    Config Timer1 = Timer , Prescale = 1                      
    Config Timer0 = Timer , Prescale = 1                        
    
    Enable Int0
    Enable Int1
    Enable Timer1
    Enable Timer0
    Enable Interrupts
    
    Dim E As Word
    Dim F As Word
    Dim X2 As Word
    
    Dim G As Byte
    Dim H As Word
    Dim I As Word
    Dim X1 As Word
    
    'INT0
    On Int0 Signal0
    Start Timer1
    Load Timer1 , 0
    
    
    'INT1
    On Int1 Signal1                                          
    Start Timer0
    Load Timer0 , 0
    
    Do
    
    If X1 > 1410 Then                                           
    set Portb.0
    set Portb.1
    set Portb.2
    set Portb.4
    set Portb.5
    set Portb.6
    set Portb.7                                   
    End If
    
    If X1 < 1410 Then                                           
    Reset Portb.0
    Reset Portb.1
    Reset Portb.2
    Reset Portb.4
    Reset Portb.5
    Reset Portb.6
    Reset Portb.7                                               
    End If
    
    Loop
    
    Signal0:
    X2 = 0
    E = 0
    F = 0
    
    If Pind.2 = 1 Then
    E = Timer1
    Bitwait Pind.2 , Reset
    F = Timer1
    X2 = F - E
    
    If X2 > 1410 Then                                           'jezeli impuls dluzszy niz 1,5 ms
    Set Portb.3                                                 'zapalam diode
    End If
    
    If X2 < 1410 Then                                           'jezeli impuls krotszy niz 1,5 ms
    Reset Portb.3                                               'gaszę diode
    End If
    
    End If
    
    Signal1:
    X1 = 0
    G = 0
    H = 0
    
    If Pind.3 = 1 Then
    G = Timer0
    Bitwait Pind.3 , Reset
    H = Timer0
    X1 = H - G
    End If
    
    Return
    End
  • REKLAMA
  • #2 7324982
    mirekk36
    Poziom 42  
    Pierwsza z pierwszych rzeczy jakich musisz się nauczyć to pisać programy do obsługi przerwań. Bez tego będziesz miał ciągle podobne albo i gorsze problemy.

    Podstawowa zasada jest taka, że kod obdługi przerwania MUSI się wykonywać maksymalnie szybko. Nie można tam wstawiać żadnych długo trwających procedur typu Wait, Wiatms czy np obsługi LCD

    wiem wiem, ty tego tu nie masz

    ale za to masz coś co powala przerwania na nogi - Bitwait . To już jest morderstwo dla przerwań i całego programu.
  • REKLAMA
  • #3 7325517
    maciejbilu
    Poziom 11  
    Ok,
    Rozumiem, ale po pierwsze: polecenie bitwait musi być aby zmierzyć szerokość impulsu.
    Po drugie: działało bezproblemowo gdy był tylko jeden licznik (jedno przerwanie).
    Program wpadał w jeden z dwóch stanów, gdy X2>1,5ms lub gdy X2<1,5ms.

    Co jest nie tak, co źle napisałem ?
  • REKLAMA
  • #4 7325620
    DonQuijote88
    Poziom 14  
    Koledzy, nie wiem jak to jest w Attiny, ale spotkałem się z dwiema rzeczami w innych uC:
    1. Timery mają własne przerwania, czyli nie musisz zajmować żadnego innego przerwania, które może Ci się przydać do czegoś innego.
    2. Jest coś takiego jak priorytet przerwań, zatem jeden z timerów będzie ważniejszy, jeśli obydwa naraz wygenerują przerwanie.
  • REKLAMA
  • #5 7325918
    mirekk36
    Poziom 42  
    maciejbilu --> powiem więc ci inaczej - trzeba to całkowicie inaczej napisać i zapewniam cię że nie trzeba wykorzystywać Bitwait. Poczytaj sobie nawet na elektrodzie o wykorzystywaniu tzw FLAG w przerwaniach - to może coś ci się rozjaśni - bo na razie to niestety brniesz w ślepy zaułek - w ogóle nie rozumiejąc podstaw i zasad działania przerwań. Stąd wg ciebie program ci "normalnie" działał gdy miałeś tylko jedno przerwanie. Eeeeh ciężko to tak w dwóch zdaniach wytłumaczyć niestety dlatego odsyłam do książek.

    DonQuijote88 napisał:
    Koledzy, nie wiem jak to jest w Attiny, ale spotkałem się z dwiema rzeczami w innych uC:
    1. Timery mają własne przerwania, czyli nie musisz zajmować żadnego innego przerwania, które może Ci się przydać do czegoś innego.
    2. Jest coś takiego jak priorytet przerwań, zatem jeden z timerów będzie ważniejszy, jeśli obydwa naraz wygenerują przerwanie.


    no ja raczej przyznam ci rację co do początkowej części twojej wypowiedzi czyli:
    DonQuijote88 napisał:
    Koledzy, nie wiem jak to jest w Attiny,


    rzeczywiście nie wiesz - i niestety mieszasz troszkę pojęcia a domyślam się, że pisząc tu o priorytetach przerwań masz może nawet na myśli takie priorytety przerwań jak w procesorach rodziny 8051 - które mogą być jeszcze dodatkowo ustawiane programowo.

    A przerwania można w AVRach używać nawet wszystkie naraz i nawet tak, żeby w trakcie jednego dochodziło do kolejnego przerwania....
  • #7 7326010
    Konto nie istnieje
    Poziom 1  
REKLAMA