Skocz do zawartości

STM32 UART wysyłanie danych typu uint16_t


radek04

Pomocna odpowiedź

Bardzo dobry pomysł z wysyłaniem ustalonej wartości. Przetestowanie działania to zawsze dobra opcja 🙂

Jak napisałem wcześniej - używaj HAL_UART_Transmit() zamiast HAL_UART_Transmit_IT(). Poprawny wynik to raczej 01 00 niż 00 01, ale na pewno nie F7 28.

Link do komentarza
Share on other sites

Zacznij od naprawienia transmisji, jak już odbierzesz 01 00, to wtedy będzie trudniejsze ćwiczenie - przesłać uint32_t o wartości 0x12345678. Zagadka: co wtedy powinno pojawić się po stronie odbiorcy?

Link do komentarza
Share on other sites

Z użyciem HAL_UART_Transmit() też otrzymuję wartości F7 A8 (czasem A8 F7).
Co to może oznaczać?
Próbowałem z innymi wartościami i zawsze są dla mnie niezrozumiałe.
Wartości 0x00 w ogóle nie wyświetla.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

Wielkie dzięki. Teraz działa. Sugerowałem się fragmentem kodu z kursu:

 ++cnt;
 size = sprintf(data, "Liczba wyslanych wiadomosci: %d.\n\r", cnt);
 HAL_UART_Transmit_IT(&huart1, data, size);

Ale tam faktycznie jest trochę inna struktura.

A dlaczego najpierw przesyłany jest młodszy bajt? Tak powinno być, czy na swoje potrzeby lepiej to zmienić?
Próbowałem z opcją MSB first, ale to zamienia bity w ramach bajtów, kolejność bajtów wciąż bez zmian.

Edytowano przez radek04
Link do komentarza
Share on other sites

2 minuty temu, radek04 napisał:

Sugerowałem się fragmentem kodu z kursu:

Jeśli to kurs STM32F4 to radziłbym się nim nie sugerować 🙂 

Nawet znak końca linii jest niepoprawny, a użycie HAL_UART_Transmit_IT może zadziałać jedynie przypadkiem.

Link do komentarza
Share on other sites

To że czasem działa, to nie znaczy że jest to poprawny kod. Dlatego radziłbym zaczynać od używania HAL_UART_Transmit(), a do wersji _IT lub _DMA podejść ostrożnie, bo ich użycie jest już nieco trudniejsze.

Link do komentarza
Share on other sites

18 minut temu, radek04 napisał:

A dlaczego najpierw przesyłany jest młodszy bajt?

Bo to architektura Little Endian, tak samo z resztą jak x86 czy ten ARM co jest w Rpi. I dlatego...

19 minut temu, radek04 napisał:

Tak powinno być, czy na swoje potrzeby lepiej to zmienić?

... nie zmieniaj, nie ma sensu, na x86 albo ARM użytym w malince reprezentacja danych jest identyczna. Chyba nie ma obecnie żadnego popularnego CPU pracującego z danymi Big Endian a te co mogą pracować w obu trybach i tak pracują w LE.

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

No dobrze, to już sobie po stronie PC chyba poukładam jakoś. Ale obawiam się, ze bez IT lub DMA będzie mi chodziło za wolno. Więc albo ogarnę to, albo będę zapisywał na kartę pamięci. Ale z tym kiedyś też się męczyłem i mi nie działało. No ale to już jest temat na inny wątek.

Jaki powinien być ten znak końca linii? 

Naprawdę jest taki kłopot z IT oraz DMA przy UART?

Link do komentarza
Share on other sites

@radek04 Problemem nie jest używanie przerwań (_IT), ani DMA tylko prędkość transmisji. Sam sobie policz ile chcesz przesłać bitów na sekundę oraz sprawdź ile UART może przesłać. Używanie HAL_UART_Transmit zajmuje tyle samo czasu co wersji z DMA, różnica jest tylko taka, że w czasie gdy DMA przesyła dane, program może robić coś innego. Ale to nie poprawi prędkości UART ani trochę. Natomiast pojawią się problemy z buforem - to co jest w przykładach kursu F4 nie zadziała, bo bufor jest alokowany jako zmienna lokalna, więc przestaje być ważny po wyjściu z funkcji, a przerwania lub DMA przesyłają dane dalej. Używanie DMA czy przerwań nie jest bardzo trudne, ale zacznij od działającej wersji z blokowaniem, a więc HAL_UART_Transmit. Dopiero jak to będzie działać, wtedy warto poszukiwać usprawnień. Przedwczesna optymalizacja to zawsze błąd.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Jasne. Dzięki za pomoc. 

Zwykle przesyłałem już przetworzone w uC dane. Wtedy IT lub DMA sie przydaje. Ale chyba szybciej będzie przesłać dane uint16_t niż float? Czy nie? Bo jeśli float mogę przesłać na 1 bajcie, to będzie szybciej. Tylko nie umiem inaczej niż z użyciem (s)printf, a to - jak wspominałem wcześniej - jest zbyt czasochłonne.

Link do komentarza
Share on other sites

19 minut temu, radek04 napisał:

Bo jeśli float mogę przesłać na 1 bajcie

To dostaniesz Nobla. Float ma cztery bajty (no, float16 ma dwa ale to i tak więcej niż jeden).

Uprzedzając: widziałem ośmiobitowe floaty, ale tylko raz i w bardzo specyficznym zastosowaniu.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.