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] Licznik impulsów nie działa poprawnie.

Tomekddd 17 Lut 2010 15:22 5027 14
REKLAMA
  • #1 7708354
    Tomekddd
    Poziom 23  
    Mam silnik z przekładnią który daje 5 impulsów na jeden obrót przekładni, obrotów jest 139 to liczyłem na piechotę ale chcę wykorzystać Atmege 8 do sterowania tym silnikiem i nie mogę dojść do ładu z liczeniem tych impulsów.

    Próbowałem liczyć impulsy funkcja DEBOUNCE i szło dobrze dopóki nie zwiększyłem prędkości obrotowej, zaczęło gubić impulsy

    Następnie próbowałem przerwania INT1 ale z racji tego ze impuls podawany na to przerwanie utrzymuje się przez dłuższa chwile to cały program się ścinał (na osi przekładni jest kółko magnetyczne i kontaktron przez to w położeniach skrajnych przekładni po wyłączeniu się krańcówki ciągle jest zwarty kontaktron to powodowało zwiechę procesora)

    Próbowałem też funkcji IF...Then ale własnie w położeniach skrajnych ciągle liczyło a gdy procesor dostał impuls to zwiększał zmienną wiele razy w czasie jego trwania a nie tylko raz

    Próbowałem liczy impulsy za pomocą TIMER1 ale po wystąpieniu impulsu timer liczy aż do jego zaniku a to tez jest źle


    Proszę o jakąś pomoc z tym programem bo ja już nie mam pomysłów
    to jest mój aktualny kod bez funkcji zliczania tylko sterowanie silnikiem

    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Lcd = 16 * 2                                         'konfiguracja wyświetlacza
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    
    
    Config Int0 = Low Level                                     'konfiguracja przerwania INT0
    Config Rc5 = Pind.2                                         'konfiguracja lini odbioru z pilota
    
    
    
    Config Pinb.2 = Output                                      'wyciągarka gora
    Config Pinb.3 = Output                                      'Wyciagarka Dol
    Config Pinb.4 = Output                                      'ściskanie
    Config Pinb.5 = Output                                      'rozciaganie
    
    
    Portb.2 = 0
    Portb.3 = 0
    Portb.4 = 0
    Portb.5 = 0
    
    
    
    
    On Int0 Pobr_rc5                                            'przerwanie na odbiór z pilota
    
    
    Dim Adres As Byte , Komenda As Byte                         'zmienne do rc5
    Dim Odebr_kod As Bit                                        'flaga potwierdzajaca odebranie kodu
    Enable Interrupts                                           'odblokowanie przerwań
    Enable Int0
    
    Reset Odebr_kod                                             'wyzerowanie flagi odebrania kodu
    
    Dim Impuls As Integer                                       'zmienna pamietająca liczbe impulsów z siłownika
    Impuls = 0
    
    Cursor Off Noblink
    
    Cls
    Do
    
    Upperline : Lcd "impulsy:" ; Impuls
    
    
    If Odebr_kod = 1 Then
    If Adres = 0 And Komenda = 1 Then                           'komenda podniesienia głosników do góry
    Gosub Gora                                                  'skok do obsługi podnoszenia
    Elseif Adres = 0 And Komenda = 7 Then                       'komenda opuszczenia glosników na doł
    Gosub Dol                                                   'skok do obslugi opuszczania
    Elseif Adres = 0 And Komenda = 3 Then                       'komenda ściśniecia głosników
    Gosub Scisk                                                 'skok do podprogramu
    Elseif Adres = 0 And Komenda = 9 Then                       'komenda rozciagnięcia
    Gosub Rozciag                                               'skok do podprogramu
    Elseif Adres = 0 And Komenda = 5 Then                       'komenda STOP
    Gosub Zatrzymaj                                             'skok do zatrzymania
    End If
    Enable Int0
    End If
    
    
    Loop
    End
    
    
    
    Pobr_rc5:                                                   'podprogram odbioru danych z pilota
    Disable Int0
    Enable Interrupts
    
    Getrc5(adres , Komenda)                                     'odbiór adresu i komendy
    Komenda = Komenda And &B01111111
    
    Set Odebr_kod                                               'ustawienie flagi odebrania
    Return
    
    Gora:
    Portb.2 = 1
    Portb.3 = 0
    Return
    
    Dol:
    Portb.2 = 0
    Portb.3 = 1
    Return
    
    Scisk:
    Portb.4 = 1
    Portb.5 = 0
    Return
    
    Rozciag:
    Portb.4 = 0
    Portb.5 = 1
    Return
    
    Zatrzymaj:
    Portb.2 = 0
    Portb.3 = 0
    Portb.4 = 0
    Portb.5 = 0
    Return
    


    Poprawiłem tytuł. - arnoldziq

    Przeniesiono z Programowanie Ogólne. - arnoldziq
  • REKLAMA
  • #2 7708634
    Konto nie istnieje
    Poziom 1  
  • #3 7708843
    Tomekddd
    Poziom 23  
    Teraz się nie zawiesza ale liczy jak mu się podoba tzn. pokazuje rożne wartości bez jakiejś reguły

    to jest przerwanie ustawione na zbocze FALLING
    
    
    Licz:
    Disable Int1
    If Scisk = 1 Then
    Incr Impuls
    Elseif Scisk = 0 Then
    Decr Impuls
    End If
    Enable Int1
    Return
    
  • REKLAMA
  • #5 7709338
    janbernat
    Poziom 38  
    Jakiś bałagan podajesz.
    1. Nie podałeś wersji z debounce- która chodziła przy wolnych obrotach.
    2. W programie który wkleiłeś nie ma żadnego odniesienia do Licz:
    Czy to jest podprogram czy obługa przerwania?
    3. Po co w tym Licz wyłączasz prerwanie?
    Jak to jest obsługa przerwania- to i tak inne przerwania są wyłączone.
  • #6 7709629
    Konto nie istnieje
    Poziom 1  
  • #7 7709988
    Tomekddd
    Poziom 23  
    wersji z DEBOUNCE nie dałem bo nie ma jej już zapewne nie działała dlatego ze impulsy docierały zbyt szybko a DEBOUNCE ma opóźnienia eliminujące drgania styków co pewnie wpływało na wykrywanie impulsów. Wiem ze można tę instrukcje przestawić zmniejszając czas opóźnienia ale to nie ma sensu bo jak kiedyś wystąpią wyższe obroty to ich nie uwzględni

    ten fragment to własnie obsługa przerwania INT1 ustawionego na wykrywanie opadającego zbocza sygnału

    Kontaktron podaje masę na procesor ale jeśli będzie potrzeba mogę to zmienić np na podawanie plusa

    Wiem że GOSUB to tu wcale nie pasuje ale to pozostałość po próbach przeróbki, zaraz je wywalę i zrobię tak jak należy

    Jeszcze mam problem z wyświetlaniem na LCD jak dam CLS w pętli DO...LOOP to tak szybko odświeża ze nie widać znaków a jak dam poza nią to znowu nie czyści wyświetlacza i pozostają śmieci
    da sie to jakoś zrobić bez wprowadzania do programu niepotrzebnego opóźnienia?
  • REKLAMA
  • #8 7710177
    janbernat
    Poziom 38  
    "bo jak kiedyś wystąpią wyższe obroty to ich nie uwzględni "
    Słusznie- debounce to paskuda.
    Ale od czegoś trzeba zacząć.
    Normalnie ma 25ms- można dać 1ms i chociaż sprawdzić.
    Kontaktron tak jak przycisk- ma drgania.
    Trzeba sprawdzić czy po 20ms ma ten sam stan- dla początkujących- debounce.
    A lepiej ale nie jako "pacaneum"- wygenerować przerwanie z jakiegos Timera i sprawdzać co jakis czas.
    CLS daje duże opóźnienia.
    Sprawdź $lib "Lcd4busy.lib"
  • #9 7710881
    Tomekddd
    Poziom 23  
    właśnie dlatego nie chce korzystać z DEBOUNCE bo później mogę mieć problemy

    odnośnie biblioteki to mi sie ona nie przyda bo tylko przyspiesza transmisję między wyświetlaczem a to mi nie pomoże bo znaki nadal będą migać i nic nie będzie widać
    może za pomocą LOCATE jakoś sobie poradzę

    Bardziej martwi mnie liczenie tych impulsów nieszczęsnych już nie wiem co wykorzystać do tego
    Przy przerwaniu zlicza ale przez czas trwania impulsu co powoduje że zwiększa zmienną wiele razy zamiast tylko raz


    Napisałem procedurę konfigurującą Timer1 jako licznik impulsów ale nie działa jak trzeba, licznik ciągle liczy bez względu na stan PORTB.0

    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Lcd = 16 * 2                                         'konfiguracja wyświetlacza
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    
    
    Config Int0 = Low Level                                     'konfiguracja przerwania INT0
    Config Rc5 = Pind.2                                         'konfiguracja lini odbioru z pilota
    
    Config Timer1 = Counter , Edge = Rising
    Config Pinb.0 = Input
    Set Portb.0
    
    Config Pinb.2 = Output                                      'wyciągarka gora
    Config Pinb.3 = Output                                      'Wyciagarka Dol
    Config Pinb.4 = Output                                      'ściskanie
    Config Pinb.5 = Output                                      'rozciaganie
    
    Portb.2 = 0
    Portb.3 = 0
    Portb.4 = 0
    Portb.5 = 0
    
    
    
    
    On Int0 Pobr_rc5                                            'przerwanie na odbiór z pilota
    
    Dim Adres As Byte , Komenda As Byte                         'zmienne do rc5
    Dim Odebr_kod As Bit                                        'flaga potwierdzajaca odebranie kodu
    Enable Interrupts                                           'odblokowanie przerwań
    Enable Int0
    Enable Timer1
    
    Timer1 = 0
    Start Timer1
    
    
    Reset Odebr_kod                                             'wyzerowanie flagi odebrania kodu
    
    Dim Scisk As Bit
    
    
    Cursor Off Noblink
    
    Cls
    Do
    
    Upperline : Lcd "impulsy:" ; Timer1
    
    
    If Odebr_kod = 1 Then
    If Adres = 0 And Komenda = 1 Then                           'komenda podniesienia głosników do góry
    Portb.2 = 1
    Portb.3 = 0
    Elseif Adres = 0 And Komenda = 7 Then                       'komenda opuszczenia glosników na doł
    Portb.2 = 0
    Portb.3 = 1
    Elseif Adres = 0 And Komenda = 3 Then                       'komenda ściśniecia głosników
    Portb.4 = 1
    Portb.5 = 0
    Scisk = 1
    Elseif Adres = 0 And Komenda = 9 Then                       'komenda rozciagnięcia
    Portb.4 = 0
    Portb.5 = 1
    Scisk = 0
    Elseif Adres = 0 And Komenda = 5 Then                       'komenda STOP
    Portb.2 = 0
    Portb.3 = 0
    Portb.4 = 0
    Portb.5 = 0
    End If
    Enable Int0
    End If
    
    
    Loop
    End
    
    
    Pobr_rc5:                                                   'podprogram odbioru danych z pilota
    Disable Int0
    Enable Interrupts
    
    Getrc5(adres , Komenda)                                     'odbiór adresu i komendy
    Komenda = Komenda And &B01111111
    
    Set Odebr_kod                                               'ustawienie flagi odebrania
    Return
    
  • REKLAMA
  • #10 7714395
    xury
    Specjalista automatyka domowa
    Jeszcze raz od nowa. Tym razem postaraj się bardziej. Ustaw wreszcie te przerwania INTx na jakieś zbocze, a nie poziom. Co z tego, że ustawiłeś Timer1 jako licznik jak nie ma to związku z resztą kodu. Timer sobie działa,a ja się pytam - i co z tego ? gdzie obsługa tego timera?
  • #11 7714664
    Tomekddd
    Poziom 23  
    Przerwanie mam ustawione na LOW LEVEL bo steruje to pilotem RC5
    a chciałem zrobić drugie INT1 na zbocze to nie działa tylko zmula program pewnie dlatego ze w skrajnych położeniach ciągle jest stan niski

    Jak obsługiwać ten Timer? czy on nie będzie zliczał zewnętrznych impulsów? bo własnie czytałem ze liczy impulsy na PB.0 a on wcale na to nie reaguje tylko ciągle sobie liczy

    Zrobiłem jeszcze z obsługą DEBOUNCE i czasem opóźnienia 5ms to niby liczy ale za każdym razem jest inny wynik podejrzewam ze gubi impulsy bo któreś mogą trafić akurat na opóźnienie
  • #12 7715132
    Konto nie istnieje
    Poziom 1  
  • #13 7716666
    Tomekddd
    Poziom 23  
    Ok po kolei, wywalam wszystko z programu, zostawiam tylko sterowanie IR i dopisuję obsługę przerwania INT1 wyzwalanego zboczem FALLING, w przerwaniu dodaje lub odejmuje jeden od zmiennej "impulsy" zależnie od zmiennej "ścisk"

    zmienna impulsy jest zwiększana o kilkanaście a nie tylko o jeden

    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Lcd = 16 * 2                                         'konfiguracja wyświetlacza
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    
    
    Config Int0 = Low Level                                     'konfiguracja przerwania INT0
    Config Rc5 = Pind.2                                         'konfiguracja lini odbioru z pilota
    
    Config Int1 = Rising
    
    Config Pinb.2 = Output                                      'wyciągarka gora
    Config Pinb.3 = Output                                      'Wyciagarka Dol
    Config Pinb.4 = Output                                      'ściskanie
    Config Pinb.5 = Output                                      'rozciaganie
    
    Portb.2 = 0
    Portb.3 = 0
    Portb.4 = 0
    Portb.5 = 0
    
    
    On Int0 Pobr_rc5                                            'przerwanie na odbiór z pilota
    On Int1 Licz
    
    Dim Adres As Byte , Komenda As Byte                         'zmienne do rc5
    Dim Odebr_kod As Bit                                        'flaga potwierdzajaca odebranie kodu
    Enable Interrupts                                           'odblokowanie przerwań
    Enable Int0
    Enable Int1
    
    
    Reset Odebr_kod                                             'wyzerowanie flagi odebrania kodu
    
    Dim Ok As Bit
    Ok = 0
    Dim Scisk As Bit
    Scisk = 1
    Dim Impulsy As Integer
    Impulsy = -1
    
    Cursor Off Noblink
    
    Cls
    Do
    
    Upperline : Lcd "impulsy:" ; Impulsy
    
    
    If Odebr_kod = 1 Then
    If Adres = 0 And Komenda = 1 Then                           'komenda podniesienia głosników do góry
    Portb.2 = 1
    Portb.3 = 0
    Elseif Adres = 0 And Komenda = 7 Then                       'komenda opuszczenia glosników na doł
    Portb.2 = 0
    Portb.3 = 1
    Elseif Adres = 0 And Komenda = 3 Then                       'komenda ściśniecia głosników
    Portb.4 = 1
    Portb.5 = 0
    Scisk = 1
    Ok = 1
    Elseif Adres = 0 And Komenda = 9 Then                       'komenda rozciagnięcia
    Portb.4 = 0
    Portb.5 = 1
    Scisk = 0
    Ok = 1
    Elseif Adres = 0 And Komenda = 5 Then                       'komenda STOP
    Portb.2 = 0
    Portb.3 = 0
    Portb.4 = 0
    Portb.5 = 0
    Ok = 0
    End If
    Enable Int0
    End If
    
    
    Loop
    End
    
    
    Pobr_rc5:                                                   'podprogram odbioru danych z pilota
    Disable Int0
    Enable Interrupts
    
    Getrc5(adres , Komenda)                                     'odbiór adresu i komendy
    Komenda = Komenda And &B01111111
    
    Set Odebr_kod                                               'ustawienie flagi odebrania
    Return
    
    
    
     'PRZERWANIE INT1
    Licz:
    If Scisk = 1 And Ok = 1 Then
    Incr Impulsy
    Elseif Scisk = 0 And Ok = 1 Then
    Decr Impulsy
    End If
    Return
    
  • Pomocny post
    #14 7716827
    Konto nie istnieje
    Poziom 1  
  • #15 7717428
    Tomekddd
    Poziom 23  
    W takim razie zrobię to na DEBOUNCE będzie lepiej a czas opóźnienia ustawie na 5ms i myślę że to pomoże
REKLAMA