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

[atmega16] [Bascom] Wpis wartości początkowej do timera

michal2666 11 Mar 2010 07:35 3021 22
  • #1 7812938
    michal2666
    Poziom 20  
    Witam szanownych Forumowiczów.
    Napotkałem pewien problem podczas pisania programu pod nowe urządzenie. W programie wykorzystuję Timer0 do generowania przerwania w obsłudze którego wykonuje się praktycznie cały program, czas wykonania obsługi jest różny w zależności od parametrów. Tu wszystko jest OK, mogę wpisać początkową wartość, i dowolnie częstotliwość sobie ustawiam.
    Problem jest z timerem1 - ten chcę wykorzystać jako generator niezależny sygnału 0 - 100 Hz. najpierw również postanowiłem zrobić generator w obsłudze przerwania i w tej obsłudze zmieniałem stan portu - w tym przypadku w obsłudze przerwania wpisuje początkową wartość i płynnie reguluję częstotliwość ale przeszkadza przerwanie od timera0 i sygnał jest przerywany. Sposób ten odrzuciłem. Później wykorzystałem wyjście CompareA, skonfigurowałem charakter na toggle i pięknie sygnał generuje, nic nie przeszkadza sygnał jest ciągły, ale za jasną ch... nie mogę wpisać początkowej wartości i regulować częstotliwość. sypie mi sygnał maksymalny dla danego podziału na preskalerze. Bardzo proszę o pomoc, oczywiście jeśli to możliwe chciałbym w trakcie działania programu zmieniać częstotliwość ale jeśli się nie da to zależy mi na stałej 100 Hz.
  • Pomocny post
    #2 7813327
    Kabuto15
    Poziom 19  
    Mnie uczono, że w przerwaniach najlepiej umieszczać jedynie ustawianie flagi, a jego obsługę w pętli głównej (pracującej z max. częstotliwością). Może spróbuj takiego rozwiązania, bo bez kodu źródłowego ciężko coś więcej doradzać.
  • #3 7813340
    piotrek7700
    Poziom 16  
    W przerwaniach mozna zrobic kilka rozkazow a nie caly kod. Najpierw posluchaj rady koleg Kabuto15 i w przerwaniu ustawiaj flage, w programie glownym jednego if'a i na pewno bedzie bardziej optymalne i z zachowaniem ram czasowych wykonywany ten kod.
    Bez kodu bedzie ciezko, Przejrzales datasheeta do Atmegi? odnosnie CompareA?
  • #4 7813360
    michal2666
    Poziom 20  
    Takie rozwiązanie niestety się nie sprawdzi bo nawet jak umieszczę obsługi obu przerwać w pętli głównej to i tak obsługa tych zadać z pierwszego przerwania zajmie trochę czasu i już będzie przerwa w generowaniu sygnału. To generowanie musi być całkowicie niezależne od wykonywania programu więc pozostaje tylko wyjście sprzętowe compare. Pytanie tylko jak zmieniać częstotliwość ?? Podaruję sporą ilość pkt. za rozwiązanie bo to temat nie cierpiący zwłoki a ja chyba zbyt ciemny jestem :cry:

    Dodano po 7 [minuty]:

    Spróbuję przenieść do pętli głównej i zobaczę jak to się będzie zachowywać ale wydaje mi się, że będzie podobnie. Umieściłem obsługę większości programu w przerwaniu bo łatwo mi w ten sposób kontrolować częstotliwość. Czytałem o compare i próbowałem stosować się to podanych informacji ale nic nie działa. Kod umieszczę tylko muszę go poukładać bo w tej postaci nikt by się w nim nie połapał. Wydaje mi się, że problem jest w braku synchronizacji pomiędzy wpisem wartości początkowej do timera a liczeniem samego licznika, jak to zsynchronizować ?
  • Pomocny post
    #5 7813418
    piotrek7700
    Poziom 16  
    Sprobuj jeszcze od timera0 obsluge przerwania w petli glownej, a Krotki kod generujacy tego prostokata, mozesz zorbic:
    -przeliczajac ile z danym kwarcem wynosi okres danej czestotliwosci
    wpisac do licznika timera1 polowe tej wartosci, aby co pol okresu zmienial stan wyjscia na przeciwnym, przerwanie od Timera1 oczywsice ze wzgledu na prostote zrob w samym przerwaniu. A jesli do licznika Timer1 bedziesz ladowal ze zmiennej wartosci impulsow, bedziesz mgl regulowac czestotliwosc.


    Pamietaj ze jak obslugujesz jedno przerwanie masz zablokowane mozliwosc wywolania drugiego, i w ten sposob gubia sie przerwania, czestotliwosci sie rozjezdzaj.
  • #6 7813478
    michal2666
    Poziom 20  
    No tak już chyba zakumałem :D bo przecież to co wykonuję w przerwaniu od timera0 nie musi działać idealnie cały czas, tam krótki przestój nie zaszkodzi. priorytet ma mieć przerwanie generujące sygnał. więc przeniesienie pierwszej obsługi to bętli głównej powinno rozwiązać problem. Dzięki wielkie, to powinno działać :) co kilka głów to nie jedna.
  • Pomocny post
    #7 7813482
    zumek
    Poziom 39  
    michal2666 napisał:
    ... Później wykorzystałem wyjście CompareA, skonfigurowałem charakter na toggle i pięknie sygnał generuje, nic nie przeszkadza sygnał jest ciągły, ale za jasną ch... nie mogę wpisać początkowej wartości i regulować częstotliwość...

    Świetny pomysł, tylko gorzej z wykonaniem :D
    Użyj jednego z dwóch trybów CTC timer1 i zmieniaj wartość końcową, czyli OCR1A, lub ICR1 - zależnie od trybu jakiego użyjesz.
  • #8 7813538
    michal2666
    Poziom 20  
    Nie znałem tych trybów czyli wpisuję wartość do porównania i jeśli jest zgodna następuje zmiana stanu Compare. Ale licznik będzie dalej liczył pozostałą wartość i tu będę miał znów przerwę. Czy w konfiguracji timera dopisujęs clear timer1 = 1 spowoduję, że po sukcesie porównania timer zostanie wyzerowany ?
  • #9 7813559
    piotrek7700
    Poziom 16  
    Timer po zrowaniu sie z zadana wartoscia jest kasowany sprzetowo iliczy od 0.
  • #10 7813826
    michal2666
    Poziom 20  
    I jeszcze jedno pytanko bo nic na ten temat nie znalazłem, więc wolę się upewnić. Tryb CTC nie wymaga jakichś dodatkowych ustawień ? wystarczy wpisać wartość do porówniania do rejestru OCR ?
  • Pomocny post
    #11 7816423
    janbernat
    Poziom 38  
    Tryb CTC należy ustawić zgodnie ze stroną 112 PDF.
    Należy dokładnie przeczytać tę stronę i okoliczne.
    Potem ustawić odpowiednie bity w odpowiednich rejestrach.
    W Bascomie robi się to np. tak:
    set TCCR1B.wgm13
    i tak dalej.
    Bascom nie ma gotowych instrukcji na wszystkie możliwe tryby pracy timerów.
    Ale pozwala na ustawienie tych trybów "ręcznie"- przez wpisanie do odpowiednich rejestrów odpowiednich wartości.
    Wtedy trochę lepiej panuje się nad pracą procesora.
  • #12 7825127
    michal2666
    Poziom 20  
    Witam !
    Dzięki wielkie za porady, po pierwsze przeniosłem cały program do pętli głównej i timera0 już nie używam, Właczyłem tryb CTC i nim pięknie generuję częstotliwość. Ale niestety w toku dalszych prac pojawił się następny problem. otórz w układzie potrzebuję wykorzystać jeszcze przerwanie od INT0
    [atmega16] [Bascom] Wpis wartości początkowej do timera
    Do wejścia tego będą podane impulsy z enkodera bo całość urzadzenia to bardzo dokłądny miernik przepływu gazu. Myślałem, że jak do generowania sygnału wykorzystam wyjście compare to nie będzie się to kłucić z innym przerwaniem, niestety po włączeniu zliczanie impulsów działa beznadziejnie. z każdym przejściem strzykawki w liczniku -zmiennej typu single wychodzą jakieś głupoty nawet po przecinku, po wyłączeniu timera1 jest OK. jak te impulsy bezkolizyjnie zliczać ??

    Post raportowany, proszę poprawić ortografię.
    Robak
  • #13 7825290
    rpal
    Poziom 27  
    impulsy mozesz liczyć na innym pozostałym liczniku, tylko należy mu ustawić jako źródlo impulsy zewnętrzne to rozwiązanie jest sprzętowe, tylko wymaga wybrania licznika o odpowiednim zakresie no i od czasu zerowanie aby przygotować go na kolejne zliczanie.
  • #14 7826212
    michal2666
    Poziom 20  
    Wszystko było by fajnie z tym innym licznikiem ale niestety zostały mi tylko 8 bitowe a to za mało, musiał bym część liczenia przenieść do pętli głównej a niestety to też nie zda egzaminu bo jak np włączę menu, a tam jest np. obsługa klawiatury i chośby dyskryminacja drgania styków która wstrzymuje czas, a w tym czasie stracę impulsy i pomiar będzie fałszywy.

    w tym przerwaniu od int0 mam proste polecenie INCR gas(zmienna typu single) a w wyniku wychodzi mi stos cyfr po przecinku.
  • #15 7826498
    janbernat
    Poziom 38  
    Timer0 ma też tryb CTC i przy ustawieniu prescale 1024 i odpowiednim ustawieniu rejestru OCR0 da się z niego uzyskać 100Hz.
    Wtedy można użyć Timer1 do liczenia.
  • #16 7826619
    michal2666
    Poziom 20  
    Witam po dalszych nocnych eksperymentach.
    Okazało się, że problem leży nie w konflikcie pomiędzy int0 a timerem, a w samej inkrementacji zmiennej single. gdy typ zmiennej, którą inkrementowałem w przrwaniu od int0 zmieniłem na word wszystko jst OK, dlaczego inkrementując single w tym przerwaniu dostawałem w wyniku jakieś śmieci po przecinku a i wartość przed przecinkiem wariowała.

    Dodano po 3 [minuty]:

    W zasadzie to muszę rozwiązać ten problem bo w tym przerwaniu chcę dokonywać aktualizacji objętości gazu więc muszę dodawać do zmiennej single 0,0087 i z tej prostej operacji też śmieci wychodzą. O co tu chodzi ?? :cry:
  • #17 7828141
    janbernat
    Poziom 38  
    Nie rób obliczeń na single w przerwaniu- obliczenia na single trwają bardzo długo.
    Dlatego pewnie na word działało.
    Jeśli jeszcze próbujesz to wyświetlić w przerwaniu- to przerwania powinny być nie częściej niż co 1s.
    Ustaw w przerwaniu tylko flagę.
    A obliczenia i wyświetlanie w pętli.
    Możesz jeszcze mieć skopane formatowanie wyświetlania.
    W sumie jak szybko jesteś w stanie odczytać zmieniające się dane?
  • #18 7828414
    michal2666
    Poziom 20  
    Dziękuję wszystkim za pomoc. Problem rozwiązałem inkrementując w przerwaniu od INT0 zmienną typu Long, przy tym typie wszystko również z liczeniem jest OK, tak więc co bym w pętli głównej nie robił liczenie cały czas jest prowadzone. Dopiero tą wartość już w pętli głównej przeliczam sobie i wyświetlam. Ale nie rozumiem dlaczego nie mogłem w przerwaniu prawidłowo przeliczać singla nawet gdy na początku przerwania wyłaczałem int0 tak by nastpny impuls nie przerwał bierzącego a po obliczeniu właczałem ponownie. To równiez nie działało - wychodziły głupoty.
  • #19 7828563
    janbernat
    Poziom 38  
    Bo nie wyłączałeś flagi żądania przerwania- wyłączałeś flagę zezwolenia na obsługę przerwania.
    A flaga żądania obsługi przerwania jest w innym rejestrze- Bascom tego nie obsługuje.
    Jak po obliczeniu włączałeś zezwolenie na przerwanie to flaga żądania obsługi przerwania już tylko "czychała" aby w to przerwanie wejść.
    Tę flagę- żądania obsługi przerwania- można skasować programowo wpisując 1.
    Przed zezwoleniem na obsługę przerwania.
    No ale wtedy tego przerwania już nie obsłużysz.
    P.S.
    Wogóle to daj kod.
    P.S.2
    Na początku obsługi przerwania wszystkie zezwolenia na obsługę innych przerwań są wyłączone automatycznie.
    Tak że nie wpisuj disable INTx na początku przerwania- to masło maślane.
    Ale flagi żądania obsługi- są.
  • #20 7828700
    michal2666
    Poziom 20  
    To na razie wersja robocza więc sporo niedociąnięć, muszę jednak zacząć rezygnować z bascoma. Niby już wszystko było OK, ale gdy tylko w pętli głównej przed wyświetlaniem chciałem zamaskować wynik poleceniem fusing, znów jakieś głupoty zaczęły się dziać. Nie mam już nerwów.

    $crystal = 8000000
    
    
    $regfile "m16def.dat"
    
    '*********************zmienne************************************
    
    Dim Objetosc As Single
    Dim Zapis As Byte
    Dim Odczyt As Byte
    Dim Adres As Word
    Dim Adresa As Byte At Adres Overlay
    Dim Adresb As Byte At Adres + 1 Overlay
    
    Dim Flagamenu As Bit
    Flagamenu = 0
    Dim Flagalcd As Bit
    Flagalcd = 1
    Dim Menuselect As Byte
    Menuselect = 1
    Dim Lcdl As Byte
    Dim Wt As Bit
    Wt = 1
    Dim Clsflag As Bit
    Clsflag = 0
    
    
    Dim Direct_flag As Bit
    
    Dim Glowna As Word
    Glowna = 0
    
    Dim Pomolcd As Byte
    Pomolcd = 0
    
    Dim Objetosc_lcd As String * 3
    '****************************************************************
    
    
    
    '************zmienna objętości gazu**************************
    Dim Gas As Long
    Dim Gasa As Byte At Gas Overlay
    Dim Gasb As Byte At Gas + 1 Overlay
    Dim Gasc As Byte At Gas + 2 Overlay
    Dim Gasd As Byte At Gas + 3 Overlay
    '************************************************************
    
    '***************procedury************************************
    Declare Sub Menu
    
    '***************koniec procedur******************************
    
    
    
    
    
    '***********************timer1****************************
    Config Timer1 = Timer , Prescale = 64 , Compare A = Toggle , Clear Timer = 1
    Config Pind.5 = Output
    Set Pind.5
    Enable Interrupts
    Enable Timer1
    
    Ocr1ah = High(310)
    Ocr1al = Low(310)
    
    Tccr1a.com1a1 = 0
    Tccr1a.com1a0 = 1
    
    Tccr1a.com1b1 = 0
    Tccr1a.com1b0 = 1
    
    ' ustawiamy Timer1 w tryb CTC - porównywanie z OCR1A
    Tccr1a.wgm11 = 0
    Tccr1a.wgm10 = 0
    
    '*********************koniec timer1**************************
    
    
    '*****************przerwanie INT0****************************
    Config Pind.2 = Input
    Set Pind.2
    Config Int0 = Rising                                        'przerwanie nastąpi podczas trwania opadającego zbocza impulsu z enkodera
    On Int0 Dodaj
                                                   'gdy processor otrzyma przerwanie wykona procedurę zwiększenia wartości ilości gazu.
    Enable Int0
    
    
    '**********************************************************
    
    
    
    
    '*************************LCD******************************
    Config Lcd = 20 * 4
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Porta.0 , E = Portb.1 , Rs = Portb.0
    Display On
    Cursor Off
    '**********************************************************
    
    
    '*************************konfiguracja SPI***********************************
    Config Pina.1 = Output
    Set Porta.1
    Cs Alias Porta.1
    Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Noss = 1
    Zapis = 2
    Odczyt = 3
    
    Spiinit
    '*************************************************************
    
    
    
    '*********Definicje przycisków********************************
    Config Pinc.2 = Input
    Set Portc.2
    Pup Alias Pinc.2
    
    Config Pinc.3 = Input
    Set Portc.3
    Pdown Alias Pinc.3
    
    Config Pind.7 = Input
    Set Portd.7
    Pok Alias Pind.7
    
    Config Pind.3 = Input
    Set Portd.3
    Pright Alias Pind.3
    
    Config Pind.4 = Input
    Set Portd.4
    Pleft Alias Pind.4
    
    Config Pind.6 = Output
    Set Portd.6
    Direct Alias Portd.6
    
    Config Pinc.4 = Input
    Set Portc.4
    Kmax Alias Pinc.4
    
    Config Pinc.5 = Input
    Set Portc.5
    Kmin Alias Pinc.5
    '*************************************************************
    
    '**********************konfiguracja I2C*************************
    Config Scl = Portc.0
    Config Sda = Portc.1
    
    '***************************************************************
    
    
    '*************************odczyt z SPI************************
    Waitms 20
    Cls
    
    '--------pierwszy bajt------
    Adres = 0
    
    Cs = 1
    Cs = 0
    
    Spiout Odczyt , 1
    Spiout Adresa , 1
    Spiout Adresb , 1
    Spiin Gasa , 1
    Cs = 1
    '---------------------------
    
    '--------drugi bajt------
    Adres = 1
    
    Cs = 1
    Cs = 0
    
    Spiout Odczyt , 1
    Spiout Adresa , 1
    Spiout Adresb , 1
    Spiin Gasb , 1
    Cs = 1
    '---------------------------
    
    '--------trzeci bajt------
    Adres = 2
    
    Cs = 1
    Cs = 0
    
    Spiout Odczyt , 1
    Spiout Adresa , 1
    Spiout Adresb , 1
    Spiin Gasc , 1
    Cs = 1
    '---------------------------
    
    '--------czwarty bajt------
    Adres = 3
    
    Cs = 1
    Cs = 0
    
    Spiout Odczyt , 1
    Spiout Adresa , 1
    Spiout Adresb , 1
    Spiin Gasd , 1
    Cs = 1
    '---------------------------
    
    '**************************************************************
    
    
    Do
    Incr Glowna
    If Glowna = 255 Then
    Glowna = 0
    
    
    
       '--------------------poruszanie strzykawką-----------------------------
       If Kmax = 0 Then
       Direct_flag = 0
       End If
    
       If Kmin = 0 Then
       Direct_flag = 1
       End If
    
       If Direct_flag = 0 Then
       Direct = 1
       End If
    
       If Direct_flag = 1 Then
       Direct = 0
       End If
    
    
       '--------------------koniec poruszania---------------------------------
    
       '-----------------wysyłka przez RS-232---------------------------------
    
    
    
    
       '------------------koniec wysyłki---------------------------------------
    
       '------------wysyłka I2C--------------------------------------------------
    
       'I2csend &H40 , Dana
       'Waitms 500
    
       '------------------koniec wysyłki--------------------------------------
    
    '****************Wywołąnie Menu*******************************************
           If Pok = 0 Then
             Flagamenu = 1
             Flagalcd = 0
           End If
    
             If Flagamenu = 1 Then
             Call Menu
             End If
    '********************koniec wywołania*************************************
    
    
    
    
       '***************Zapis SPI**************************************
       '--------------pierwszy bajt------------
    
       Adres = 0
       Cs = 1
       Cs = 0
    
       Spiout Zapis , 1
       Spiout Adresa , 1
       Spiout Adresb , 1
       Spiout Gasa , 1
       Cs = 1
       '---------------------------------------
    
       '--------------drugi bajt------------
       Adres = 1
       Cs = 1
       Cs = 0
    
       Spiout Zapis , 1
       Spiout Adresa , 1
       Spiout Adresb , 1
       Spiout Gasb , 1
       Cs = 1
       '---------------------------------------
    
       '--------------trzeci bajt------------
       Adres = 2
       Cs = 1
       Cs = 0
    
       Spiout Zapis , 1
       Spiout Adresa , 1
       Spiout Adresb , 1
       Spiout Gasc , 1
       Cs = 1
       '---------------------------------------
    
       '--------------czwarty bajt------------
       Adres = 3
       Cs = 1
       Cs = 0
    
       Spiout Zapis , 1
       Spiout Adresa , 1
       Spiout Adresb , 1
       Spiout Gasd , 1
       Cs = 1
       '---------------------------------------
    
       '**************************************************************
    
       Incr Pomolcd
       If Flagalcd = 1 And Pomolcd = 255 Then
       Pomolcd = 0
       Objetosc = Gas * 0.0087
       'Objetosc_lcd = Fusing(objetosc , "#.&&&")
    
       Locate 1 , 4
       Lcd "meter work"
    
       Locate 3 , 1
       Lcd "Obj. = " ; Objetosc
       End If
    
    End If
    Loop
    End
    
    '*********************Menu***************************
    Menu:
    
       Locate 1 , 3
       Lcd "***** Menu *****"
    
    
       If Pup = 0 Then
    
       Incr Menuselect
       Cls
       End If
    
       If Pdown = 0 Then
       Decr Menuselect
       Cls
       End If
    
    
    
    
    
       Select Case Menuselect
       Case 1:
       Locate 4 , 1
       Lcd "press -> or <- "
    
       Locate 2 , 1
       Lcd "1. LCD light: " ; Lcdl ; "     "
       Locate 3 , 1
       Lcd "                    "
    
       If Pright = 0 Then
    
       Incr Lcdl
       Cls
       End If
    
       If Pleft = 0 Then
    
       Decr Lcdl
       Cls
       End If
    
       If Lcdl = 11 Then
       Lcdl = 0
       End If
    
       If Lcdl = 255 Then
       Lcdl = 10
       End If
       '*********
       Case 2:
       Locate 4 , 1
       Lcd "press -> or <- "
    
       Locate 2 , 1
       Lcd "2. Work type:"
    
       If Pright = 0 Then
       Wt = 0
       Cls
       End If
    
       If Pleft = 0 Then
       Wt = 1
       Cls
       End If
    
       If Wt = 1 Then
       Locate 3 , 1
       Lcd "   - Gas pump"
       End If
    
       If Wt = 0 Then
       Locate 3 , 4
       Lcd "   - Gas meter"
       End If
    
       Case 3:
       Locate 2 , 1
       Lcd "3. EXIT MENU"
       Locate 3 , 1
       Lcd "If Yes press: OK"
       If Pok = 0 Then
          Waitms 50
          If Pok = 0 Then
       Flagamenu = 0
       Flagalcd = 1
       Menuselect = 1
       Waitms 60
       Cls
       End If
       End If
       Case 4:
       Locate 2 , 1
       Lcd "4. Clear gas measure"
       Locate 3 , 1
       Lcd "If Yes press OK"
       If Pok = 0 Then
       Gas = 0
       Locate 4 , 1
       Lcd "Saved: Gas = 0"
       End If
    
       End Select
    
    Return
    
    
    '**************** Zwiększanie wartości policzonej gazu ****************************
    Dodaj:
    
    If Direct_flag = 1 Then
    Gas = Gas + 1
    
    End If
    
    Return
    '********************************************


    Dodano po 25 [minuty]:

    [atmega16] [Bascom] Wpis wartości początkowej do timera

    A to moje miejsce walki, ale chyba dzięki bascomowi polegnę. Nie rozumiem, dlaczego dodanie w pętli głównej polecenia fusing rozwala nawet wartość w zmiennej objetosc. To jakaś masakra !!!
  • Pomocny post
    #21 7829379
    janbernat
    Poziom 38  
    Zmień: dim Objetosc_lcd as string*10- a potem jakie x-sprawdź.
    Bascom jest wolny i gruby- jak wół.
    Można na nim w pewnym stopniu polegać
    Ale opanowanie rasowego konia jakim jest C- jest trudniejsze- ma sam na wiele spraw własne zdanie.
    Brakuje oscyloskopu.
    Chyba jest-widać sonde.
    P.S.
    W głównej pętli wywołujesz menu w którym "siedzisz" przez waitms 60 i waitms 50.
    W tym czasie program jest w "pustej" pętli- ale obsługa przerwań jest włączona.
    Sprawdź co się może wtedy stać.
  • #22 7829695
    michal2666
    Poziom 20  
    Dzięki
    Dowiedziałem się właśnie, że każdy ciąg znaków string kończy się znakiem 0 i zawsze trzeba przewidzieć o jeden bajt więcej niż potrzeba. Na razie wszystko działa więc ruszam z dalszymi funkcjami. Pozdrawiam wszystkich udzielających się w temacie, gotowe urządzenie ze wszystkimi szczegółami opisuję u umieszczę na mojej stronie.

    Dodano po 15 [minuty]:

    janbernat napisał:
    W głównej pętli wywołujesz menu w którym "siedzisz" przez waitms 60 i waitms 50.
    W tym czasie program jest w "pustej" pętli- ale obsługa przerwań jest włączona.
    Sprawdź co się może wtedy stać.


    te 50 i 60 ms dodałem na razie tylko do jednego przycisku jako niwelacja drgających styków bo nie mogłem opuścić menu ale takie dyskryminacje będą przy wszystkich przyciskach. i właśnie dlatego zależało mi na przerwaniu od int0 bo menu będę potrzebował także w czasie pracy i chciałbym by impulsy z enkodera wtedy nie były tracone. i jak na razie tak się dzieje, pomimo tych pustych pętli program zlicza prawidłowo impulsy. Czy coś może się złego dziać ??

    Dodam tylko, że nie jest to komercyjny projekt, szczegółowo wszystko opisuję i umieszczę na mojej www. Urządzenie to będzie mierzyć ilości i przepływy powstającego w reaktorze laboratoryjnym metanu z biomasy.
  • #23 7830878
    janbernat
    Poziom 38  
    Ja to robię tak:
    
    Do
    
       If Flaga = 1 Then          'gdy jest przerwanie od Timer0- co 237us -czyli w zasadzie pętla wykonuje się co 237us aż do flaga=0
         If Pinb.0 = 0 Then       'i jest wciśnięty przycisk PIND.2- ustawianie kierunku jednym przyciskiem
             Incr Opoznienie_odczytu       'no bo przycisk ma drgania dłużej niż 237us- niech zwiększy
                                            'to sprawdzanie powtórne do 17ms
    
             If Opoznienie_odczytu >= 71 Then       'dajmy mu na wygaszenie drgań 17ms
    
                If Temp0 = 0 Then ' i jest zezwolenie na zmianę stanu
                   Gosub Ustawianie
                   Temp0 = 1      ' zablokuj zezwolenie na zmianę stanu
                End If
    
                Opoznienie_odczytu = 0       'Jak już ustawił kierunek to pozwolimy mu liczyć od początku-
                                              'po powtórnym naciśnięciu PIND.2
              End If
    
          Else
             Temp0 = 0            'zezwalaj na zmiany
             Opoznienie_odczytu = 0
          End If
    
    '********************  koniec obsługi przycisku
    'teraz część programu wykonująca się co przerwanie z Timer0-237us
    
    No i ustawiamy  flaga=0
    
    'teraz część programu wykonująca się w każdym przejściu pętli.
    

    itd.
    Przerwanie daję co 237us- bo takie potrzebuję impulsy.
    A sprawdzanie stanu przycisku co 17ms- bo to wystarcza.
    
    Step_delay:                   'ten timer określa szybkość z jaką szybkością kręci się silnik- teraz ok0.25ms/ impuls
    
       Timer0 = 60                'no to skracamy- ten silnik się jeszcze kręci- ale na jakimś innym moze to trzeba zmienić
       Flaga = 1                  'tu jest ok.237us obliczone 
    
    Return
    

    Z timera0 jest przerwanie co ok. 0.237us i w petli sprawdzam co ok.17ms czy przycisk jest wciśnięty.
    To z głównej pętli można też zrobić w procedurze- jak wygodniej.
    Wtedy nie ma żadnych waitms w pętli ani w procedurze.
    Procesor chodzi "ile mu fabryka dała".
REKLAMA