Skocz do zawartości
Komentator

Kurs STM32 F4 - #7 - Komunikacja przez UART

Pomocna odpowiedź

html_mig_img
Tworząc system, w którym mikrokontroler będzie współpracował z innymi urządzeniami, należy w jakiś sposób przesyłać między nimi dane.Bardzo częstym rozwiązaniem, które implementują konstruktorzy jest UART. W tym odcinku skupimy się na opisie tego interfejsu od strony teoretycznej oraz praktycznej z użyciem kreatora Cube oraz bibliotek HAL.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Udostępnij ten post


Link to post
Share on other sites

Siemka,

Kurs super, ale mam jedno pytanie, jak stworzyć swoją bibliotekę (gdzie umieścić w tej strukturze katalogów) tak żeby można było ją zainkludować do pliku "main.c" ?. Z AVRami pod eclipse nie miałem żadnego problemu a tutaj nie wiem gdzie to wrzucić.

pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

darek12, tam, gdzie będzie Ci wygodniej. Przy kilku plikach możesz je umieścić nawet bezpośrednio "obok" main.c, przy większej ilości warto stworzyć sobie foldery, które ułatwią poruszanie po projekcie. Wystarczy wgrać plik w odpowiednie miejsce i zaimportować go do projektu.

Udostępnij ten post


Link to post
Share on other sites

Witam,

Kolejny odcinek kursu super, więc dzięki!!!

Ale odnośnie tego co pisał darek12 to utworzyłem sobie dwa pliki common.c i common.h obok main.c, przeniosłem definicje void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) do common.c i deklaracje do common.h. Następnie zainkludowałem w main.c common.h i lipa- No such file or directory i same błędy. Tak też robiłem pod eclipse dla avr, ale tu są te znaczniki z Cube3d i pewnie robi się to troche inaczej. Może jakiś przykład jak podzielić program na bloki, funkcje przenieść do osobnych plików. Coś w ten deseń

https://www.forbot.pl/forum/upload_img/obrazki/IMG_5755d0375fac64077.png

Udostępnij ten post


Link to post
Share on other sites

Witam

Czy da się pisać w C++ korzystając z HAL?

Ze strony github.. wynika że tak, tyle że tam jest projekt pod KEILa.

W ECLIPS (sw4stm32) po wygenerowaniu projektu w CUBE i przekonwertowaniu do C++ nagłówki plików stm32F4xx_hal_**.h są widoczne tylko w main. Po utworzeniu pliku np my_lib.hpp nie działa w nim

#include "stm32f0xx_hal.h"

Unresolved inclusion: "stm32f0xx_hal.h"

Da się wykonać include ale podając ścieżkę do pliku

#include "../../../../Drivers/STM32F0xx_HAL_Driver/INC/stm32f0xx_hal.h"

i taki inklude działa ale nie do końca bo nie widać funkcji np HAL_GPIO_Write(.....)

Czy udało się komuś stworzyć np jakąś klasę (nie w pliku main.c) z wykorzystaniem HAL?

Udostępnij ten post


Link to post
Share on other sites
Witam,

Kolejny odcinek kursu super, więc dzięki!!!

Ale odnośnie tego co pisał darek12 to utworzyłem sobie dwa pliki common.c i common.h obok main.c, przeniosłem definicje void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) do common.c i deklaracje do common.h. Następnie zainkludowałem w main.c common.h i lipa- No such file or directory i same błędy. Tak też robiłem pod eclipse dla avr, ale tu są te znaczniki z Cube3d i pewnie robi się to troche inaczej. Może jakiś przykład jak podzielić program na bloki, funkcje przenieść do osobnych plików. Coś w ten deseń

https://www.forbot.pl/forum/upload_img/obrazki/IMG_5755d0375fac64077.png

Plik do zaimportowania którego szukasz znajduje się na początku pliku main:

#include "stm32f4xx_hal.h"

Dodaj go w swoim nowym pliku *.h i będziesz mógł korzystać w nim ze wszystkich funkcji, które poznaliśmy w kursie 🙂

[ Dodano: 07-06-2016, 11:29 ]

Witam

Czy da się pisać w C++ korzystając z HAL?

Nigdy nie interesowałem się tym tematem, więc na ten moment nie potrafię niestety odpowiedzieć na Twoje pytanie.

Udostępnij ten post


Link to post
Share on other sites
Witam,

Kolejny odcinek kursu super, więc dzięki!!!

Ale odnośnie tego co pisał darek12 to utworzyłem sobie dwa pliki common.c i common.h obok main.c, przeniosłem definicje void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) do common.c i deklaracje do common.h. Następnie zainkludowałem w main.c common.h i lipa- No such file or directory i same błędy. Tak też robiłem pod eclipse dla avr, ale tu są te znaczniki z Cube3d i pewnie robi się to troche inaczej. Może jakiś przykład jak podzielić program na bloki, funkcje przenieść do osobnych plików. Coś w ten deseń

https://www.forbot.pl/forum/upload_img/obrazki/IMG_5755d0375fac64077.png

Siemka, posiedziałem trochę i w końcu udało mi się dodać swoją bibliotekę do projektu. Poniżej screen ,na którym widać gdzie to należy zrobić.

Udostępnij ten post


Link to post
Share on other sites

Witam, problem mój polega na tym, że eclipse wyrzuca mi warningi przy funkcjach typu sprintf(pointer targets in passing arguments 1 of 'sprintf') lub atoi (Implict declaration of function atoi). Kod mam linijka w linijke taki sam jak z kursu, ktoś się spotkał z podobnym problemem?

Pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

Magit, komplikacja przebiega dalej poprawnie i możesz wgrać program do mikrokontrolera, czy pojawiają się później jakieś błędy?

Udostępnij ten post


Link to post
Share on other sites

Magit, ja pracuje na Keilu 5 i też mi wyrzuca warninga do atoi (implicit declaration of function 'atoi' is invalid in C99) oraz wyrzuca mi warninga do size (passing 'uint8_t [50]' to parameter of type 'char*' converts between pointers to integer types with different sign).

Jestem początkujący(coś tam wcześniej dzióbałem ale nie z takim zrozumieniem jak teraz) i zaczynam się uczyć na tych artykułach i w miarę możliwości doczytywać na internecie ale nie mogę sobie poradzić z tym problemem.

Udostępnij ten post


Link to post
Share on other sites

Witam, co do atoi to prototyp funkcji wygląda tak:

int atoi (const char *string);

i wystarczy zastosować zwykłe rzutowanie czyli linijka z funkcją atoi powinna wyglądać tak:

switch (atoi((char*)&Received)) {

Udostępnij ten post


Link to post
Share on other sites

Korzystając z wolnej chwili postanowiłem przeczytać nieco dokładniej kurs STM32F4 i mam kilka uwag odnośnie tej części:

1) istnieją różne standardy kodowania końca linii, ale opisany w artykule jest chyba najmniej popularny. Zamiast \n\r powinno być \r\n - oczywiście zakładam, że autor chciał uzyskać zgodność z Windowsem, bo jeśli z zabytkowym Acorn BBC to jest w porządku. Ten błąd jest niestety częsty i nawet w pracy się z nim spotkałem, stąd prośba o korektę - jak już się ktoś ma uczyć to chociaż poprawnie. Więcej informacji o kodowaniach końca linii jest np. tutaj: https://en.m.wikipedia.org/wiki/Newline

2) przykład opisujący odbieranie wiadomości o długości "1" jest nie do końca poprawny. W momencie otrzymania przerwania, program "na ślepo" wysyła dane - a powinien najpierw sprawdzić, czy nie trwa wysyłanie innego komunikatu. Dlatego otrzymane wyniki są błędne, ale trudno oczekiwać lepszych, jeśli w połowie transmisji wysyłamy nowe dane.

3) podobnie jest w dalszej części - problem jest niewidoczny jeśli odbieramy więcej danych, niż wysyłamy, ale sam błąd jest identyczny. Więc poprawić należy logikę programu, a nie powiększać bufor odbiorczy.

4) jak chodzi o DMA, to bufor musi być dostępny przez cały czas transmisji. Zmienne lokalne tworzone są na stosie, więc w momencie zakończenia wykonywania procedury ich zawartość będzie zastąpiona innymi danymi. Ponieważ program może wyjść z zakresu zmiennej, zanim transmisja się zakończy, transmitowane dane są mocno losowe - a im dłużej trwa transmisja, tym większe prawdopodobieństwo, że zamiast komunikatu wyślemy zrzut zawartości stosu. To prawdopodobnie tłumaczy pytanie w artykule - skąd dziwne dane na końcu komunikatu. Zmienne globalne oraz statyczne są alokowane "na stałe", ich zawartość nie jest niszczona po wyjściu z funkcji i dlatego program działa poprawnie.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Elvis, dziękuję za sugestie - przekażę do autora kursu i przy najbliższej aktualizacji kursu zajmiemy się tym tematem 🙂

Udostępnij ten post


Link to post
Share on other sites

Mam mały problem, program dla uart3 działa tak:

1. Odbieram przerwaniem po usart

2. Wysyłam co odebrałem z małą modyfikacją

Postanowiłem nadawać i odbierać na dwóch magistralach jednocześnie, przy czym jedna to RS485 do której potrzebny był kierunek(PA1). Elektronika działa bo jak ustawie w pętli głównej odbiór przerwe 1000ms i wysył i przerwe 1000ms to wszystko chula, a jak zrobie to w przerwaniach to uart 3 działa a rs485 tylko odbiera:


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); //DIR na wysyłanie
uint8_t Data[40]; // Tablica przechowujaca wysylana wiadomosc.
uint16_t size = 0; // Rozmiar wysylanej wiadomosci

size = sprintf(Data, "Odebrana wiadomosc: %s\n\r",Received);
HAL_UART_Transmit_IT(&huart3, Data, size); // Rozpoczecie nadawania danych z wykorzystaniem przerwan
HAL_UART_Transmit_IT(&huart2, Data, size); // Rozpoczecie nadawania danych z wykorzystaniem przerwan

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); //DIR na odbieranie
HAL_UART_Receive_IT(&huart3, Received, 10); // Ponowne włączenie nasłuchiwania
HAL_UART_Receive_IT(&huart2, Received, 10); // Ponowne włączenie nasłuchiwania

//HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_2);
}

Dla RS485 działa odbiór tak jakby coś blokowało wysył.

Wszystko wskazuje na problem z kierunkiem, zmieniłem prędkość portu na najszybszą ale nic to nie dało, Clear i rebild też nie. POMOCY!

Udostępnij ten post


Link to post
Share on other sites

Problem rozwiązany, za szybko zmieniałem pin i wiadomość nie zdążyła zostać wysłąna, program teraz wygląda tak:


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); //DIR na wysyłanie
uint8_t Data[40]; // Tablica przechowujaca wysylana wiadomosc.
uint16_t size = 0; // Rozmiar wysylanej wiadomosci

size = sprintf(Data, "Odebrana wiadomosc: %s\n\r",Received);
//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
HAL_UART_Transmit_IT(&huart3, Data, size); // Rozpoczecie nadawania danych z wykorzystaniem przerwan
HAL_UART_Transmit_IT(&huart2, Data, size); // Rozpoczecie nadawania danych z wykorzystaniem przerwan


}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); //DIR na odbieranie
HAL_UART_Receive_IT(&huart3, Received, 10); // Ponowne włączenie nasłuchiwania
HAL_UART_Receive_IT(&huart2, Received, 10); // Ponowne włączenie nasłuchiwania
}


  • Lubię! 1

Udostępnij ten post


Link to post
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!

Gość
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...