Skocz do zawartości

radek04

Użytkownicy
  • Zawartość

    192
  • Rejestracja

  • Ostatnio

Informacje

  • Płeć
    Mężczyzna

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

Osiągnięcia użytkownika radek04

Eksplorator

Eksplorator (8/19)

  • Juror
  • Stały wizytator
  • Wschodząca gwiazda
  • To już 5 lat!
  • Za 100 postów

Odznaki

29

Reputacja

  1. Zasadniczo jest lepiej, bo zapisuje mniej danych, ale i tak występują opóźnienia. W zasadzie jeśli i tak mam przerwy w odczytach, to większej różnicy nie robi mi wielkość tej przerwy, a postać po konwersji funkcją sprintf() jest dla mnie wygodniejsza. Wciąż zależy mi na zapisie ciągłym, to niestety nie jest rozwiązanie. Ale oczywiście dziękuję za propozycję, bo jest bardzo sensowna.
  2. OK, fajny pomysł. W jakiej formie to jest wtedy faktycznie zapisywane? Zera i jedynki? Najłatwiej by mi było to obrabiać w MATLAB-ie, bo i tak tam będę później przetwarzał te dane.
  3. Pomysł jest niezły, aje jak wykorzystać takie dane?
  4. Na mojej najszybszej karcie tracę ok. 1 pomiar na 50 poprawnie wykonanych i to niezależnie od wielkości bufora jednorazowo zapisywanego na kartę.
  5. No i chyba właśnie tak dziwnie się zachowuje. Mimo użycia zapisu na kartę w trybie DMA (pewności nie mam, że tak to się odbywa, ale wszystkie ustawienia i pliki mam zmienione na DMA), operacja ta jakby blokowała inne instrukcje... W wątku STM32H7 Zapis na kartę SD z użyciem FatFs - wykorzystanie DMA kontynuuję walkę na H7 i proponuję tam też kontynuować dyskusję.
  6. No właśnie przy FatFs nie ma w Cube takich ustawień DMA, jak np. przy interfejsach I2C, gdzie w łatwy sposób mogę zrobić bufor okrężny. Natomiast przy samodzielnym podziale na 2 bufory wciąż występuje ten sam problem. Zawsze gubię po 6 odczytów. Tak, jakby DMA nie działało... Wrzucę fragment kodu, może zauważycie jakiś błąd. while (1) { while (previous_timer_tick == current_timer_tick) //jeśli timer nie zmienił jeszcze wartości current_timer_tick { HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RESET); // 0 HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RESET); // 0 HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RESET); // 0 HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RESET); // 0 } if (previous_timer_tick < current_timer_tick - 1) //jeśli timer zmienił wartość current_timer_tick więcej niż 1 raz (program nie wyrabia czasowo) program się nie zatrzymuje { //printf("Uklad nie wyrabia czasowo (karta)\n"); HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RESET); // 0 HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, SET); // 1 HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RESET); // 0 HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RESET); // 0 current_timer_tick = previous_timer_tick; //naprawa sytuacji, by dalej działało } if (current_timer_tick == previous_timer_tick + 1) { while //dopóki którykolwiek I2C nie jest gotowy ( HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY || HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY || HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY || HAL_I2C_GetState(&hi2c4) != HAL_I2C_STATE_READY ) { //printf("I2C nie jest gotowe\n"); HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RESET); // 0 HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RESET); // 0 HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, SET); // 1 HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RESET); // 0 } //printf("Wszystkie I2C sa gotowe, normalna praca\n"); previous_timer_tick = current_timer_tick; HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RESET); // 0 HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RESET); // 0 HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RESET); // 0 HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, SET); // 1 HAL_I2C_Mem_Read_DMA(&hi2c1, MPU9250_ACC_ADDRESS_A, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_A, 14); //14 pomiarów od razu HAL_I2C_Mem_Read_DMA(&hi2c2, MPU9250_ACC_ADDRESS_B, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_B, 14); //14 pomiarów od razu HAL_I2C_Mem_Read_DMA(&hi2c3, MPU9250_ACC_ADDRESS_C, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_C, 14); //14 pomiarów od razu HAL_I2C_Mem_Read_IT(&hi2c4, MPU9250_ACC_ADDRESS_D, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_D, 14); //14 pomiarów od razu if (ktory_bufor == 0) /* wybór buforów */ { sprintf(&my_string_0[(ASCII_char_No + 7)*(round_No-1)], /* zapis z czujników do bufora nr 0 */ "%6d " "%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", real_timer_tick, 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 (round_No == rounds)//jeśli skończą się pomiary w danym etapie (np. przez 5 sekund 500*5) { ktory_bufor = 1; //zmiana bufora round_No = 0; lap++; //kolejne okrążenie HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, SET); //włączenie diody if(f_write(&fil, my_string_0, sizeof(my_string_0), &numread) != HAL_OK) printf("f_write ERROR\n"); /* zapis na kartę z bufora nr 0 */ HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RESET); //wyłączenie diody - koniec zapisu na kartę }else if (ktory_bufor == 1) /* wybór buforów */ { sprintf(&my_string_1[(ASCII_char_No + 7)*(round_No-1)], /* zapis z czujników do bufora nr 1 */ "%6d " "%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", real_timer_tick, 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 (round_No == rounds)//jeśli skończą się pomiary w danym etapie (np. przez minutę 500*60) { ktory_bufor = 0; //zmiana bufora round_No = 0; lap++; //kolejne okrążenie HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, SET); //włączenie diody if(f_write(&fil, my_string_1, sizeof(my_string_1), &numread) != HAL_OK) printf("f_write ERROR\n"); /*zapis na kartę z bufora nr 1 */ HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RESET); //wyłączenie diody - koniec zapisu na kartę } if (lap == laps) //koniec wszystkich operacji { HAL_TIM_Base_Stop_IT(&htim7); //uruchomienie timera generującego przerwanie HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RESET); //wyłączenie diody printf("Zatrzymuje przerwania TIM7\n"); if (f_close(&fil) == HAL_OK) printf("f_close OK\n"); else printf("f_close ERROR\n"); unmount_sd(); printf("previous = %d, current = %d, real = %d, round_No = %d, lap = %d\n", previous_timer_tick, current_timer_tick, real_timer_tick, round_No, lap); printf("done\n"); return 0; } } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) /* przerwanie timera */ { if (htim->Instance == TIM7) // przerwanie pochodzi od timera 7 { current_timer_tick++; round_No++; real_timer_tick++; //wartość ta nigdy nie jest zerowana } } Edit: Zrobiłem też 2 komplety tablic do zapisu z czujników. Zamiast MPU9250_Data_A[] mam MPU9250_Data_A_0[] oraz MPU9250_Data_A_1[] (i tak dla każdego czujnika), ale efekt bez zmian.
  7. Rozumiem, że nawet jeżeli zapis na kartę z bufora dokonuje się z wykorzystaniem DMA, to w tym samym czasie nie mogę odczytywać tego bufora i do niego zapisywać? Potrzebuję tutaj 2 buforów pracujących naprzemiennie, tak? Na razie testuję 1 bufor i w czasie zapisu na kartę tracę zawsze 6 odczytów pomiędzy kolejnymi "okrążeniami". Czyli zapisuje mi pierwsze 200 odczytów (rozmiar bufora), następnie jest 6 przerwań timera (12 ms, f=500 Hz), w czasie których zapis do bufora się nie realizuje, kolejna zapisana próbka ma numer 207 i tak w kółko.
  8. Tak, widziałem to. Ale właśnie nie mogłem się doszukać, czym te wersje się różnią. No i na razie nie udało mi się żadnej uruchomić. Mam dziesiątki błędów przy kompilacji, więc to nie jest trywialna zamiana plików... Edit: Pozbyłem się błędów. Testuję.
  9. Chyba tak. Zachowywały się jak antena zbierająca zakłócenia. Dlatego czasem dotyk palcem zmieniał zachowanie. Ale to tylko moje podejrzenia.
  10. Na PCB tryb 4-bit dla SDMMC1 działa bez żadnych problemów. Okazuje się, że wyprowadzenia w Nucleo są przyczyną niektórych kłopotów.
  11. Czy dobrze rozumiem, że operacja, która została - nomen omen - przerwana przez przerwanie wykonujące coś innego, po zakończeniu instrukcji w przerwniu wróci w odpowiednim momencie do realizacji swojego kodu? Czy to raczej ryzykowne i nieprzewidywalne? Chodzi mi o zapis na kartę - powiedzmy, że 60% danych się zapisało, zapis został przerwany przez odczyt z czujników (wywoływany w przerwaniu timera). Czy po zakończeniu odczytu na kartę zostanie zapisane pozostałe 40% danych, czy to tak nie zadziała?
  12. radek04

    Oscyloskop - pomoc w wyborze

    Zakupiłem SDS1104X-E. Był dużo tańszy od SDS1204X-E, a przede wszystkim dostępny od ręki. 150 MHz mierzy dobrze (oczywiście tłumienie jest już większe). Co do wentylatora, to w moim przypadku nie ma mowy o pracy w nocy. Ale każdy ma inną żonę 😉
  13. Cześć, powoli muszę kończyć projekt, z którym walczę od kilku miesięcy. Dotyczy on akwizycji danych z czujników inercyjnych (i mikrofonów) oraz ich zapis na kartę SD. Dla zainteresowanych przedstawiam tematy bezpośrednio związane z projektem: STM32 UART wysyłanie danych typu uint16_t, STM32F7 Zbyt mała szybkość zapisu danych z czujników I2C na kartę SD, Nucleo-H7 - odłączone piny SDMMC i dwa związane pośrednio: Gdzie opłaca się zamawiać PCB?, Oscyloskop - pomoc w wyborze. Zmontowałem układ na PCB, co rozwiązało kilka problemów związanych z wyprowadzeniami pinów uC na płytce Nucleo. Zapis na kartę działa już sprawnie, ale wciąż w trybie blokującym. Przez to nawet z użyciem dwóch buforów i naprzemiennego odczytu/zapisu wciąż tracę niektóre pomiary, których nie mogę realizować podczas zapisywania danych na SD. Czy ktoś z Was robił coś podobnego? Szukam rozwiązań w sieci, ale nie mogę niczego konkretnego się doszukać. W CubeIDE jest informacja, by wygenerować kod bazujący na sd_diskio_dma_template.*files. Gdzie znajdę takie takowe szablony?
  14. radek04

    Oscyloskop - pomoc w wyborze

    A wentylator jest głośny? Da radę używać w nocy przy śpiącej żonie? 🙂
  15. radek04

    Oscyloskop - pomoc w wyborze

    A jaka jest prawdziwa różnica między modelami SDS1104X-E oraz SDS1204X-E, jeżeli mają identyczny przetwornik A/C 1 GSa/s? W niższym modelu nie wyświetli mi sinusoidy 200 MHz? Czy wyświetli zniekształconą? Bardziej zniekształconą niż w wyższym modelu z tym samym ADC? Czy to oby nie jest czysty chwyt marketingowy?
×
×
  • 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.