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 trwania stanu niskiego na Atmega8

grala1 15 Sty 2011 22:04 1652 2
REKLAMA
  • #1 9011367
    grala1
    Specjalista grupy V.A.G.
    Witam.
    Jeżeli nie ten dział to przepraszam i proszę o przeniesienie do odpowiedniego działu.
    Napisałem program do pomiaru czasu trwania stanu niskiego.
    $regfile = "m8def.dat"
    $crystal = 16000000
    Config Lcd = 16 * 2
    
    Enable Interrupts
    
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Timer1 = Timer , Prescale = 64       'maks=0,261s, min=0,000004s
    Enable Timer1
    
    Config Int0 = Falling
    On Int0 Poczatek
    Enable Int0
    
    Stop Timer1
    Timer1 = 0
    
    Dim Wynik As Word
    
    Dim Flaga As Bit
    Dim Wynikczas As Single
    
    Cls
    Cursor Off
    
    Do
    Locate 1 , 1
    Lcd Wynikczas ; Spc(6)
    
    Waitms 100
    
    Loop
    End
    
    Poczatek:
    
    If Flaga = 0 Then
    Load Timer1 , 0
    Start Timer1
    Config Int0 = Rising
    Else
    Stop Timer1
    Wynik = Timer1
    Wynikczas = Wynik * 0.000004
    Load Timer1 , 0
    Config Int0 = Falling
    End If
    
    Toggle Flaga
    Return

    Przy pomiarze dłuższych czasów np. 0,5s (wcześniej był inny prescaler więc mogłem mierzyć dłuższe czasy) na NE555 nie było żadnych problemów.
    Zrobiłem generatorek na drugim uC.
    $regfile = "m8def.dat"
    $crystal = 4000000
    Config Pinb.1 = Output
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Disconnect , Prescale = 8
    
    Config Portd = Input
    
    Config Portd.0 = Output
    Config Portd.1 = Output
    Config Portd.2 = Output
    Config Portd.3 = Output
    Config Portd.4 = Output
    
    Do
    Set Portd.0
    Set Portd.1
    Set Portd.2
    Set Portd.3
    Set Portd.4
    
    If Pind.0 = 0 Then
    Pwm1a = 50
    End If
    
    If Pind.1 = 0 Then
    Pwm1a = 100
    End If
    
    If Pind.2 = 0 Then
    Pwm1a = 150
    End If
    
    If Pind.3 = 0 Then
    Pwm1a = 200
    End If
    
    If Pind.4 = 0 Then
    Pwm1a = 250
    End If
    
    Loop
    End
    Return

    Po spięciu ich ze sobą na wyświetlaczu wynik jest "przebijany" przez jakąś liczbę.
    Tzn np. przy PWM=200 otrzymuję czas 0,00079... na zmianę z 0,999 lub inna wartością. Można powiedzieć że na 10 wyników wyświetlanych w ciągu sekundy 7 jest poprawnych a 3 są "z księżyca".
    Wydaje mi się że częściej wynik jest "przebijany" przy niższych wartościach PWM.
    W czym może być problem i jak to poprawić?
    Może coś z fusami? Przestawiłem tylko CKTOP i ustawiłem zewnętrzny kwarc 16MHz.
    Nie wiem czy to coś zmienia ale oba uC to ATmega8A.
  • REKLAMA
  • #2 9011547
    Fredy
    Poziom 27  
    Zła konstrukcja programu. Masz bardzo rozbudowane przerwanie, w którym robisz obliczenia na liczbach z przecinkiem. To po skompilowaniu stworzy ogromny kod i będzie trwało wieczność. W głównej pętli masz ciągłe wypisywanie na LCD, jeśli w trakcie transmisji do LCD wejdzie przerwanie może być kolizja.
    Zmień program tak aby w przerwaniu była tylko ustawiana flaga. Resztę robisz w programie głównym. A na wyświetlacz wysyłasz tekst tylko wtedy gdy nastąpi jakaś zmiana czyli tu zostanie ustawiona flaga w przerwaniu.
    Myślę że program znacznie się poprawi w swoim działaniu.
REKLAMA