Странно, у меня наоборот - не было с ним особых проблем никогда... Хотел библиотеку скинуть из одного проекта, сто процентов рабочий вариант, но там по I2C у меня. Посмотри все равно, может поможет:
Там под RTOS работало, в целом используется примерно так:
void main() { MPU9250_Init(); while(1) { MPU9250_Process(); } }
Данные с датчика тут:
float MPU9250_CompassAngles[ANGLES_NUM]; float MPU9250_Acc[AXIS_NUM]; float MPU9250_Gyro[AXIS_NUM];
Первая переменная - уже после пересчета в углы pitch, roll, yaw, сырые с магнетометра там внутри тоже где-то есть. В MPU9250_Init() проверка на WHO_AM_I = 0x71, если что, надо убрать или на свое значение актуальное изменить.
А непосредственно по проблеме - выкинь дисплей временно из проекта, чисто под отладчиком всегда будут адекватные данные? Если да, то аналогично под отладчиком можно будет отловить момент, когда что-то нарушается.
У меня ощущение, что CS поднимается раньше, чем заканчивается передача/приём.
Такие глюки чаще всего от этого бывают.
У меня ощущение, что CS поднимается раньше, чем заканчивается передача/приём.
Такие глюки чаще всего от этого бывают.
Да, похоже.
Приобрел для сравнения модуль MPU6050. Его данные акселерометра и гироскопа отличаются от данных MPU9250. Это меня очень удивило, датчики расположены в одной плоскости и оси направлены одинаково. Но используя алгоритм Кальмана в обоих модулях, я был удивлен, что крен и тангаж в обоих устройствах почти одинаковы.
Я когда-то находил отрисовку крена и тангажа на мониторе. Простейший прямоугольник наклонялся в разные стороны. Сейчас не могу найти сей алгоритм на просторах интернета. Можно конечно самому сбастать, но это долго. Может у кого-то есть эти ссылки? Поделитесь пожалуйста.
А магнитометр так и не заработал. Жду еще один модуль MPU9250, чтоб проверить, что в действительности. Инициализация или сам модуль хреновый?
Я только не просмотрел, поди на ардуино там.
У меня ощущение, что CS поднимается раньше, чем заканчивается передача/приём.
Такие глюки чаще всего от этого бывают.
Перед тем как поднять CS нужно дождаться опустошения буферов TX и RX. В STM LL Library это делается следующим циклом:
while (!LL_SPI_IsActiveFlag_TXE(SPI1)){}
Как здесь это сделать, имея в наборе HAL-функции, я не представляю...
Есть идеи???
@mihayk У ST концепция, что HAL - это самый верхний уровень, вся работа с флагами ниже, поэтому там, насколько я помню, через HAL_xxx функции напрямую к флагам/регистрам нет доступа.
То есть гипотетически ты берешь функцию HAL_Transmit() или подобную и все проверки уже внутри нее выполняются.
@aveal Можно ли эти LL и Hal библиотеки использовать вместе?
@mihayk Ну технически-то ничего не мешает... Тут вопрос, что наверно что-то не так могло в другом месте пойти. Нет возможности полный проект скинуть?
@mihayk Ну технически-то ничего не мешает... Тут вопрос, что наверно что-то не так могло в другом месте пойти. Нет возможности полный проект скинуть?
Проект скинуть могу.
Но похоже я нашел панацею всех бед содинения 3 устройств на одну шину SPI (1 Master 2 Slave). Перед тем как оключить Slave надо дождаться завершения передачи (выставления регистра)
void ST7735_Unselect() { while ((((hspi1.Instance->SR) & (SPI_FLAG_RXNE)) == (SPI_FLAG_RXNE))){} HAL_GPIO_WritePin(ST7735_CS_GPIO_Port, ST7735_CS_Pin, GPIO_PIN_SET); }
Вот в этом и была вся собака, которая кусалась всю неделю!
@mihayk Правильнее проверять флаг BSY, тогда точно SPI больше ничего не делает.
RXNE только говорит, что приём закончен и байт в буфере. А в это время может приниматься следующий байт.
@mihayk Правильнее проверять флаг BSY, тогда точно SPI больше ничего не делает.
RXNE только говорит, что приём закончен и байт в буфере. А в это время может приниматься следующий байт.
В принципе и мой вариант тоже подойдет, Я жду когда флаг RXNE исчезнет, т.е. даже в буфере байтов нет!