Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Problem z przerwaniem od T1 w ATMega16 (Bascom)

byrrt 12 Cze 2007 12:46 1390 2
  • #1 12 Cze 2007 12:46
    byrrt
    Poziom 21  

    Witam!

    Od kilku dni siedze i nie mogę nic wymyśleć :(
    Bez ogrudek - podaje źródło:

    Code:

    $regfile = "m16def.dat"
    $crystal = 8000000

    'definiowanie zmiennych i stałych
    Dim T As Integer

    Dim Licznik_przerwan As Byte

    Dim Dioda As Bit

    'konfigurowanie interfejsu 1Wire
       Config 1wire = Portd.1                             

    'konfiguracja wyświetlacza
       Config Lcdpin = Pin , Db4 = Portc.6 , Db5 = Portc.5 , Db6 = Portc.4 , Db7 = Portc.3 , E = Portc.7 , Rs = Porta.7
       Config Lcd = 16 * 2
       Cursor Off

       Deflcdchar 0 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32         'znak stopnia
       Deflcdchar 1 , 16 , 24 , 28 , 30 , 31 , 31 , 31 , 32
       Deflcdchar 2 , 32 , 32 , 32 , 32 , 32 , 17 , 27 , 32
       Deflcdchar 3 , 1 , 3 , 7 , 15 , 31 , 31 , 31 , 32
       Cls


    'konfiguracja Timer1 jako czasonierza
       Config Timer1 = Timer , Prescale = 256
       On Ovf1 Timer_przerwanie
       Enable Ovf1
       Load Timer1 , 62500

    Enable Interrupts

    'określanie końcówek jako wejścia
       Config Pind.6 = Output

       Led Alias Portd.6

    Do
    Loop

    Timer_przerwanie:
       Reset Led
       Load Timer1 , 62500
       Incr Licznik_przerwan
       Lcd Licznik_przerwan

       If Licznik_przerwan = 1 Then
          1wreset
          1wwrite &HCC
          1wwrite &H44
       End If
       If Licznik_przerwan = 2 Then
          1wreset
          1wwrite &HCC
          1wwrite &HBE
          T = 1wread(2)
          T = T / 16
          Licznik_przerwan = 0
          Cls
       End If
       Set Led
    Return

    end


    Jest to część znacznie większego programu.. Wiele razy w rożnych projektach korzystałem z T1 jako źródła przerwań, ale nigdy nie było takich jaj.. Efekt jest teraz taki ze kilka razy (na oko patrząc na diodę) przerwanie idzie ok, potem zaczyna jakby przyspieszać do takiego stopnia ze zaczyna pulsować bardzo szybko poczym program się wywala i ustawia prawie wszystkie zmienne w programie na max wartość (np. bajt 255). Wygląda to tak jakby się zapętlały przerwania.. Ale chyba 2s starczy na odczytanie z DS18B20 temperatury i przeliczenie jej... Śmiechu warte normalnie.. Jak w podprogramie przerwana jest tylko zmiana stanu diody to częstotliwość jej migania jest ok. Gdy wyłączę linie przeliczania temp (T=T/16) program jakby się wyrabiał, ale raz kiedyś tez się wysypie... O co chodzi - może ktoś wie?

    Pozdrawiam
    Piotr

    0 2
  • #2 14 Cze 2007 15:04
    cyberdar
    Poziom 31  

    Witam

    Jakoś dziwnie to napisane. Przede wszystkim jak piszę TIMER to nie używam potem OVF1. Jakoś mi to brzydko wygląda choć działać powinno.
    Skoro chcesz mieć jeden odczyt na dwie sekundy to zrób to zupełnie inaczej. Np. w programie głównym zrób sobie licznik i dla wartości powiedzmy jeden niech wyśle rozkaz do DSa ażeby przetwarzał temperaturę. następnie zadeklaruj sobie opóźnienie na 100ms. Jak licznik zliczy do 20 to odczytaj zawartość DSa i wyzeruj licznik. Jeśli chcesz to oprzeć o przerwanie to w programie głównym umieściłbym rozkaz przetwarzania temperatury i start odmierzania czasu prze timer. Jak odmierzy czas to powinien odczytać z rejestrów temperaturę, przeliczyć ją i powiedzmy wystawić znacznik zakończenia operacji. Jak w programie głównym taki znacznik zostanie wychwycony to znów dajesz start przetwarzania włączasz timer, itd.

    --
    pozdrawiam

    0
  • #3 14 Cze 2007 22:48
    byrrt
    Poziom 21  

    Właśnie cały problem w tym, że program główny ma co robić i nie jest pustą pętlą.. Temperatura musi być stale kontrolowana choćby dlatego aby włączać wentylatory (jest to wzmacniacz) lub reagować np wyłączaniem zasilania.. Dlatego zależy mi aby działało to poza programem głównym.. I pomijając estetykę programu... Czemu to nie chce działać? Co ma odczyt DSa z przerwaniem?

    Rozwiązałem to chwilowo tak, że usunołem ten warunek w pętli.. Teraz co sekunde wysyłam i zaraz odczytuje temp z DS'a (mimo, że jeszcze jest w nim stara wartość ale opóźnienie 1s mi nie przeszkadza ;) ) - i to działa.. Tak jakby pętla warunkowa przeszkadzała w przerwaniu... :/

    Pozdrawiam

    0