Урок 41
Часть 3
Подключаем акселерометр LIS3DSH
В предыдущей чатсти нашего занятия мы считали идентификатор данных, тем самым убедились в правильных настройках шины и то, что мы работаем именно с этим датчиком, а также написали функцию записи данных в регистры акселерометра.
Теперь напишем напишем код в функцию инициализации настроек
void AccInit(uint16_t InitStruct)
{
uint8_t ctrl = 0x00;
ctrl = (uint8_t) (InitStruct);
Accel_IO_Write(&ctrl, LIS3DSH_CTRL_REG4_ADDR, 1);
ctrl = (uint8_t) (InitStruct >> 8);
Accel_IO_Write(&ctrl, LIS3DSH_CTRL_REG5_ADDR, 1);
}
Назначение регистров 4 и 5 датчика разберем чуть ниже, когда будем заносить туда данные настроек.
Теперь продолжим писать код в функцию основной инициализации нашего акселерометра
else Error();
/* Configure MEMS: power mode(ODR) and axes enable */
ctrl = (uint16_t) (LIS3DSH_DATARATE_100 | LIS3DSH_XYZ_ENABLE);
/* Configure MEMS: full scale and self test */
ctrl |= (uint16_t) ((LIS3DSH_SERIALINTERFACE_4WIRE |
LIS3DSH_SELFTEST_NORMAL |
LIS3DSH_FULLSCALE_2 |
LIS3DSH_FILTER_BW_800) << 8);
AccInit(ctrl);
LD6_ON;
}
А теперь попытаемся разобраться, что и куда мы заносим.
Сначала разберемся с регистром LIS3DSH_CTRL_REG4_ADDR (адрес 0x20)
В нём мы настроим следующие биты:
LIS3DSH_DATARATE_100: значение 0x60: данным значением мы включим биты ODR1 и ODR2, тем самым настроим скорость передачи данных 100 герц.
LIS3DSH_XYZ_ENABLE: значение 0x07: включим биты всех осей, тем самым скажем датчику о том, чтобы он нам считывал данные всех трёх осей (x,y и z)
Больше мы в данном регистре ничего не включаем. Теперь разберемся со следующим регистром: LIS3DSH_CTRL_REG5_ADDR (адрес 0x24).
Здесь будут следующие настройки:
LIS3DSH_SERIALINTERFACE_4WIRE: значение 0x00: данный бит отвечает за включение режима интерфейсной шины. Оставляем 0, тем самым мы включим 4-проводной SPI.
LIS3DSH_SELFTEST_NORMAL: значение 0x00: здесь мы обозначим, что мы не будем включать биты 1 и 2 (ST1 и ST2), тем самым мы включим режим первоначального самотестирования (обычный режим).
LIS3DSH_FULLSCALE_2: значение 0x00: биты FSCALE мы также не включаем, тем самым скажем акселерометру, чтобы он измерял показания по всем осям в пределах от -2G до +2G.
LIS3DSH_FILTER_BW_800: значение 0x00: биты ширины полосы пропускания фильтра сглаживания. Мы их не устанавливаем, поэтому ширина полосы пропускания у нас будет 800 герц.
Ну и для того, чтобы получить информацию о том, что у нас ничего не подвисло, включим ещё в конце функции синий светодиод.
Теперь перейдем к более интересной части нашего урока – получение измеренных показаний из датчика. Внесем определенный код в функцию Accel_GetXYZ.
void Accel_GetXYZ(int16_t* pData)
{
int8_t buffer[6];
uint8_t crtl, i = 0x00;
float sensitivity = LIS3DSH_SENSITIVITY_0_06G;
float valueinfloat = 0;
}
В этом коде добавления в функцию переменных нам интересно значение чувствительности LIS3DSH_SENSITIVITY_0_06G. Здесь мы настраиваем то, что в определенный регистр мы внесем позже такие данные, которые позволят нам настроить чувствительность датчика до 0.06 mg.
Считаем данные из регистра LIS3DSH_CTRL_REG5_ADDR (адрес 0x24), назначение битов которого мы разбирали выше, в переменную ctrl.
float valueinfloat = 0;
Accel_IO_Read(&crtl, LIS3DSH_CTRL_REG5_ADDR, 1);
}
Далее из соответствующих регистров датчика мы считаем младшие и старшие байты 16-битных показаний, измеренных по каждой из трёх осей
Accel_IO_Read(&crtl, LIS3DSH_CTRL_REG5_ADDR, 1);
Accel_IO_Read((uint8_t*)&buffer[0], LIS3DSH_OUT_X_L_ADDR, 1);
Accel_IO_Read((uint8_t*)&buffer[1], LIS3DSH_OUT_X_H_ADDR, 1);
Accel_IO_Read((uint8_t*)&buffer[2], LIS3DSH_OUT_Y_L_ADDR, 1);
Accel_IO_Read((uint8_t*)&buffer[3], LIS3DSH_OUT_Y_H_ADDR, 1);
Accel_IO_Read((uint8_t*)&buffer[4], LIS3DSH_OUT_Z_L_ADDR, 1);
Accel_IO_Read((uint8_t*)&buffer[5], LIS3DSH_OUT_Z_H_ADDR, 1);
Дальше проверим считанные биты из 5 регистра. Так как нас интересуют только 1,2 и 5 бит, то остальные сбросим маской (LIS3DSH__FULLSCALE_SELECTION = 0x38)
Accel_IO_Read((uint8_t*)&buffer[5], LIS3DSH_OUT_Z_H_ADDR, 1);
switch(crtl & LIS3DSH__FULLSCALE_SELECTION)
{
}
В зависимости от значений данных битов внесём значение в переменную sensitivity (чувствительность), то есть мы тем самым будем настраивать чувствительность датчика в зависимости от пределов измерений.
switch(crtl & LIS3DSH__FULLSCALE_SELECTION)
{
case LIS3DSH_FULLSCALE_2:
sensitivity = LIS3DSH_SENSITIVITY_0_06G;
break;
case LIS3DSH_FULLSCALE_4:
sensitivity = LIS3DSH_SENSITIVITY_0_12G;
break;
case LIS3DSH_FULLSCALE_6:
sensitivity = LIS3DSH_SENSITIVITY_0_18G;
break;
case LIS3DSH_FULLSCALE_8:
sensitivity = LIS3DSH_SENSITIVITY_0_24G;
break;
case LIS3DSH_FULLSCALE_16:
sensitivity = LIS3DSH_SENSITIVITY_0_73G;
break;
default:
break;
}
Ну и в соответствии с чувствительностью несколько преобразуем измеренные показания и внесем их в буфер для дальнейшего использования в работе нашей программы.
break;
}
for(i=0; i<3; i++)
{
valueinfloat = ((buffer[2*i+1] << 8) + buffer[2*i]) * sensitivity;
pData[i] = (int16_t)valueinfloat;
}
}
Далее напишем код в функции Accel_ReadAcc.
void Accel_ReadAcc(void)
{
int16_t buffer[3] = {0};
int16_t xval, yval , zval = 0x00;
Accel_GetXYZ(buffer);
HAL_Delay(20);
}
Показания с датчика считываем в бесконечном цикле в функции main().
/* USER CODE BEGIN 3 */
Accel_ReadAcc();
}
/* USER CODE END 3 */
В следующей части занятия мы мы завершим работу с датчиком-акселерометром LIS3DSH, закончим писать функцию сбора значений с осей акселерометра и мониторинга данных значений с помощью светодиодов, терминала и программы визуализации, которую я написал сам.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация на датчик
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий