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 2569 11
REKLAMA
  • #1 7481555
    adambehnke
    Poziom 24  
    Posty: 882
    Pomógł: 23
    Ocena: 40
    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
    #2 7481674
    xury
    Specjalista automatyka domowa
    Posty: 7078
    Pomógł: 878
    Ocena: 1492
    Rozwiązanie jest proste :)
    Odbieraj 156 znaków.
    Po odebraniu znaku zwiększaj zmienną pomocniczą. Jeśli osągnie ona 156 to zakończ odbieranie.
    Użyj np. petli FOR..NEXT lub DO..LOOP UNTIL
  • REKLAMA
  • Pomocny post
    #4 7481717
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • Pomocny post
    #5 7481734
    xury
    Specjalista automatyka domowa
    Posty: 7078
    Pomógł: 878
    Ocena: 1492
    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.
  • Pomocny post
    #7 7481763
    xury
    Specjalista automatyka domowa
    Posty: 7078
    Pomógł: 878
    Ocena: 1492
    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  
    Posty: 882
    Pomógł: 23
    Ocena: 40
    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?
  • Pomocny post
    #9 7481796
    xury
    Specjalista automatyka domowa
    Posty: 7078
    Pomógł: 878
    Ocena: 1492
    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
  • REKLAMA
  • Pomocny post
    #11 7481817
    xury
    Specjalista automatyka domowa
    Posty: 7078
    Pomógł: 878
    Ocena: 1492
    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.

Podsumowanie tematu

✨ W dyskusji poruszono problem odbioru długiego ciągu znaków w module ATMEGA2560 przy użyciu sprzętowych UART. Użytkownik poszukiwał sposobu na odbieranie danych z innego modułu (ATMEGA32) w formacie protokołu, który nie może być zmieniony. Uczestnicy sugerowali różne metody, w tym odbieranie danych w przerwaniach oraz użycie bufora do przechwytywania znaków. Zwrócono uwagę na możliwość zliczania znaków po napotkaniu specyficznych sekwencji, takich jak "AT", oraz na wykorzystanie polecenia INPUT do odbioru danych. Ostatecznie problem został rozwiązany poprzez zastosowanie bufora i rozpoznawanie znaków "AT" w odebranych danych.
Wygenerowane przez model językowy.
REKLAMA