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.

[BASCOM] Odczyt UART w przerwaniu a obróbka danych

xury 25 Paź 2009 01:38 3963 4
  • #1 25 Paź 2009 01:38
    xury
    Poziom 39  

    Napisałem sobie taką oto procedurę odczytu z UART w przerwaniu:

    Code:
    Odczyt:
    
     Znak = Udr

     If Bc < Cmaxchar Then
        Incr Bc
        Select Case Znak
         Case 13                    'pomijanie CR
         Case 10                    'koniec odczytu  linii z UART
            If Znak <> "" Then
               Bc = Cmaxchar
               B = 1                 'flaga odebrania CRLF
            End If
         Case Else
         Todczyt = Todczyt + Chr(znak)
        End Select
     End If
    Return


    Tylko teraz nie jestem pewien co zrobić by odczytane dane trafiły w odpowiednie miejsce w programie głównym.

    Wymyśliłem że może to zrobić tak:

    Code:
    do
    
    ...
    'jakieś instrukcje
    C=1                         'flaga miejsca w które ma trafić odczytana zmienna Todczyt
    Print komenda AT       '
    if B=1 and C=1 then
      instrukcje obsługujace zmienną Todczyt
      B=0
    endif
    C=0
    ....
    kolejne instrukcje
    C=2
    Print kolejna komenda AT
    if B=1 and C=2 then
     instrukcje obsługujące zmienną Todczyt
     B=0
    endif
    ....
    loop


    I tak dalej, czyli aby mieć pewność że zmienna Todczyt zawiera odpowiednie dane i są one umieszczane w odpowiednim miejscu muszę stosować dodatkową flagę C która jest zmienną typu Byte.
    Czy może istnieje inny sposób ? Jak wy to rozwiązujecie ?

    0 4
  • #2 25 Paź 2009 08:23
    mirekk36
    Poziom 42  

    Tak w Bascomie istnieje idealny sposób aby rozwiązać odbiór znaków przez RS232 (także nadawanie) - za pomocą przerwań. A kod zajmie kilka linijek.

    Wystrczy zapoznać się dogłębnie z takim poleceniem jak Config Serialin oraz wykorzystaniem np jednego z parametrów do tego polecenia - Bytematch (ale także innych)

    wtedy przy minimum wysiłku i kodowania będziesz miał nie tylko wzorowo zrobioną obsługę takiej transmisji na przerwaniach ale także piękne buforowanie

    pomyśl o tym

    0
  • #3 25 Paź 2009 14:31
    xury
    Poziom 39  

    Tak Bytematch to pożyteczna funkcja, tylko ona nie pomoże mi w moim problemie. To znaczy upewnieniem się, że odczytane dane trafią w odpowiednie miejsce. No chyba, że nie za bardzo rozumiem działanie przerwania. Taktowanie uC mam ustawione na 8 Mhz, a prędkość UART na 9600 bps. Po odebraniu znaku program powraca do przerwanego działania w pętli głównej i zdąży obiec pętlę główną kilkaset razy zanim nadejdzie następny znak itd. więc obawiam się, że zostaną podstawione w złym miejscu w programie. Mógłbym zabezpieczyć sie przed tym korzystając za każdym razem z innych zmiennych, ale to marnotrawstwo RAMu, lub przed każdym odczytem z UART ustawiać inną flagę.
    I chyba widzę, że nie ma innego wyjścia. Bo niby po czym innym program ma poznać czy odczytane dane pasują w tym określonym miejscu ?

    0
  • Pomocny post
    #4 25 Paź 2009 15:08
    mirekk36
    Poziom 42  

    No, coś mi się wydaje, że jednak może nie do końca rozumiesz właśnie to wszystko i stąd takie podajęcie.

    Co to w ogóle dla ciebie znaczy, że:

    Cytat:
    Bo niby po czym innym program ma poznać czy odczytane dane pasują w tym określonym miejscu ?


    .... toż twoja próba obsługi tego przerwania - pokazuje, że w 1000% mógłbyś wykorzystać mechanizm z Bytematch

    Ustawiłbys sobie poleceniem Config SerialIn - poza długością bufora itp - także to aby była zgłaszana poprzez przerwanie procedura Bytematch - która właśnie nastąpi gdy nadleci kolejny znak CR. Wtedy w obsłudze tej procedury możesz spokojnie ustawiać sobie flagę

    a następnie w pętli głównej - badać tę flagę - i jeśli jest ustawiona to odczytywać z bufora wszystkie znaki aż do momentu wystąpienia właśnie CR. Czyli spokojnie obsłużyć sobie wtedy w pętli głównej i sparsować jakieś tam nadlatujące polecenie AT. Nawet jak obsługa jednego polecenia powiedmy trwałaby dłużej - to będziesz spokojny, ponieważ Bascom zadba aby kolejne nadlatujące znaki nadal ładnie wpadały do bufora

    Wtedy znowu gdy pętla główna dojdzie do sprawdzenia tej flagi i okaże się że znowu nadszedł jakiś łańcuch danych zakończonych znakiem CR - to znowu go obsługujesz i tak dalej itd itd

    (tzn pewnie, że można to robić samemu na piechotę i pisać obsługę takiego przerwania - ale po co - skoro jeśli używasz Bascoma to masz na prawdę dobrego gotowca, który cię wyręcza w tym momencie - a ty możesz zająć się pisaniem pozostałej części swojego kodu. Stracisz mniej czasu i pamięci programu na pisanie własnej obsługi - bo piszesz ją w Bascomie, a oryginalna procedura obsługi ta Bascomowska jest ładnie napisana i zoptymalizowana w asemblerze. Wiadomo bywają potrzeby gdy i ona nie wystarcza - ale w tym przypadku??? - to można ją jak pisałem wykorzystać w 1000%)

    0
  • #5 25 Paź 2009 15:56
    xury
    Poziom 39  

    No tak tylko, że zdarza mi się oczekiwać na bardzo długą linię np. 80 bajtów czyli bufor musiałby też tyle mieć i zmienna stringdo której kopiuję bufor po odebraniu CR też, to jest juz 160 bajtów, a poza nimi muszę mieć kilka innych zmiennych potrzebnych do parsowania. I inne do innych celów, i SRAM na obsługę stosów i ramkę. Więc zdecydowałem, że nie będę czekał na odebranie CR za pomocą Bytematch=13 lecz użyję Bytematch=ALL. Jakkolwiek bym tego nie zrobił to jedna flaga nie wystarczy, bo oprócz spodziwanych danych z uart mogę otrzymać takrze niespodziewane po nadejściu SMS i wlaśnie te dane (ciąg PDU o dlugości około 80 bajtów mogą mi skaszanić parsowanie jeśli nie znajdą się w odpowiednim miejscu w programie.
    Celowo nie chciałem buforować właśnie z tego powodu.
    Nie chcę też dawać innych pętli w pętli głownej, bo mój program nie może zapętlać się we fragmentach z powodu nadchodzących SMS wlasnie.
    Więc jedynie mi pozostaje ustawianie różnych flag przed odczytem, bo jesli ustawię flagę w procedrze obsługi Serial0ByteReceived lub Serial0CharMatch to zawsze będzie to taka sama flaga, a wtedy to nie mam pewności czy zmienna Todczyt ma w tym miejscu właśnie takie dane jakie potrzebuję

    Ok już wiem. Są dwie możliwości zabezpieczenia odczytanej linii z Uart w przerwaniu tak by dane nie poleciały nie wiadomo gdzie:
    Pierwsza to dodatkowa flaga - wtedy sprawdzając stan flagi parsujemy dane w odpowiednim miejscu. Pętla sobie lata w kółko i może robić co innego.
    Druga to dodatkowa pętla która nie pozwoli na przejście dalej zanim nie oebrana będzie cała linia

    0