wierczewski Styczeń 12, 2019 Udostępnij Styczeń 12, 2019 (edytowany) do usunięcia Edytowano Styczeń 14, 2019 przez wierczewski napisałem głupoty :D Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Styczeń 14, 2019 Udostępnij Styczeń 14, 2019 (edytowany) Wydaje mi się, że ten post powinien być wydzielony z tematu, bo nie bardzo ma związek z kursem. Natomiast jak chodzi o podpowiedź, to proponowałbym zacząć od podstaw języka C, to co napisałeś jest straszne. Dnia 12.01.2019 o 13:09, wierczewski napisał: char *wybor=""; Tutaj tworzysz wskaźnik do pustego napisu, czyli bajtu o wartości zero - bo tak w języku C są przechowywane napisy. Dnia 12.01.2019 o 13:09, wierczewski napisał: strcat(*wybor,value); W tym miejscu dla odmiany starasz się dopisać coś do napisu, ale nie zarezerwowałeś tam miejsca więc w optymistycznej wersji zamazujesz przypadkowe dane w pamięci RAM. Dnia 12.01.2019 o 13:09, wierczewski napisał: if(*wybor=='aaa') Tutaj jest tyle błędów ile znaków w linii... Pojedynczy apostrof to znak, nie napis. Napisów się nie porównuje za pomocą ==. No i ten wybor nieszczesny nadal wskazuje na pusty napis - chociaż może już nie bo kasując losowe dane strcat może i coś zapisał. Jeszcze ta dereferencja zmiennej wybor - jest znakiem, a nie napisem. W każdym razie radziłbym kurs podstaw C zamiast takiego lepienia kodu metodą "a może zadziała". Edytowano Styczeń 14, 2019 przez Elvis 1 Cytuj Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Styczeń 14, 2019 Udostępnij Styczeń 14, 2019 @wierczewski, czyli reasumując - wprowadź w życie poprawki na błędy wskazane przez @Elvis i pokaż nową wersję kodu 😉 Cytuj Link do komentarza Share on other sites More sharing options...
wierczewski Styczeń 14, 2019 Udostępnij Styczeń 14, 2019 (edytowany) Prawie mi się udało... Został mi jedynie warunek porównania warunku z tym co wpisuje. Robiąc krok po kroku w debuggerze wszystko jest okej. Warunek i Value są identyczne a mimo to funkcja strcmp nie zwraca 0 tylko -18. Przepraszam, że wykorzystuje tu HAL, lecz odkryłem ten kurs na nowszych bibliotekach i stwierdziłem, że lepiej będzie się uczyć na tych nowszych. int licznik=0; while (1) { if (__HAL_UART_GET_FLAG(&uart, UART_FLAG_RXNE) == SET) { char value[3]; // powinno być [4] zarówno w buforze jak i warunku, ponieważ dochodzi jeszcze znak końca tekstu '/0' char warunek[3]="on1"; HAL_UART_Receive(&uart, &value[licznik], 1, 100); licznik++; if(licznik==3) { licznik=0; int a=strcmp(value,warunek); if(a==0) send_string("on1\r\n"); else if(strcmp(value,"of2")==0) send_string("of2\r\n"); } } } Edytowano Styczeń 15, 2019 przez wierczewski tablica char za krótka - brakuje miejsca dla znaku końca tekstu 1 Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
Elvis Styczeń 15, 2019 Udostępnij Styczeń 15, 2019 Znowu podstawy C się kłaniają. Poczytaj jak reprezentowane są napisy, podpowiem że trzy znaki to za mało na przechowywanie napisu o długości 3. 1 1 Cytuj Link do komentarza Share on other sites More sharing options...
Gumek Lipiec 14, 2019 Udostępnij Lipiec 14, 2019 Witam, Mam problem z którym ciężko poradzić mi sobie samemu otóż w terminalu pojawia się wiadomość która nie odpowiada temu co powinno być napisane, podanemu w kursie "Hello world!" odpowiada (Ascii): Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř® Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř® Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř®Ľř® Ľř®Ľ Real Term pozwala mi odtworzyć to w innych formatach oto kilka z nich: -Hex + Ascii BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D BC AD F8 AE 1D -unit8 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 1 88 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 1 73 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 248 174 29 188 173 Dla testu skróciłem wiadomość do samego "a" oto wyniki: Asci: ţ Hex+Ascii: FE unit8: 254 Samemu trudno zauważyć mi tu jakąś zależność, pytam więc czy ktoś może wie na czym może polegać błąd? (dodam że problem występuje również w Teraterm) Cytuj Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Lipiec 16, 2019 Udostępnij Lipiec 16, 2019 @Gumek witam na forum 🙂 Czy na pewno wybrałeś w terminalu odpowiednią prędkość komunikacji (musi być taka sama jak w programie)? Jej błędne ustawienie jest częstym powodem takich błędów. Cytuj Link do komentarza Share on other sites More sharing options...
aldenham Lipiec 29, 2019 Udostępnij Lipiec 29, 2019 Witam Niestety również mam problem z zadaniem #5.2. Na pewno mam zbyt małą wiedze nt. programowania w C, a szczególnie nt. STM32, ale dotychczas wszystkie zadania wykonywałem bez problemu. 1) Po pierwsze nurtuje mnie jedna rzecz - w instrukcji HAL w opisie funkcji HAL_UART_Receive podane są takie instrukcje. (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout) Wychodzi na to, że w przykładzie zmienna value musi być typu uint8_t i tak rzeczywiście jest. Zastanawia mnie, jak to jest, że w instrukcji switch oczekiwany jest znak (char), a w funkcji deklarowany jest int (uint8_t). Czy jest to rzutowanie? To w takim razie dlaczego jeśli próbuję odczytać z value łańcuch znaków, kompilator pokazuje type mismatch jeszcze przed próbą kompilacji? Zastosowanie strcmp(value, moja_zmienna_tablicowa_typu_char) również jest dla kompilatora błędna, bo traktuje value jako uint8_t. Kod napisany przez kolegę Wierczewskiego nie powinien się skompilować (nie sprawdzałem), bo zadeklarował value jako char, podczas gdy HAL_UART_Receive oczekiwało w tym miejscu zmiennej typu uint8_t. 2) To jak w końcu napisać tę funkcję tak, żeby zadziałała? Czy ilość danych do odbioru (uint16_t Size w dokumentacji HAL) powinna być ustawiona na 3 (lub 4) zamiast 1, jeśli chcę odebrać łańcuch o długości 4 znaków? Nie oczekuję gotowego rozwiązania, ale liczę na "ciekawą" podpowiedź 😉 Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Sierpień 1, 2019 Udostępnij Sierpień 1, 2019 uint8_t to najzwyklejszy, w dodatku 8-bitowy bajt. W języku C odpowiada dokładnie unsigned char. Zarówno signed char i unsigned char zajmują 8-bitów, różnica polega na interpretacji najwyższego bitu, czyli liczby ze znakiem lub bez. Sam typ char niestety nie wiadomo czy jest signed, czy unsigned - ale ew. pomyłka nie jest krytyczna. Kompilator ostrzega że typ jest inny, ale nic złego się nie dzieje. Biblioteka HAL jest delikatnie mówiąc przeciętna, używanie uint8_t jako typu bufora jest marnym pomysłem, ale ST potrafi produkować dobre mikorokontrolery, z programowaniem u nich gorzej. Nie pozostaje więc nic innego jak rzutować typ wskaźnika (rzutowany jest typ wskaźnika, nie same dane). Odbieranie po jednym bajcie jest oczywiście mało wydajne, ale nie jest błędem. Tym co było najgorsze w programie to brak miejsca na znak końca napisu, czyli '\0' - trzeba o tym pamiętać, że w języku C napisy są przechowywane z zerem na końcu. Czyli żeby zapisać łańcuch o długości 4 znaków potrzebna jest tablica o długości 5. 1 Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Sierpień 1, 2019 Udostępnij Sierpień 1, 2019 22 minuty temu, Elvis napisał: Sam typ char niestety nie wiadomo czy jest signed, czy unsigned - ale ew. pomyłka nie jest krytyczna. Kompilator ostrzega że typ jest inny, ale nic złego się nie dzieje. Powiedz to komuś, kto trzy dni szukał błędu w programie, który osiem lat działał na pececie a na raspberrym się wykładał 😉 Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Sierpień 1, 2019 Udostępnij Sierpień 1, 2019 Trzy dni to krótko, wręcz standardowy czas na znalezienie błędu 🙂 Oczywiście nie zawsze można pomijać czy zmienna jest ze znakiem, czy bez - chodziło mi o ten konkretny przypadek i napisy w 7-bitowym ASCII. A wyjaśniając - właśnie dlatego wprowadzono typy w rodzaju int8_t, uint8_t i podobne, żeby uniknąć różnic wynikających z wersji, czy parametrów kompilatora. Stare typy w C mają niestety taką cechę, że mogą mieć różną reprezentację w zależności od środowiska - przykładowo int może mieć 16, albo 32 bity, char może być ze znakiem lub bez itd. 1 Cytuj Link do komentarza Share on other sites More sharing options...
Zealota Sierpień 1, 2019 Udostępnij Sierpień 1, 2019 1 godzinę temu, Elvis napisał: używanie uint8_t jako typu bufora jest marnym pomysłem, ale ST potrafi produkować dobre mikorokontrolery, z programowaniem u nich gorzej. Nie pozostaje więc nic innego jak rzutować typ wskaźnika (rzutowany jest typ wskaźnika, nie same dane). W takim razie jaki to ma być typ zmiennej? char odpada, tak wnioskuję, po innych wpisach w wątku, bo jest typem archaicznym. Osobiście nie korzystam z char, właśnie z tego powodu. Trochę szukałem informacji na ten temat, ale zdania są zwykle podzielone. Natomiast wniosek wyciągnąłem taki, że należy wybierać typy zmiennych zgodnie z ich przeznaczenie, zatem znak ascii nie ma "znaku" to trzeba zapomnieć o char. Z chęcią dowiem się coś więcej na ten temat, choć czuję podskórnie, że po to wymyślono inne języki, żeby nie doktoryzować się przy tych już wiekowych 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Sierpień 1, 2019 Udostępnij Sierpień 1, 2019 Największym problemem HAL nie jest uint8_t jako taki, ale brak const przy wysyłaniu. Natomiast w C lepszym rozwiązaniem byłoby użycie void* nawet jeśli to nieco archaiczne - ale oszczędziłoby używania konwersji tam gdzie nie jest to konieczne. Tym bardziej że wysyłane dane nie zawsze są w 8-bitowych bajtach. Natomiast czy trzeba zmieniać język programowania to bym polemizował. Wystarczy nauczyć się używać tego co się ma. 1 Cytuj Link do komentarza Share on other sites More sharing options...
aldenham Sierpień 13, 2019 Udostępnij Sierpień 13, 2019 @Elvis Dzięki za porady. Z tym \0 oczywiście byłem świadomy, tylko niezbyt wyraźnie napisałem, o co mi chodzi. Stwierdziłem, że trochę szkoda zajmować się rozwiązaniem, z którego w przyszłości i tak nie będę korzystał, bo przeniosę pewnie kod na DMA 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
dzozda Wrzesień 28, 2019 Udostępnij Wrzesień 28, 2019 Witam, Dlaczego nie trzeba dołączyć biblioteki stdio.h skoro korzystamy z funkcji printf? Pozdrawiam Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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!