Wstyd się przyznać, ale pieprzyłem się z tym cały dzień, a przecież to wyjątkowo prosty program.
STM32CubeIDE nigdy nie używałem, choć próbowałem kilka razy. Największym problemem jest niedostępność dokumentacji. To znaczy, że dokumentacja na pewno jest, ale znaleźć ją w Internecie nie sposób. O co by się Google nie pytać, to się dostaje sto linków do kretyńskich publikacji jakichś debili, którym coś się fuksem udało i mają imperatyw pochwalić się tym w necie...
Niemożliwością jest przekopać się przez te góry śmieci żeby odnaleźć wartościowe treści...
Najpierw myślałem że szlag mnie trafi, bo mi przy edycji pinów kasowało fragmenty mojego kodu. Rozwiązanie okazało się wyjątkowo proste - kod użytkownika należy wpisywać pomiędzy komentarzami "USER CODE BEGIN ..." a "USER CODE END ...", wtedy rekonfiguracja zostawia te fragmenty kodu tak, jak je zastała. Aż trudno w to uwierzyć, ale tak podstawowej informacji nie znalazłem nigdzie i sam się musiałem tego domyślić...
Drugie pół dnia zmarnowałem na przejście z arduinowego Serial.print() na standardowe printf(). O ile sposób przekierowania standardowego wyjścia na port szeregowy znalazłem od razu, to efekt był daleki od oczekiwań...
Otóż taki prosty kod doprowadzał mnie do szału:
Kod: Zaznacz cały
while (1)
{
printf("X%ld;Y%ld;Z%ld;", timer2_ovf + TIM2->CNT, timer3_ovf + TIM3->CNT, timer4_ovf + TIM4->CNT);
HAL_Delay(50);
}
Funkcja printf() działa poprawnie z podanymi argumentami, ale oczywiście pewny tego być nie mogłem.
Funkcja HAL_Delay() też działa poprawnie, czego też pewny być nie mogłem.
Tak więc szukałem przyczyny w składni, typach argumentów, a nawet w systemie przerwań...
Otóż wynik działania tej pętli można przewidywać w taki sposób, że co około 50 ms jest wysyłany jeden pakiet danych na port szeregowy, natomiast w rzeczywistości wypluwa ona wiele pakietów na raz, jak z karabinu maszynowego, po czym jest kilkusekundowa cisza...
W końcu okazało się, że przyczyną jest używanie przez funkcję printf() bufora... Najzwyczajniej printf() pisze do bufora, a nie bezpośrednio na wyjście, zawartość bufora jest natomiast wysyłana na wyjście w całości i do tego w momentach które trudno przewidzieć. Na szczęście można funkcję printf() zmusić do tego, żeby nie korzystała z bufora i wysyłała dane od razu na wyjście...
Powyższe jest doskonałym dowodem na to, że korzystanie z ArduinoIDE jest w dłuższej perspektywie głupotą.
Aczkolwiek pisanie prostych programów w tym środowisku jest dziecinnie proste, o tyle napisanie bardziej zaawansowanego kodu jest drogą przez mękę, najpierw zaczynają się schody, potem schody są coraz wyższe, a na koniec trafiamy na ścianę, na przykład w postaci bibliotek rozbabranych do połowy i porzuconych w takim stanie, czego doskonały przykład mamy tutaj.
Kodu napisanego w ArduinoIDE na STM32F103 nie da się w żaden sposób przenieść na STM32F401 tylko i wyłącznie z tego powodu, że autor ukrywający się pod ksywą CARLOS biblioteki dla F103 przerobił, a biblioteki dla F401 rozbabrał i porzucił, bo trafił na zbyt wiele problemów. Tutaj akurat ktoś sprawę totalnie spartaczył, tego kto to już nie wiem, ale albo biblioteki są z różnych wersji kompilatora, albo autor bibliotek miał kompatybilność w głębokim poważaniu. Dość powiedzieć, że argumenty pewnych funkcji w F103 są zadeklarowane jako zmienne, a w F401 jako stałe... Po prostu kod napisany pod F103 nie ma prawa zadziałać w F401 i faktycznie nie działa...
No a potem ktoś, kto korzystał z ArduinoIDE bo łatwo i szybko, musi zapomnieć o wszystkim czego się nauczył i zacząć wszystko od zera w jakimś poważniejszym środowisku, albo poprzestać na projektach na poziomie Blink...
Wracając do programu DRO napisanego na STM32CubeIDE, to wygląda na to, że wszystko działa jak powinno i kod będzie przenośny na dowolny STM32, pod warunkiem że posiada on potrzebne zasoby.
Niestety nie mam w tej chwili ani czasu, ani głowy żeby wszystko sprawdzić i dopieścić kod, więc na razie go nie opublikuję.