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

[Rozwiązano] [atmega328p][C] odczyt danych z uart z przerwania w pętli głównej

duke_luke 13 Wrz 2019 23:46 624 5
  • #1 18166889
    duke_luke
    Poziom 15  
    Witam,

    Mam potencjalnie banalny problem z odczytem stringa z przerwania UART w pętli głównej programu. Kiedy przesyłam przez UART ciąg znaków są one odbierane, jednak przy próbie wyświetlenia ich na wyświetlaczu którego obsługa znajduje się w pętli głównej programu zamiast przesłanego stringu widzę losowe śmieci z pamięci (np. fragmenty danych poprzednio wysłanych na wyświetlacz). Obsługa wyświetlacza nie jest tutaj problemem, bo tą część już sprawdziłem. Procedura obsługi przerwania której używam wygląda następująco:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    funkcja callbackowa print jest zdefiniowana w main.c jako:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    zmienna bt_buffer w main.c ma następującą deklarację:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    natomiast zmienna używana w przerwaniu od uart jest zadelarowana następująco:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Obsługa uart jest wyniesiona do osobnych plików (uart.c i uart.h) co sprawia, że mając bufor w przerwaniu jako static nie mogę go zadeklarować jako extern w main.c.

    Czy ktoś wie jak dane zapisane w UART_RxBuf przenieść do pętli głównej programu tak, aby przy okazji nie przejechać się po pamięci MCU?

    Pozdrawiam,
  • Pomocny post
    #2 18166927
    simw
    Poziom 27  
    Wg mnie dobrze kombinujesz z buforem statycznym.
    Jeśli masz tylko dość pamięci to powinieneś pójść tą drogą, a odpowiedź na Twoje pytanie jest dość proste, tak mi się wydaje.
    Zrób po prostu funkcję, która będzie zwracała wskaźnik do Twojego bufora, coś na kształt:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    W pliku nagłówkowym zadeklaruj funkcję:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Właśnie w ten sposób najlepiej łączyć różne moduły (jednostki kompilacji) poprzez funkcje, a nie zmienne globalne.
  • Pomocny post
    #3 18167027
    mpier
    Poziom 29  
    Witam, pomijając resztę, to mógłbyś wytłumaczyć jak działa ten fragment.
    duke_luke napisał:
    print(UART_RxBuf[tmphead], tmphead);
    Napisz jeszcze czy funkcja wysyłająca na LCD nie wymaga zera na końcu danych i dlaczego uruchamiasz ją z przerwania.
  • Pomocny post
    #4 18167118
    tmf
    VIP Zasłużony dla elektroda
    A kompilator nie zwraca ci żadnych ostrzeżeń? Niemożliwe. Zobacz na wywołanie;
    print(UART_RxBuf[tmphead], tmphead);
    wywołujesz funkcję o typie najpewniej (uint8_t, int), podczas gdy jej deklaracja wygląda tak:
    print(uint8_t* data, uint16_t len);
    Jak widzisz, funkcja oczekuje wskaźnika, stąd powinno być wywołanie;
    print(&UART_RxBuf[tmphead], tmphead);
    Poza tym wywołanie funkcji zapisu do LCD z przerwania to może niezbyt szczęśliwy pomysł - ile trwa ich wykonanie?
  • #5 18171322
    duke_luke
    Poziom 15  
    Dziękuję wszystkim za odpowiedzi! Finalnie problem rozwiązałem poprzez pobieranie w pętli głównej pojedynczych znaków z bufora cyklicznego zamiast próbować zrzucić cały bufor za jednym razem. Rozwiązanie działa, więc spełnia swoje zadanie :) Co od obsługi wyswietlania na LCD w przerwaniu - tutaj fakt, moje przeoczenie, zamierzenie było takie, żeby ta funkcja była dopiero w pętli gównej ale zapomniałem ją usunąć z callbacka. Tak, czy inaczej, temat uznaję za zamknięty :)
  • #6 18171325
    duke_luke
    Poziom 15  
    Dziękuję wszystkim za odpowiedzi! Finalnie problem rozwiązałem poprzez pobieranie w pętli głównej pojedynczych znaków z bufora cyklicznego zamiast próbować zrzucić cały bufor za jednym razem. Rozwiązanie działa, więc spełnia swoje zadanie :) Co od obsługi wyswietlania na LCD w przerwaniu - tutaj fakt, moje przeoczenie, zamierzenie było takie, żeby ta funkcja była dopiero w pętli gównej ale zapomniałem ją usunąć z callbacka. Tak, czy inaczej, temat uznaję za zamknięty :)

    Dodano po 1 [minuty]:

    Problem rozwiązany poprzez pobieranie pojedynczych znaków z bufora cyklicznego w pętli głównej programu zamiast próby zrzucenia całej zawartości bufora.
REKLAMA