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

ATMEGA2560[BASCOM] 4 uarty sprzętowe i odbiór ciągu znaków.

adambehnke 03 Sty 2010 23:33 2491 11
REKLAMA
  • #1 7481555
    adambehnke
    Poziom 24  
    Witam

    Dodam że szukałem na forum odpowiedzi na to pytanie ale nie znalazłem 100% pewnej informacji.
    Otóż posiadam w atmedze cztery sprzętowe uarty i na jednym z nich ma pracować mój poprzedni już działający moduł(którego już nie mogę przeprogramować aby zmienić coś).

    Transmisja wygląda tak:

    Z modułu A (atmega32) wysyłam poleceniem :

    Print #5 ,"RED"                         'to działa poprawnie 


    Moduł B na otrzymaną wiadomość tworzy coś w stylu swojego własnego protokołu i wysyła mi wartości interesujących mnie zmiennych takim poleceniem:

     Print Komenda ; Chr(13);                '  gdzie komenda to string


    o takiej treści:

    AT150T223T339T499UP44UW40UK40UB10SP10US1UL0UD1UO0R1088OP0C11C21C31C41C51P10P21P30P40P50P60P70P80KLU1KLD1KLL1KLR1KLM1KLE1R11R22R33R44R510R611R712R813R914QPM1 


    Dodam że takie zapytanie i odpowiedź będzie wysyłane cyklicznie co 10-20sekund.

    Teraz aby w module A który wysłał zapytanie (RED) odebrać ten długi tekst w przerwaniu pomyślałem że zrobię to tak:


    
    Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 
    
    Config Serialin3 = Buffered , Size = 160  ,Bytematch = 13        '13 bo znak końca to chr(13)
    
    



    Chciałem aby po odebraniu znaku końca (tzn. po wywołanym nim przerwaniu) wyciągnąć z bufora dane i przepisać do odpowiedniej zmiennej np . tak:

    Serial3bytereceived:
    
    odebrane dane = bufor
    
    Return


    Niestety to nie zadziała bo w przesyłanym tekście może wielokrotnie wystąpić znak 13. Jedyne pewne znaki to te na początku czyli "AT1". Więc nic z tego nie będzie.

    Pomyślałem żeby pozbyć się tego :

    Config Serialin3 = Buffered , Size = 160  ,Bytematch = 13


    i zastąpić to tym:

    Config Serialin3 = Buffered , Size = 160  ,Bytematch = ALL




    i odbierać dane w taki sposób:

    
    Serial3bytereceived:
    
    Dane = Inkey(#6)
    odebrane_dane = odebrane_dane + Chr(dane)
    
    return
    


    Co prawda to działa (kulawo ale działa) ale jeśli nastąpi szybkie wymienianie się informacji to nie da się zapanować nad odbieraniem w ww. przykład bo lubi zdublować odebrane dane i zamiast odebrać 156 znaków odbieram dwa razy tyle.

    Chciałbym koniecznie odbierać dane w przerwaniu (w sumie wysyłać także bym chciał w ten sposób) , i zrobić to tak że jak przyjdą dane(kompletne czyli 156 znaków) to aby zostały przepisane do zmiennej (np. odebrane_dane -oczywiście string) i aby jakaś flaga (np. dane_czekaja = 1 ) informowała że dane czekają.
    Dobrze aby można było odbierać i krótsze informacje np: "ABC" wysyłane z urządzenia B także w taki sposob:

     Print cisnienie ; Chr(13);                '  gdzie cisnienie to string


    Może niezbyt jasno to wszystko opisałem ale tak to wygląda. Wiem że już milion razy były podobne rzeczy na forum ale nie znalazłem nic co w 100% mi pomoże.
  • REKLAMA
  • Pomocny post
    #4 7481717
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • Pomocny post
    #5 7481734
    xury
    Specjalista automatyka domowa
    Odbieraj znaki w przerwaniu, a obsługę rób w pętli głównej, lub wyłączaj przerwanie po odebraniu pierwszego znaku, a potem załączaj.
    Możesz też sprawdzać czy nie pojawia się Twoje "jedynie pewne znaki"
    I po ich odebraniu "odciąć" ciąg.

    Masz jeszcze Ischarwaiting do zabawy.
  • REKLAMA
  • Pomocny post
    #7 7481763
    xury
    Specjalista automatyka domowa
    Ma się dobrze jeśli ma odbierać dane z bufora.
    Jeśli Twoje
    Cytat:
    Print Komenda ; Chr(13);

    zmieniłbyś na


    To z powodzeniem mógłbyś odbierać w przerwaniu
    Pozostało by ci tylko ustawić:
    Config Input = Crlf , Echo = Crlf
    Config Serialin = Buffered , Size = 80 , Bytematch = 13
    


    a przy odbieraniu:
    Input Odczyt Noecho
  • #8 7481767
    adambehnke
    Poziom 24  
    Czyli mógłbym tym poleceniem odebrać na raz całość jaka czeka na mnie w buforze (czyli przykładowo 156 znaków) ? I czy mogę sprawdzać np. w pętli głównej ile znaków czeka w buforze i ewentualnie czyścić bufor z poziomu pętli głównej jeśli uznam to za stosowne?
  • REKLAMA
  • Pomocny post
    #9 7481796
    xury
    Specjalista automatyka domowa
    Tak mógłbyś odbierać wszystkie znaki aż do wystąpienia CRLF
    Po wystapieniu znaku CR program skoczyłby do obsługi przerwania i poczekał na LF.
    Możesz sprawdzać z pętli głównej ilość znaków w buforze.

    Acha no chyba że w odbieranym ciągu przewidujesz nie zamierzone wystąpienie po sobie CRLF
  • Pomocny post
    #11 7481817
    xury
    Specjalista automatyka domowa
    Help > Config serialin

    The following internal variables will be generated for UART0:

    _RS_HEAD_PTR0 , a byte counter that stores the head of the buffer

    _RS_TAIL_PTR0 , a byte counter that stores the tail of the buffer.

    _RS232INBUF0 , an array of bytes that serves as a ring buffer for the received characters.

    _RS_BUFCOUNTR0, a byte that holds the number of bytes that are in the buffer.
REKLAMA