Przeszukaj forum
Pokazywanie wyników dla tagów 'Nucleo'.
Znaleziono 12 wyników
-
Cześć, od dłuższego czasu pracuję nad projektem o poniższych założeniach: - odczyt z 4 czujników IMU (24 osie) - szybkość akwizycji - 400-500 pomiarów na sekundę - mikrokontroler z serii F7 (wymogi późniejszej rozbudowy) - zapis na kartę SD lub bezprzewodowe przesłanie danych. Wpis ten jest tak naprawdę kontynuacją wątku STM32 UART wysyłanie danych typu uint16_t. Okazało się, że pomysł z bezprzewodowym przesyłaniem danych po UART jest trudny/nierealny do zrealizowania, więc postanowiłem wykorzystać zapis na kartę pamięci. Było z tym mnóstwo problemów (z zainteresowanymi chętnie się podzielę), ale koniec końców udało mi się zrealizować zapis w 4-bitowym trybie SDMMC. Obecnie zmagam się z problemem odpowiedniej szybkości pobierania danych z czterech MPU9250 podłączonych do dwóch linii I2C i ich zapisem na SD. Realizuję to w przerwaniu timera, które odpowiada za stałą szybkość akwizycji. Ustawiając zegary na maksymalne wartości pozwalające na skuteczny zapis na SD, podczas 1-minutowych testów z fs=400 Hz całkowity czas operacji wynosi ok. 65 sekund. Np. dla 100 Hz jest to dokładnie 60 sekund. Zatem program "nie wyrabia" owych 400 Hz. Wpadłem na pomysł, żeby czujniki podłączyć do 4 osobnych magistrali I2C i używać trybu IT, ale mój procesor ma tylko 1 pin (PC9) odpowiedzialny zarówno za I2C3_SDA, jak i MMC1_D1, czyli w moim przypadku nie da rady go użyć. Musiałbym wykorzystać wersję przynajmniej 176-pinową, a tych nie znalazłem dostępnych w Polsce. Póki co, aby nieco przyśpieszyć akwizycję, zastosowałem pewien (dziwny) trick i z każdej I2C jeden czujnik obsługuję trybem blokującym, a drugi z użyciem przerwania. Poniżej fragment kodu: uint8_t my_string[4*24+1]; //bez spacji void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM10) //przerwanie pochodzi od timera 10 { HAL_I2C_Mem_Read(&hi2c1, MPU9250_ACC_ADDRESS_A, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_A, 14, 50); //14 pomiarów od razu HAL_I2C_Mem_Read_IT(&hi2c1, MPU9250_ACC_ADDRESS_B, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_B, 14); //14 pomiarów od razu HAL_I2C_Mem_Read(&hi2c2, MPU9250_ACC_ADDRESS_C, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_C, 14, 50); //14 pomiarów od razu HAL_I2C_Mem_Read_IT(&hi2c2, MPU9250_ACC_ADDRESS_D, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_D, 14); //14 pomiarów od razu timer_tim10++; if (timer_tim10 <= 6*4000) { sprintf(my_string, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", MPU9250_Data_A[0],MPU9250_Data_A[1],MPU9250_Data_A[2],MPU9250_Data_A[3],MPU9250_Data_A[4],MPU9250_Data_A[5],MPU9250_Data_A[8],MPU9250_Data_A[9],MPU9250_Data_A[10],MPU9250_Data_A[11],MPU9250_Data_A[12],MPU9250_Data_A[13], MPU9250_Data_B[0],MPU9250_Data_B[1],MPU9250_Data_B[2],MPU9250_Data_B[3],MPU9250_Data_B[4],MPU9250_Data_B[5],MPU9250_Data_B[8],MPU9250_Data_B[9],MPU9250_Data_B[10],MPU9250_Data_B[11],MPU9250_Data_B[12],MPU9250_Data_B[13], MPU9250_Data_C[0],MPU9250_Data_C[1],MPU9250_Data_C[2],MPU9250_Data_C[3],MPU9250_Data_C[4],MPU9250_Data_C[5],MPU9250_Data_C[8],MPU9250_Data_C[9],MPU9250_Data_C[10],MPU9250_Data_C[11],MPU9250_Data_C[12],MPU9250_Data_C[13], MPU9250_Data_D[0],MPU9250_Data_D[1],MPU9250_Data_D[2],MPU9250_Data_D[3],MPU9250_Data_D[4],MPU9250_Data_D[5],MPU9250_Data_D[8],MPU9250_Data_D[9],MPU9250_Data_D[10],MPU9250_Data_D[11],MPU9250_Data_D[12],MPU9250_Data_D[13]); if(f_lseek(&fil, f_size(&fil)) != HAL_OK) printf("f_lseek ERROR\n"); if(f_write(&fil, my_string, sizeof(my_string), &numread) != HAL_OK) printf("f_write ERROR\n"); }else if (timer_tim10 == 6*4000+1) { close_file(); unmount_sd(); printf("done\n"); } } } Jak widać (mam nadzieję), czujnik A i B znajdują się na I2C1, C i D na I2C2. B i D odczytuję z użyciem przerwania (IT) po zakończeniu odczytu odpowiednio A i C. Jak mogę to zrobić szybciej? Domyślam się, że DMA mogłoby pomóc, ale kompletnie nie umiem tego zrobić. Zwykła zamiana _IT na _DMA nie działa. W sieci znalazłem mnóstwo wątków z problemami użycia DMA na F7, ale bez skutecznych (w moim przypadku) rozwiązań. Proszę tu o Waszą pomoc. A może mogę jakoś przyśpieszyć zapis na kartę pamięci? Czy tutaj można jakoś zaprząc do pacy DMA lub inny szybki mechanizm? Wydaje mi się też, że funkcja sprintf zajmuje sporo czasu. Usunąłem z niej wszystkie zbędne znaki i przesyłam jedynie po 2 na każdy rejestr oraz znak nowej linii po zapisaniu wszystkich potrzebnych rejestrów (w liczbie 48), czyli w sumie 97 znaków w każdej iteracji. Czy są jakieś szybsze alternatywy? Trochę się rozpisałem. Temat jest wielowątkowy, generuje różne problemy i zaskakujące niespodzianki. Starałem się zawrzeć tylko najważniejsze informacje. Testy przeprowadzam na Nucleo F746. Docelowo chciałem użyć 100-pinowego F756VGT6, ale może być inny (dostępny od ręki) z serii F7. STM32CubeIDE 1.10.1 MCU Package 1.17.0
-
Cześć, niedawno zakupiłem Nucleo-H743ZI2 (MB1364) głównie w celu uzyskania dostępu jednocześnie do 4 linii I2C oraz interfejsu SDMMC. No i spotkała mnie pewna niespodzianka, ponieważ wyprowadzenia SDMMC_D0 oraz SDMMC_D1 są rozłączone od złącza morpho. Można je podłączyć poprzez 2 zworki (SB14 i SB15). Niby oczywiste, ale zastanawia mnie, dlaczego producent nie podłączył ich fabrycznie. W dokumencie UM2407 znajduje się informacja "These pins are disconnected from ST morpho connector CN12 to avoid stub of SDMMC data signals on PCB". Co to dokładnie oznacza. Czym "grozi" dodanie tych zworek i jak się uchronić przed ewentualnymi problemami. I drugie pytanie - rozumiem, że dotyczy to jedynie interfejsu SDMMC2, czyli pinów PB14 i PB15? Niestety nie znalazłem schematu do MB1364, a na schematach MB1137 zworki te odpowiadają za zupełnie inne piny. Czy możliwe jest w ogóle używanie obu interfejsów SDMMC jednocześnie? Jawnie nigdzie nie definiuję pinów, do których jest podłączony moduł SD, ani nie wskazuję, czy używam interfejsu nr 1 czy 2.
-
Cześć, Mam płytkę Nucleo-L476RG. Podczas próby kompilacji programu pojawia się seria błędów kompilacji związanych z sterownikami, głównie pojawia się: arm-none-eabi-gcc: fatal error: cannot execute 'cc1': CreateProcess: No such file or directory compilation terminated. Z góry dziękuję za pomoc. Problem się także pojawia przy zupełnie pustym programie(jedynie automatycznie wygenerowany kod)
-
Problem z odczytaniem biblioteki HAGL na płytce NUCLEO L476RG
trol opublikował temat w Mikrokontrolery
Chyba próbowałam już wszystkiego. Program ma problem z odczytaniem plików typu: #include "hagl/bitmap.h". -
Cześć, próbuje uruchomić układ z akcelerometrem LSM303D (kurs) na płytce nucleo-f7, niestety w tej generacji nie ma już dostępnej biblioteki "STM32F10x Standard Peripherals Library". Aktualnie korzystam z biblioteki HAL. Czy jest jakiś dobry sposób aby przerobić ten kod pod generacje F7? Czy jest może już napisana jakaś biblioteka tego akcelerometru? Czy jest może jakiś odpowiednik "Standard Peripherals Library" dla stm32f7?
-
Witam, chciałbym zrobić układ sterowania silnikiem DC na Nucleo F302R8. Posiadam sterownik DC BTS7960. Do tej pory takie rzeczy robiłem na arduino i nie mam pomysłu jak zabrać się za to na nucleo.
-
Witam, Jak zrobić system komunikacji płytki nucleo przez wifi z komputerem. Stm 32 kontroluje silniki i czujniki i przesyła dane do komputera. Program w komputerze podejmuje decyzje i przesyła je do Stm który podejmuje działania. Czy nie lepiej w roli nucleo sprawdził by się komputer jednopłytkowy?
-
Jestem na lekcji 3 z kursu STM32 F1 HAL i próbując pobrać sterowniki z linku podanego w kursie na stronie producenta po kliknięciu w link z maila wyskakuje mi error 403. Miał może ktoś podobny problem? Z Góry dzięki za odpowiedź.
-
Czy integrowanie SBC np. Raspberry z płytką typu nucleo ma sens? Chodzi mi o to czy używanie nucleo itp. jako pośrednika między czujnikami, sterownikami silników a raspberry lub innym SBC na którym znajduje się główny program odpowiadający za pracę robota jest wydajne i czy ma sens ?
-
Witajcie Realizuję komunikację pomiędzy mikroprocesorem STM32F411RE (NUCLEO) a modułem SIM800L. Wykorzystuję do tego interfejs UART. Inicjalizuję go poprzez bibliotekę HAL'a. Samą wymianę danych postanowiłem zrobić ręcznie, odwołując się bezpośrednio do rejestrów UART. Poniżej funkcja inicjalizacyjna: void uart_init(uint32_t baud) { uart_gpio.Pin = GPIO_PIN_9 | GPIO_PIN_10; //TX RX uart_gpio.Mode = GPIO_MODE_AF_PP; uart_gpio.Alternate = GPIO_AF7_USART1; uart_gpio.Speed = GPIO_SPEED_HIGH; uart_gpio.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA,&uart_gpio); usart.Instance = USART1; usart.Init.BaudRate = baud; usart.Init.Parity = USART_PARITY_NONE; usart.Init.StopBits = USART_STOPBITS_1; usart.Init.WordLength = USART_WORDLENGTH_8B; usart.Init.Mode = USART_MODE_TX_RX; HAL_USART_Init(&usart); } Sama komunikacja odbywa się w funkcji "sim_reception", w przerwaniu od timera mikroprocesora. #define SIM_TX_BUF_SIZE 32 #define SIM_RX_BUF_SIZE 32 volatile unsigned char sim_tx_buf[SIM_TX_BUF_SIZE]; volatile unsigned char sim_rx_buf[SIM_RX_BUF_SIZE]; volatile unsigned char sim_tx_len = 0; volatile unsigned char sim_rx_len = 0; enum { handshake, hdsh_resp }; volatile uint8_t sim_states = handshake; #define SIM_HNDSHK "AT\r\n" void sim_reception(void) { //RX //if Receiver not empty flag is set and we have space in rx buffer, we read byte while(USART1 -> SR & USART_SR_RXNE) { if(sim_rx_len < SIM_RX_BUF_SIZE) sim_rx_buf[sim_rx_len++] = USART1 -> DR; //after reading byte we increment buffer length else break; } //TX //if Transmitter empty flag is set and we have data in tx buffer, we send byte while(USART1 -> SR & USART_SR_TXE) { if(sim_tx_len != 0) { USART1 -> DR = sim_tx_buf[0];//send one byte sim_byte_up(sim_tx_buf); //shift one byte up } else break; } switch(sim_states) { case handshake: sim_tx_buf_put(SIM_HNDSHK); sim_states = hdsh_resp; break; case hdsh_resp: break; default: sim_states = handshake; break; } } Na razie chcę wysłać tylko jedno polecenie i odczytać odpowiedź modułu SIM800L. Krótko opiszę nadawanie, które działa bez zarzutu. Wywołuję funkcję "sim_tx_buf_put", która napełnia bufor komendą "SIM_HNDSHK", zdefiniowaną wyżej za pomocą #define. Funkcja bada ile miejsca mamy w buforze i czy wystarczy go jeszcze dla nowego polecenia. Jeśli tak to wstawia je bajt po bajcie i zwiększa odpowiednio zmnienną "sim_tx_len". Nie będe wstawiał kodu tej funkcji, ponieważ działa ona bardzo dobrze, nie mam z nią problemu. Wyżej w kodzie widać, że jest badany stan flagi "Transmitter Empty", gdy się ona pojawi i w buforze Tx są dane przystępuje się do wysyłania danych bajt po bajcie. Po każdym wysłanym bajcie wywoływana jest funkcja "sim_byte_up", która przesuwa bajty bufora "o jeden w górę", czyli sim_tx_buf[0] = sim_tx_buf[1], sim_tx_buf[1] = sim_tx_buf[2] itd. oraz zmniejsza wartość "sim_tx_len" o jeden, następnie wysyłany jest kolejny bajt i tak do opróżnienia bufora. Nadajnik działa jak należy, co pokazuje screenshot z analizatora stanów logicznych. Po wysłaniu wiadomości "AT\r\n" moduł SIM800L odsyła odpowiedź. Zatem flaga "Receiver Not Empty" powinna zostać aktywowana, bufor Rx jest pusty, tak więc coś powinno zostać zapisane w buforze. Jednak nic takiego się nie dzieje. Screenshoty z debugowania. W buforze Rx pojawia się tylko jeden bajt o wartości 127. Dalszych procedur odbioru nawet nie opracowałem, bo skoro w buforze odbiorczym nic nie ma... Nie bardzo wiem z czym jest związany ten problem, próbowałem wyprowadzić Tx i Rx we wszystkich możliwych konfiguracjach, jednak zawsze jest tak samo, nadajnik wysyła bez żadnego problemu a odbiornik nie może nic odczytać. Jeśli ktoś ma jakiś pomysł co może być przyczyną problemu i jak to rozwiązać to byłbym bardzo wdzięczny za pomoc 😉 Pozdrawiam mw
-
Podłączyłem sobie dzisiaj dwa silniki. Wszystko dzialalo dobrze az do pewnego czasu gdy przez przypadek rozlaczyl mi sie kabel doprowadzajacy zasilanie do sterownika silnika z akumulatora. Uslyszalem lekkie pykniecie i natychmiast wylaczylem obwod z akumulatora. Teraz nawet gdy podlaczam sam mikrokontroler to mimo ze diody sie swiecą to st-link nie wykrywa plytki. Dodatkowo zauwazylem ze plytka sie mocno nagrzewa. Czy to jest objaw spalenia mikrokontrolera? Prawdopodobnie tak, ale co konkretnie moglo byc przyczyna?
-
Witajcie! Pracuje obecnie na Nucleo-F746ZG. Chce nawiązać komunikacje przez SPI z FPGA. Moje urządzenie działa jako slave. Obecnie nie jest źle, komunikacja działa poprawnie w obydwie strony. Problem jest w zasadzie prosty, FPGA wysyła mi 32 liczby 16bitowe, a ja mam je odebrać w odpowiedniej kolejności. Co wiec robie? Ustalam, że ciąg liczb powinien się zaczynać od wartości 0x01. Niestety moje próby zakończyły się niepowodzeniem. Mikrokontroler "łapie" dane w losowym momencie, stąd w moim buforze dane zaczynać się mogą od dowolnej liczby ze zbioru wszystkich 32 liczb. Można to potraktować jako przesuniecie w fazie, lecz najgorsze jest to że po "złapaniu" jest ono stale. Wiec moje ify na niewiele się zdadzą, bo jak 0x01 jest na 7 miejscu w buforze to tak już pozostanie. Mam nadzieje, że wyraziłem się względnie jasno. Zamieszczam część kodu obsługująca SPI. Używam HAL i w projekcie pomaga mi CubeMX. Będę wdzięczny za sugestie! #define WORD_LENGTH 32 /* word length */ uint16_t rx_spi5[WORD_LENGTH]; /* Buffer for received data from SPI5 */ uint16_t tx_spi5[WORD_LENGTH]; /* Buffer for sending data from SPI5 */ uint16_t trig = 0x0001; /* Trigger value */ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { if(hspi->Instance == hspi5.Instance) { //HAL_SPI_Receive_IT(&hspi5, &rx_spi5, 1); HAL_SPI_TransmitReceive_IT(&hspi5, tx_spi5, rx_spi5, WORD_LENGTH); } } while(1) { if (rx_spi5[0] == trig) { for (int i = 0; i <WORD_LENGTH; ++i) { size = sprintf(data, " %x ; ", rx_spi5[i]); HAL_UART_Transmit(&huart3, data, size, HAL_MAX_DELAY); memset(data, 0, 75); } size = sprintf(data, "\r\n"); HAL_UART_Transmit(&huart3, data, size, HAL_MAX_DELAY); memset(data, 0, 75); } }