Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Przerwanie UART, I2C i Bascom.

robiw 13 May 2007 10:56 3431 13
  • #1
    robiw
    Level 26  
    Witam.
    Zamierzam "sklecić" taki układzik, który przy użyciu magistrali I2C zmienia odpowiednie parametry reagując w ten sposób na polecenia z klawiatury. Jednocześnie chciałbym aby te parametry mogły być także zmieniane przez odpowiednie instrukcje interfejsu MIDI (to taki UART z baud 31250). Wymyśliłem sobie, że sterownika będzie realizował (w pętli) swoje podstawowe funkcje a przy zgłoszeniu przerwania z UARTa odczytywał bajt i jeśli = 176 to odczytuje 2 następne, następnie "dekoduje" i wysyła odpowiednie sygnały regulacyjne przez I2C. Problem w tym, że oprócz tego na co ma zareagować (czyli danej 176) w MIDI co chwilę mogą przychodzić jakieś sygnały i w związku z tym obawiam się czy takie nieustanne przerwania od UARTa (MIDI) i sprawdzanie odczytanego bajta oraz ewentualnie 2 kolejnych nie spowodują "zatkania" programu głównego nie mówiąc już o "wywalaniu" transmisji I2C. Zresztą swoją drogą to nie wiem czy tą transmisję I2C umieszczać w procedurze obsługi przerwania, raczej nie... ale jeśli tak to powinna ta procedura przekazać parametry do pętli głownej a ta zrealizuje transmisję I2C tylko, że zanim to zrobi to może przyjść już nowe przerwanie... Macie jakieś pomysły (Bascom)... robiw
  • #2
    szymtro
    Level 30  
    Mamy pomysły.
    Użyjesz sprzętu który ma oba interface sprzętowe.
    Zdeklarujesz sobie bufory do wysyłania/odbierania jako bajtowe o odpowiedniej pojemności.
    Do tego liczniki danych w buforze.

    Program ma działać samoczynnie - ma odebrać dane do bufora po rs i wysłać dane samoczynnie z bufora po i2c po wyzwoleniu oczywiście.

    I2C zaraz po pierwszym przerwaniu ma sprawdzić czy licznik bajtów jest mniejszy niż ustawiony (do wysłania) i jeżeli nie to ładuje kolejny bajt i wysyła. Jak tak to wysyła stop i się wyłącza.

    RS podobnie - sprawdza jak wygląda licznik bajtów odebranych i jeżeli jest zero to sprawdza ten twój 176. Jak znajdzie zwiększa licznik i kolejna dana będzie lądowała w buforze - aż do osiągnięcia odpowiedniej liczby lub np crlf na końcu.

    Napisanie czegoś takiego nie jest trudne. Uruchomienie będzie bardziej skomplikowane niż LCD lub ds1820. Praca głównie z rejestrami niż wbudowanymi funkcjami bascom = można równie szybko zrobić to w asm.
  • #3
    robiw
    Level 26  
    Pomysł fajny ale odpada bo:
    1. uC to 89C4051 (sprzętowy UART) tylko odbiór Rx
    2. I2C - Bascom (steruje układami TDA)
    3. sterownik poza tym obsługuje "klawiaturę" (2 piny), impulsator i lcd 4x16znaków oraz adresuje 4052... robiw
  • #4
    szymtro
    Level 30  
    Quote:
    1. uC to 89C4051
    Faktycznie to troszkę zmienia.
    Ale malutka '51 atmela ma sprzętowy uart i chociaż to warto było by wykorzystać. Co do reszty sprzętu to użyj jak najwięcej hardware jak się da (encoder na przerwaniu).

    O rs sprzętowym pod bascomem już tutaj parę razy pisaliśmy - ostatni raz chyba wakacje zeszłego roku.

    Co do reszty to też da się zrobić - tylko pisz z głową, najlepiej uruchamiaj funkcje po kolei. I kup może jeszcze jednego uC bo 1000 cykli programowania może się okazać za mało.
  • #5
    robiw
    Level 26  
    szymtro wrote:
    Quote:
    1. uC to 89C4051
    Faktycznie to troszkę zmienia.
    Ale malutka '51 atmela ma sprzętowy uart i chociaż to warto było by wykorzystać. Co do reszty sprzętu to użyj jak najwięcej hardware jak się da (encoder na przerwaniu).

    O rs sprzętowym pod bascomem już tutaj parę razy pisaliśmy - ostatni raz chyba wakacje zeszłego roku.

    Co do reszty to też da się zrobić - tylko pisz z głową, najlepiej uruchamiaj funkcje po kolei. I kup może jeszcze jednego uC bo 1000 cykli programowania może się okazać za mało.


    Dlaczego Encoder na przerwaniu? To byłoby kolejne przerwanie, które może położyć transmisję I2C a nawet do LCD...1000 cykli programowania to aż nadto..nie mówiąc już o tym, że pewnie wytrzymują więcej. Na problem nie mam narazie pomysłu... robiw
  • #6
    szymtro
    Level 30  
    Tu się nie martw że ci wyłoży komunikację i2c - to nie jest 1wire. Tu można przerwać cykl zegara na bardzo długo i nic się złego nie stanie - dlatego wolę tmp100 od ds1820.
    To samo tyczy się komunikacji z lcd - jak wyjdzie dłużej to nic nie będzie - gorzej jak wyjdzie za krótko.

    Encoder ma dwa sygnały a i b. Jeden dajesz na przerwanie a drugi sygnał sprawdzasz jak wystąpi przerwanie. Jeden to kręcone w jedną 0 to w drugą o jeden impuls.
  • #7
    robiw
    Level 26  
    To jak najlepiej to napisać aby nie wstrzymywać programu a jednocześnie nie zgubić żadnych danych z MIDI - w Bascomie. robiw
  • #8
    szymtro
    Level 30  
    Najlepiej to napisać sobie w bascomie ale z użyciem sprzętu - czyli przerwania tu gdzie się tylko da.
    Rozumiem że masz tylko odbierać dane po rs z ustalona prędkością i jakoś je zapisywać. Fajnie było by gdyby te dane były jednobajtowe - szybciej się wtedy reaguje i są pojedyncze, szybkie warunki.
    Kwarc daj max jaki wyjdzie z wyliczeń (najchętniej bardzo blisko 24MHz)

    Encoder podłączony do intx, przerwanie na zbocze. W przerwaniu coś takiego:
    int0_przerwanie:
     if p1.2=0 then
      if licznik_encoder<255 then incr licznik_encoder
     else
      if licznik_encoder >0 then decr licznik_encoder
     endif
    return
    Albo tak(bo pewnie do menu to potrzebne):
    int0_przerwanie:
     if p1.2=0 then
      set bit_pomoc_plus
     else
      set bit_pomoc_minus
     endif
    return
    a w pętli programu będziesz sobie sprawdzał te bity, odpowiednio reagował i kasował je (reset).
  • #9
    robiw
    Level 26  
    Impulsator nie będzie pracował na przerwaniu tylko zwykle w pętli bo takie rozwiązanie wystarczy. W tejże pętli będą także wysyłane sygnały regulacyjne po I2C jako odpowiedź na regulacje wykonane impulsatorem oraz wyświetlane dane na LCD. Procedura obsługi przerwania od Rx (MIDI) odczytuje bajt i jeżeli równy jest 176 (nasze dane) to czyta dwa kolejne do 3 elementowej tablicy oraz ustawia flagę midi_active. W pętli programu głównego jest sprawdzana ta flaga i jeżeli jest ustawiona to dekodowane są 2 bajty z tablicy (2-gi i 3-ci) i rozkazy wysyłane po I2C a na końcu flaga jest kasowana. Chcę uniknąć tych zdarzeń w procedurze obsługi przerwania. Takie rozwiązanie ma jednak tę wadę, iż może się zdarzyć, że zanim nasze dane zostaną w głównej pętli programu zdekodowane i wysłane po I2C to przyjdą już nowe zamieniając tamte...może jakiś bufor? Dodatkowo, nie wiem, najlepiej której użyć instrukcji odczytu danej z MIDI przy użyciu Bascoma. Rezonator musi być 12MHz dla baud 31250... robiw
  • #10
    robiw
    Level 26  
    ...nikt nie pomoże w wyborze rozwiązania/instrukcji pod Bascomem? robiw

    Dodano po 17 [minuty]:

    i jak zrealizować format danych MIDI:
    rozkaz ma 10 bitów - bit startu, 8 bitów danych, 1 bit stopu (bez kontroli parzystości)? robiw
  • #11
    Jacek1708
    Level 12  
    miałem podobny problem. Przerwanie od UART powodowało że program wpadał w przerwanie i nie chciał wyjść. Zrezygnowałem z przerwania i w pętli głównej wstawiłem Zmienna = inkey ; if zmienna = ??? then ???. to rozwiązanie nie powoduje przerwania ale trzeba czekać aż program w pętli dojdzie do tego punktu. Wszystko zależy czy ma natychmiast reagować na przerwanie, czy może poczekać aż wykona polecenia w pętli głównej i dojdze do tego momentu.
  • #12
    robiw
    Level 26  
    Jacek1708 wrote:
    miałem podobny problem. Przerwanie od UART powodowało że program wpadał w przerwanie i nie chciał wyjść. Zrezygnowałem z przerwania i w pętli głównej wstawiłem Zmienna = inkey ; if zmienna = ??? then ???. to rozwiązanie nie powoduje przerwania ale trzeba czekać aż program w pętli dojdzie do tego punktu. Wszystko zależy czy ma natychmiast reagować na przerwanie, czy może poczekać aż wykona polecenia w pętli głównej i dojdze do tego momentu.


    Reagować nie musi tak natychmiast ale Twoje rozwiązanie może spowodować, iż wiele danych wysłanych po MIDI zostanie utraconych bo program będzie w tym czasie znajdował się w innym miejscu. Myślę nad tym, czy by danych z MIDI nie ładować do jakiejś zmiennej/bufora z indeksem a potem w pętli "do loop" odczytywać je i przesyłać przez I2C. To rozwiązanie nie daje jednak także pewności co do możliwości utracenia danych gdy będzie ich przesłanych sporo w jednostce czasu... robiw
  • #13
    Jacek1708
    Level 12  
    Po warunku If Then możesz dać polecenie Midi nadaj >< słuchaj MIDI ładuj do bufora wróć do programu
  • #14
    robiw
    Level 26  
    Znalazłem i zmieniłem taki kod:
    
    Dim Dana(3) as byte
    Dim Midi as Bit
    
    Serial_int:
       If scon.0= 1 Then
          Dana[1] = Sbuf
          Set Midi
          scon.0=0 'zerowanie flagi rx
       else
          scon.1=0 'zerowanie ew. flagi tx
       End If
    Return
    


    I teraz tak:
    1.czy przerwanie będzie zgłaszane po każdym bajcie, który nadejdzie po Midi (RS)... bo program ma reagować na dane z Midi i jeżeli odczyta bajt=176 (I TYLKO WTEDY) to ma odczytać 2 kolejne i ustawić zmienną Midi aby program w pętli głównej "przerobił" te dane i wysłał po I2C. Jak to przerobić? robiw