radek04 Napisano Sierpień 28, 2023 Udostępnij Napisano Sierpień 28, 2023 Cześć, używam w projekcie 4 modułów GY-91. Odczytuję z nich 500 razy na sekundę wartości z akcelerometru, żyroskopu i barometru. O ile osobno IMU i BAR działają dobrze, o tyle mam problem z "symultanicznym" odczytem wszystkich danych. Korzystam z 4 linii I2C (każdy moduł podłączony do innej) oraz odczytu w trybach DMA oraz IT. Problem w tym, że zarówno IMU (akcelerometr i żyroskop), jak i barometr korzystają ze wspólnego interfejsu I2C. Poprawnie mogę odczytać tylko te dane, które w programie są jako pierwsze (reszta zostaje zerami). Podejrzewam, że kolejny pomiar próbuję zrobić, zanim poprzedni się zakończył. Jak sprawdzić, czy operacja HAL_I2C_Mem_Read_DMA() została już zakończona i mogę wykonać kolejny pomiar po tej samej linii I2C? Jest jakaś flaga do tego? Na razie roboczo wstawiłem opóźnienie, ale to rozwiązanie nie do końca mnie zadowala, ponieważ ważna dla mnie jest każda mikrosekuda. Poza tym to niezbyt eleganckie rozwiązanie. Używam STM32H743ZII, STM32CubeIDE. HAL_I2C_Mem_Read_DMA(&hi2c1, BMP280_ADDRESS_A, BMP280_REG_BAR_MSB, 1, BMP280_Data_A, 3); // 3 registers (MSB, LSB, XLSB) HAL_I2C_Mem_Read_DMA(&hi2c2, BMP280_ADDRESS_B, BMP280_REG_BAR_MSB, 1, BMP280_Data_B, 3); // 3 registers (MSB, LSB, XLSB) HAL_I2C_Mem_Read_DMA(&hi2c3, BMP280_ADDRESS_C, BMP280_REG_BAR_MSB, 1, BMP280_Data_C, 3); // 3 registers (MSB, LSB, XLSB) HAL_I2C_Mem_Read_IT (&hi2c4, BMP280_ADDRESS_D, BMP280_REG_BAR_MSB, 1, BMP280_Data_D, 3); // 3 registers (MSB, LSB, XLSB) Hal_Delay(1); HAL_I2C_Mem_Read_DMA(&hi2c1, MPU9250_ACC_ADDRESS_A, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_A, 14); //14 registers measurement HAL_I2C_Mem_Read_DMA(&hi2c2, MPU9250_ACC_ADDRESS_B, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_B, 14); //14 registers measurement HAL_I2C_Mem_Read_DMA(&hi2c3, MPU9250_ACC_ADDRESS_C, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_C, 14); //14 registers measurement HAL_I2C_Mem_Read_IT (&hi2c4, MPU9250_ACC_ADDRESS_D, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_D, 14); //14 registers measurement Cytuj Link do komentarza Share on other sites More sharing options...
radek04 Sierpień 28, 2023 Autor tematu Udostępnij Sierpień 28, 2023 (edytowany) Wybaczcie moją niefrasobliwość. Okazało się,że już wcześniej to robiłem funkcją while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){} Tylko teraz nasuwa mi się pytanie, czy lepiej sprawdzać każdą linię I2C osobno while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_DMA(&hi2c1, BMP280_ADDRESS_A, BMP280_REG_BAR_MSB, 1, BMP280_Data_A, 3); while(HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_DMA(&hi2c2, BMP280_ADDRESS_B, BMP280_REG_BAR_MSB, 1, BMP280_Data_B, 3); while(HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_DMA(&hi2c3, BMP280_ADDRESS_C, BMP280_REG_BAR_MSB, 1, BMP280_Data_C, 3); while(HAL_I2C_GetState(&hi2c4) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_IT (&hi2c4, BMP280_ADDRESS_D, BMP280_REG_BAR_MSB, 1, BMP280_Data_D, 3); while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_DMA(&hi2c1, MPU9250_ACC_ADDRESS_A, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_A, 14); while(HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_DMA(&hi2c2, MPU9250_ACC_ADDRESS_B, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_B, 14); while(HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_DMA(&hi2c3, MPU9250_ACC_ADDRESS_C, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_C, 14); while(HAL_I2C_GetState(&hi2c4) != HAL_I2C_STATE_READY){} HAL_I2C_Mem_Read_IT (&hi2c4, MPU9250_ACC_ADDRESS_D, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_D, 14); czy wystarczy wszystkie jednocześnie? while( 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){} HAL_I2C_Mem_Read_DMA(&hi2c1, BMP280_ADDRESS_A, BMP280_REG_BAR_MSB, 1, BMP280_Data_A, 3); HAL_I2C_Mem_Read_DMA(&hi2c2, BMP280_ADDRESS_B, BMP280_REG_BAR_MSB, 1, BMP280_Data_B, 3); HAL_I2C_Mem_Read_DMA(&hi2c3, BMP280_ADDRESS_C, BMP280_REG_BAR_MSB, 1, BMP280_Data_C, 3); HAL_I2C_Mem_Read_IT (&hi2c4, BMP280_ADDRESS_D, BMP280_REG_BAR_MSB, 1, BMP280_Data_D, 3); while( 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){} HAL_I2C_Mem_Read_DMA(&hi2c1, MPU9250_ACC_ADDRESS_A, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_A, 14); HAL_I2C_Mem_Read_DMA(&hi2c2, MPU9250_ACC_ADDRESS_B, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_B, 14); HAL_I2C_Mem_Read_DMA(&hi2c3, MPU9250_ACC_ADDRESS_C, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_C, 14); HAL_I2C_Mem_Read_IT (&hi2c4, MPU9250_ACC_ADDRESS_D, MPU9250_ACCEL_XOUT_H, 1, MPU9250_Data_D, 14); Chodzi mi o to, który sposób będzie szybszy, jeśli przy trybach DMA i IT to w ogóle ma jakieś znaczenie. Edytowano Sierpień 28, 2023 przez radek04 1 Cytuj Link do komentarza Share on other sites More sharing options...
ReniferRudolf Sierpień 29, 2023 Udostępnij Sierpień 29, 2023 (edytowany) Dnia 28.08.2023 o 05:07, radek04 napisał: Jak sprawdzić, czy operacja HAL_I2C_Mem_Read_DMA() została już zakończona i mogę wykonać kolejny pomiar po tej samej linii I2C? Jest jakaś flaga do tego? A czy nie trzeba by do tego celu zaużyć przerwania? Warto zapoznać się z sekwencją programowania w HAL protokołu I2C w trybie DMA i przerwaniowym, przy czym nie mogę namierzyć odpowiednika poniższego dokumentu dla innych wersji boardów STM32 (tu jest link do dokumentacji HALa dla STM32F4 - może być co najmniej dobrą inspiracją)... https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf Edytowano Sierpień 29, 2023 przez ReniferRudolf Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Sierpień 29, 2023 Udostępnij Sierpień 29, 2023 Nie znam się na STM-ach, ale różnica między "mam następne dane" i "już odczytałem wartości" może być w tym przypadku kluczowa... 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
radek04 Sierpień 30, 2023 Autor tematu Udostępnij Sierpień 30, 2023 Dane pobieram 500 razy na sekundę i tak szybko też (w przerwaniu timera) odczytuję je. Dane wyglądają dobrze i za każdym razem delikatnie inne, więc zdaje się, że działa to dobrze. Roboczo przyjmuję, że odczytuję nowe dane po tym, jak się zmieniły i zanim nastąpi kolejna zmiana. W instrukcji BMP280 jest informacja, że jeśli odczyt wykonywany jest seryjnie po kolejnych rejestrach, to dane są zawsze spójne. W MPU9250 podobnej informacji nie znalazłem i przyznaję, że nie sprawdzam tego. Nie bardzo nawet umiem takie rzeczy robić. 1 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!