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

[Atmega8515][AVR gcc] 4 zdarzenia wywołujące 1-o przerwanie

GUZIK.ZIELONY 31 Sie 2009 14:30 1776 3
REKLAMA
  • #1 6964203
    GUZIK.ZIELONY
    Poziom 10  
    Witam,

    chciałem podłączyć pod ATmegę 4 enkodery z myszek PC. Znalazłem taki kod w sieci:

    
     *
     * ENCODER - Checks rotary encoder and returns the following:
     *
     *               0:  no movement
     *              -1:  ccw rotation
     *               1:  cw rotation
     *
     *------------------------------------------------------------------------*/
    
    signed char 
    encoder(void)
    {
       static unsigned char a, b;
       if (!a & !b) {
          if (ENC_A) {
             a = ENC_A;
             return (-1);
          }
          if (ENC_B) {
             b = ENC_B;
             return (1);
          }
       }
       if (a & !b) {
          if (!ENC_A) {
             a = ENC_A;
             return (1);
          }
          if (ENC_B) {
             b = ENC_B;
             return (-1);
          }
       }
       if (a & b) {
          if (!ENC_A) {
             a = ENC_A;
             return (-1);
          }
          if (!ENC_B) {
             b = ENC_B;
             return (1);
          }
       }
       if (!a & b) {
          if (ENC_A) {
             a = ENC_A;
             return (1);
          }
          if (!ENC_B) {
             b = ENC_B;
             return (-1);
          }
       }
       return (0);
    }
    


    Kod wygląda ok.Problem stanowi dla mnie to, że oprócz obsługi tych enkoderów uP będzie miał robić jeszcze masę innych rzeczy. Dlatego pomyślałem, żeby obsługę enkoderów zrobić w przerwaniu zewnętrznym. Tylko jak to zrobić dla 4 enkoderów? Osobiście wymyśliłem coś takiego i chciałem zapytać czy to ma szanse zadziałać:
    -podłączam wszystkie sygnały z enkoderów do sumatora, a jego wyjście pod PIN od wyzwalania przerwania zewnętrznego,
    -konfiguruje przerwanie, żeby wyzwalała je zmiana stanu na tym pinie,
    -wyprowadzenia z enkoderów podłączam też do multipleksera,
    -i w obsłudze przerwania po kolei wybieram multiplekserem enkodery i używam tej funkcji co wyżej wrzuciłem "encoder(void)", dzięki temu wiem, który enkoder działa oraz w którą stronę był ruch.

    Mam wątpliwości czy czasowo się wyrobię- czy np jeżeli będzie to ostatni enkoder to czy zdążę odczytać info czy już przestanie wysyłać te sygnały przesunięte w fazie.
    Zależy mi na szybkim zareagowaniu na te enkodery. Czy to co wymyśliłem ma szanse zadziałać, a może ktoś z Forumowiczów ma lepszy pomysł. Czekam na propozycje i sugestie.
  • REKLAMA
  • #2 6965677
    Krauser
    Poziom 26  
    - Podobne rozwiązanie jest często stosowane. Mianowicie linie, które mają być podpięte do jednego wejścia dołącza się na wejścia bramki AND a jej wyjście na wejście przerwania. Dodatkowo te linie dołącza się na linie portów skonfigurowanych jako wejścia. To przypadek gdy interesuje nas zmiana z 1 na 0 i linia przerwania wykrywa zbocze opadające, ale wybierając inne bramki OR, NOR i NAND oraz wykrywanie zbocza narastającego można dowolnie to konfigurować.
    - Stosowanie multipleksera jest mało opłacalne, bo przy 4 liniach zaoszczędzisz 1 wejście i musisz uwzględnić czas przełączania multipleksera i w kolejnej instrukcji po ustawieniu radzę dać jednego nop'a (co jest wymogiem również w innych aplikacjach gdzie najpierw ustawiamy a zaraz potem czytamy stan portu).
    - Program wygląda w porządku, ale obsługuje tylko 2 enkodery (wejścia ENC_A i ENC_B).
    - Wada rozwiązania. Załóżmy, że w podanym przeze mnie przykładzie akurat jeden enkoder stoi i nieszczęśliwie ustawił się na 0, wtedy inne wejścia nic nie mają do gadania = nie będzie przerwania. Może w myszce to mało prawdopodobne, ale możliwe.
    - Inne rozwiązanie: PCF8574(A). Ten układ na I2C po skonfigurowaniu linii jako wejścia po zmianie tych właśnie linii też daje przerwanie. Pozostałe 4 linie można wykorzystać do sterowania np. 4 Led. 3 wyprowadzenia uP wystarczą.

    Sam jestem ciekaw co można jeszcze w tym temacie wymyślić.
  • REKLAMA
  • #3 6966766
    rpal
    Poziom 27  
    Stosowanie PCF8574 ma tę wadę że przerwanie go nie obsłuży i trzeba użyć znacznika aby w pętli głownego programu go odczytać. Nie napisano nic i typie scalaka ale domyślam się że trzeba spowodować aby z 4 linii wejściowych na których występuje logiczne 0 wygenerować przerwanie i ew. odczytać stan tych linii w przerwaniu ?
    Jeśli tak to proponuję rejest typu latch z wyjściem trójstanowym w miarę szybki np. z serii HC a jego linie wejściowe podłączyć dodatkowo na wejścia bramki NAND np. 7420. Wejścia dodatkowo podciągnąć rezystorami do +5V. Wyście na 7420 dać na wejście zegarowe Lach-a aby narastające zbocze sygnału wpisywało stan linii do rejestru a także na wejście INTx w procku (wyzwalane zboczem narastającym). Ważne jest aby 7420 nie był za szybki i miał dość długi czas propagacji aby sygnał był opóźniony o jakieś 50 ns w stosunku do stanu na liniach wejściowych. Seria CD40XX jest dość wolna ale i ta stara seria zwykłych TTL-i nie jest żadna rewelacją pod względem szybkości. Teraz aby odczytać to co się w latch-u znajduje wystarczy na wejście OE podac logiczne 0 i bufor trójstanowy otwiera się podając na jego wyjścia zapamiętane stany wejść. Można to zrobić w przerwaniu a linie procka używać dowolnie bo są one wejściami tylko na czas odczytu z latch-a. potrzebna jest tylko jedna linia do sterowaniem wejścia OE i ta jest istotnei zmarnowana dla innych celów. Taka moja propozycja :)
  • #4 6966786
    kwesoly
    Poziom 15  
    Krauser napisał:
    - Program wygląda w porządku, ale obsługuje tylko 2 enkodery (wejścia ENC_A i ENC_B).

    raczej jeden enkoder, A i B to przesunięte w fazie kanały tego samego enkodera.

    Dużo zależy od szybkości działania tych enkoderów - wywołanie przerwania i jego obsługa zajmie kilka cykli - przy programowej obsłudze 8 linii zrobi się gęsto od if'ów (4x to co juz jest), zwłaszcza, że przy połączonych przerwaniach trzeba będzie ręcznie sprawdzać który pin się zmienił, więc procek może nie wyrobić przy zbyt częstych impulsach.

    Do przerwań możesz użyć układu 74s135 9o ile gdzieś da się go kupić :/), zmontujesz exor na 8 wejściach i każda zmiana wejścia spowoduje zmianę wyjścia - pozostaje znów kwestia tego jak szybkie będą impulsy, żeby dwa następujące po sobie nie mogły zostać przegapione.

    Dodano po 8 [minuty]:

    Jeśli procesor nie jest narzucony konstrukcyjnie i możesz wybrać inny - rozejrzyj się za atmegami z całym portem podpiętym pod przerwania - Ustawiasz tylko które linie danego portu mają wywoływać przerwanie i masz 8 wejść z przerwaniem - np ATmega162.
REKLAMA