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

Jak odczytać łańcuch znaków z PC do AVR przez RS232 w przerwaniu?

mikee 28 Lis 2006 22:03 1760 7
REKLAMA
  • #1 3274013
    mikee
    Poziom 11  
    Posty: 33
    Pomógł: 1
    Witam,

    Czy wie ktoś może jak odczytać dane wysyłane z PCta przez RS232 do AVR, przy czym dane w procku maja być odczytywane w przerwaniu.
    Wiem jak odczytać pojedyńczy znak, ale nie potrafie odczytać łańcucha skladającego sie z kilku(nastu) znaków wysłanych z PC.
    Kod piszę w C.

    Dziękuję za każdą pomoc!
  • REKLAMA
  • #2 3274110
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Zrób sobie zmienną globalną, która będzie indeksować łąńcuch bufora. W przerwaniu odczytujesz znak, wrzucasz do bufora pod baj o danym indeksie, zwiększasz indeks. Kiedy już przyjdzie znak końca łańcucha zerujesz indeks, a daną masz w buforze. Możesz ją jeszcze przepisać do innej zmiennej, by jej nie stracić, gdy zacznie się odbiór następnego łańcucha :]
  • REKLAMA
  • #3 3274218
    mikee
    Poziom 11  
    Posty: 33
    Pomógł: 1
    OK. pomysł mam ten sam tylko jak go zrealizować w C?
    Mam coś takiego do odbierania znaku:
    
    SIGNAL(SIG_UART_RECV)
    {
       znak=UDR;
    }
    

    jak to zmienić by odebrać cały łańcuch?

    Próbowałem też sprawdzać flagę zgłoszenia przerwania RXC jak poniżej:
    
    SIGNAL(SIG_UART_RECV)
    {
       while(! (UCSRA & (1<<RXC)))
                tablica[index++]=UDR;
    }
    
    

    ale nie to też nie działa. Być może sam kod jest błędny.

    Proszę o pomoc!
    Pozdrawiam
  • #5 3274504
    adamusx
    Poziom 27  
    Posty: 977
    Pomógł: 94
    Ocena: 28
    
    SIGNAL(SIG_UART_RECV)
    {
       while(! (UCSRA & (1<<RXC)))
                tablica[index++]=UDR;
    }
    


    W tym przypadku nie musisz sprawdzac flagi od odebranego ( UCSRA & (1<<RXC) ) znaku gdyz flaga ta jest ustawiana przy wejsciu w przerwanie i zerowana w przerwaniu.


    Najprościej to moglo by wygladac tak.


    SIGNAL(SIG_UART_RECV)
    {


    unsigned char Bufor;

    Bufor = UDR;

    if (index != 0){
    Bufor[index++] = Bufor;
    }

    if (index == BUFOR_SIZE){
    Frame_Rev_Flag = 1;
    index = 0;
    }

    }
    W przerwaniu po odebraniu znaku, kolejny znak zapisywany jest do tablicy Bufor[index] . Po odebraniu okreslonej liczby znakow o rozmiarze BUFOR_SIZE ustawiana jest flaga Frame_Rev_Flag. W glownej czesci programu sprawdzasz czy Frame_Rev_Flag =1 i wowczas wiesz ze w buforze jest okreslona liczba znakow ktor mozesz odczytac. Po odczytaniu ustawiasz Frame_Rev_Flag na 0.
  • REKLAMA
  • #6 3276106
    pubus
    Poziom 30  
    Posty: 1289
    Pomógł: 138
    Ocena: 31
    Kolega adamusx wypisuje jakieś herezje...
    Po pierwsze deklaracja zmiennej w obsłudze przerwania...
    Druga sprawa, Bufor jest deklarowany jako zmienna unsigned char po czym przemienia się w tablicę...
    No chyba, że Bufor i Bufor to nie to samo... ;)
    W takim razie powinny mieć inne nazwy albo przynajmniej Bufor i bufor... to wystarczy...
    Proponowana metoda sprawdzi się jeżeli każda paczka ma taką samą długość (w bajtach)...
    Jeżeli długość jest różna można zastosować znaki, a właściwie ich wartość z kodu ASCII które są rzadko używane... chodzi o początkowe liczby które w kodzie ASCII oznczają jakieś krzaczki... jako kody początku i końca ramki danych...
  • #7 3276360
    adamusx
    Poziom 27  
    Posty: 977
    Pomógł: 94
    Ocena: 28
    Nie herezje tylko pisalem to na szybko i wdarł się ten błąd.

    Oczywiscie zmienna Bufor nie moze miec takiej samej nazyw jak tablica do przechowywania danych .

    Powinno to wygladac tak>

    
    SIGNAL(SIG_UART_RECV)
    {
    
    
    unsigned char Bufor;
    
    Bufor = UDR;
    
    if (index != 0){
    ReceiverTabl[index++] = Bufor;
    }
    
    if (index == BUFOR_SIZE){
    Frame_Rev_Flag = 1;
    index = 0;
    }
    
    } 
    


    , a ReceiverTabl zdefiniowany globalnie.


    To bylo wzorowane na przykladzie twóryc postu, miało pokazywac główna idee odebrania kilku znaków, jednak oczywiscie nie jest to sposob najlepszy.

    A od kiedy to NIE mozna deklarować zmiennej w obsłudze przerwania???
    Mozna deklarować zmienne nawet typu STATIC ! .
  • REKLAMA
  • #8 3277600
    pubus
    Poziom 30  
    Posty: 1289
    Pomógł: 138
    Ocena: 31
    Ale jaki to ma sens...???
    Czy przypadkiem zmienna nie jest tworzona i kasowany przy każdym wejściu w przerwanie...?
    A więc spowalnia to tylko jego obsługę...
    Oczywiście w przypadku pc nie jest to nic dziwnego i sam tak robię ale na uC to chyba nie jest dobry pomysł...

Podsumowanie tematu

✨ Dyskusja dotyczy odczytu łańcucha znaków przesyłanych z komputera PC do mikrokontrolera AVR przez interfejs RS232 w obsłudze przerwania. Problem polega na tym, jak w przerwaniu UART odbierać nie pojedynczy znak, lecz ciąg znaków. Proponowane rozwiązanie to wykorzystanie globalnej tablicy buforowej oraz indeksu do zapisywania kolejnych odebranych znaków w procedurze obsługi przerwania SIG_UART_RECV. Po odebraniu całej ramki danych (np. po osiągnięciu ustalonego rozmiaru bufora lub po wykryciu znaku końca łańcucha) ustawia się flagę informującą o gotowości danych do przetworzenia w głównej pętli programu. Dyskutowano także o poprawnej deklaracji zmiennych w przerwaniu, unikaniu deklaracji zmiennych lokalnych, które są tworzone i kasowane przy każdym wywołaniu przerwania, oraz o możliwości stosowania znaków ASCII jako delimitery początku i końca ramki danych dla zmiennej długości łańcuchów. Podkreślono, że mikrokontrolery AVR posiadają sprzętowe wsparcie USART, co ułatwia implementację odbioru danych w przerwaniu.
Wygenerowane przez model językowy.
REKLAMA