Урок 39
Подключаем акселерометр LSM303DLHC
Часть 2
В предыдущей части нашего урока мы кратко изучили документацию на датчик, создали для него проект, добавили некоторые макросы и начали писать функцию инициализации датчика.
Теперь нам понадобится следующая функция
#include «lsm303dlhc.h»
//—————————————
uint8_t Accel_IO_Read(uint16_t DeviceAddr, uint8_t RegisterAddr)
{
}
Жирным шрифтом я буду выделять новые фрагменты. А старые я размещаю в статью для того, чтобы понять, куда именно писать код. Также функции, которые мы вызываем из других, я стараюсь писать выше, иначе придется писать прототип. Добавим объявление указателя шины I2C
#include «lsm303dlhc.h»
//————————————
extern I2C_HandleTypeDef hi2c1;
//————————————
Следующие две функции в том же файле:
extern I2C_HandleTypeDef hi2c1;
//————————————
static void Error (void)
{
LD3_ON;
}
//—————————————
static uint8_t I2Cx_ReadData(uint16_t Addr, uint8_t Reg)
{
HAL_StatusTypeDef status = HAL_OK;
uint8_t value = 0;
status = HAL_I2C_Mem_Read(&hi2c1, Addr, Reg, I2C_MEMADD_SIZE_8BIT, &value, 1, 0x10000);
if(status != HAL_OK)
{
/* Execute user timeout callback */
Error();
}
return value;
}
//—————————————
Теперь, заполнив вышестоящие в файле функции, будем двигаться сверху вниз по остальным функциям. Допишем функцию Accel_IO_Read:
uint8_t Accel_IO_Read(uint16_t DeviceAddr, uint8_t RegisterAddr)
{
return I2Cx_ReadData(DeviceAddr, RegisterAddr);
}
Теперь допишем функцию Accel_ReadID:
uint8_t ctrl = 0x00;
ctrl = Accel_IO_Read(0x32, 0x0F);
return ctrl;
Ну и добавим в функцию инициализации функцию считывания идентификатора датчика:
void Accel_Ini(void)
{
uint16_t ctrl = 0x0000;
HAL_Delay(1000);
if(Accel_ReadID()==0x33) LD6_ON;
else Error();
}
Задержка добавлена с учетом на то, что датчику нужно какое-то время для включения. Т.е. если идентификатор совпадёт с идентификатором из даташита, то мы зажжем зеленый светодиод, а если нет, то вызовем обработчика ошибки, который зажжет нам красный светодиод. Прошьем контроллер и проверим это
Если всё нормально и светодиод светится зелёный, продолжаем дальше. Если не так, то советую несколько раз передернуть плату, пройти по отладчику, повторить процесс. Такое бывает.
Внесем на будущее некоторые макроподстановки в файл lsm303dlhc.h для регистров и значений регистров нашего датчика
#define LD10_OFF HAL_GPIO_WritePin(LD_PORT, LD10, GPIO_PIN_RESET) //RED2
//————————————————
#define LSM303DLHC_NORMAL_MODE ((uint8_t)0x00)
#define LSM303DLHC_LOWPOWER_MODE ((uint8_t)0x08)
//————————————————-
#define LSM303DLHC_ODR_1_HZ ((uint8_t)0x10) /*!< Output Data Rate = 1 Hz */
#define LSM303DLHC_ODR_10_HZ ((uint8_t)0x20) /*!< Output Data Rate = 10 Hz */
#define LSM303DLHC_ODR_25_HZ ((uint8_t)0x30) /*!< Output Data Rate = 25 Hz */
#define LSM303DLHC_ODR_50_HZ ((uint8_t)0x40) /*!< Output Data Rate = 50 Hz */
#define LSM303DLHC_ODR_100_HZ ((uint8_t)0x50) /*!< Output Data Rate = 100 Hz */
#define LSM303DLHC_ODR_200_HZ ((uint8_t)0x60) /*!< Output Data Rate = 200 Hz */
#define LSM303DLHC_ODR_400_HZ ((uint8_t)0x70) /*!< Output Data Rate = 400 Hz */
#define LSM303DLHC_ODR_1620_HZ_LP ((uint8_t)0x80) /*!< Output Data Rate = 1620 Hz only in Low Power Mode */
#define LSM303DLHC_ODR_1344_HZ ((uint8_t)0x90) /*!< Output Data Rate = 1344 Hz in Normal mode and 5376 Hz*/
//————————————————-
#define LSM303DLHC_X_ENABLE ((uint8_t)0x01)
#define LSM303DLHC_Y_ENABLE ((uint8_t)0x02)
#define LSM303DLHC_Z_ENABLE ((uint8_t)0x04)
#define LSM303DLHC_AXES_ENABLE ((uint8_t)0x07)
#define LSM303DLHC_AXES_DISABLE ((uint8_t)0x00)
//————————————————-
#define LSM303DLHC_HR_ENABLE ((uint8_t)0x08)
#define LSM303DLHC_HR_DISABLE ((uint8_t)0x00)
//————————————————-
#define LSM303DLHC_FULLSCALE_2G ((uint8_t)0x00) /*!< ±2 g */
#define LSM303DLHC_FULLSCALE_4G ((uint8_t)0x10) /*!< ±4 g */
#define LSM303DLHC_FULLSCALE_8G ((uint8_t)0x20) /*!< ±8 g */
#define LSM303DLHC_FULLSCALE_16G ((uint8_t)0x30) /*!< ±16 g */
//————————————————-
#define LSM303DLHC_BlockUpdate_Continous ((uint8_t)0x00) /*!< Continuos Update */
#define LSM303DLHC_BlockUpdate_Single ((uint8_t)0x80) /*!< Single Update: output registers not updated until MSB and LSB reading */
//————————————————-
#define LSM303DLHC_BLE_LSB ((uint8_t)0x00) /*!< Little Endian: data LSB @ lower address */
#define LSM303DLHC_BLE_MSB ((uint8_t)0x40) /*!< Big Endian: data MSB @ lower address */
//————————————————-
#define LSM303DLHC_HPM_NORMAL_MODE_RES ((uint8_t)0x00)
#define LSM303DLHC_HPM_REF_SIGNAL ((uint8_t)0x40)
#define LSM303DLHC_HPM_NORMAL_MODE ((uint8_t)0x80)
#define LSM303DLHC_HPM_AUTORESET_INT ((uint8_t)0xC0)
//————————————————-
#define LSM303DLHC_HPFCF_8 ((uint8_t)0x00)
#define LSM303DLHC_HPFCF_16 ((uint8_t)0x10)
#define LSM303DLHC_HPFCF_32 ((uint8_t)0x20)
#define LSM303DLHC_HPFCF_64 ((uint8_t)0x30)
//————————————————-
#define LSM303DLHC_HPF_AOI1_DISABLE ((uint8_t)0x00)
#define LSM303DLHC_HPF_AOI1_ENABLE ((uint8_t)0x01)
//————————————————-
#define LSM303DLHC_HPF_AOI2_DISABLE ((uint8_t)0x00)
#define LSM303DLHC_HPF_AOI2_ENABLE ((uint8_t)0x02)
//————————————————-
#define LSM303DLHC_CTRL_REG1_A 0x20 /* Control register 1 acceleration */
#define LSM303DLHC_CTRL_REG2_A 0x21 /* Control register 2 acceleration */
#define LSM303DLHC_CTRL_REG3_A 0x22 /* Control register 3 acceleration */
#define LSM303DLHC_CTRL_REG4_A 0x23 /* Control register 4 acceleration */
#define LSM303DLHC_CTRL_REG5_A 0x24 /* Control register 5 acceleration */
//————————————————-
#define LSM303DLHC_ACC_SENSITIVITY_2G ((uint8_t)1) /*!< accelerometer sensitivity with 2 g full scale [mg/LSB] */
#define LSM303DLHC_ACC_SENSITIVITY_4G ((uint8_t)2) /*!< accelerometer sensitivity with 4 g full scale [mg/LSB] */
#define LSM303DLHC_ACC_SENSITIVITY_8G ((uint8_t)4) /*!< accelerometer sensitivity with 8 g full scale [mg/LSB] */
#define LSM303DLHC_ACC_SENSITIVITY_16G ((uint8_t)12) /*!< accelerometer sensitivity with 12 g full scale [mg/LSB] */
//————————————————
#define LSM303DLHC_OUT_X_L_A 0x28 /* Output Register X acceleration */
#define LSM303DLHC_OUT_X_H_A 0x29 /* Output Register X acceleration */
#define LSM303DLHC_OUT_Y_L_A 0x2A /* Output Register Y acceleration */
#define LSM303DLHC_OUT_Y_H_A 0x2B /* Output Register Y acceleration */
#define LSM303DLHC_OUT_Z_L_A 0x2C /* Output Register Z acceleration */
#define LSM303DLHC_OUT_Z_H_A 0x2D /* Output Register Z acceleration */
//————————————————
void Accel_Ini(void);
Продолжим нашу инициализацию. Для этого напишем удобную функцию отправки данных в шину I2C
//—————————————
static void I2Cx_WriteData(uint16_t Addr, uint8_t Reg, uint8_t Value)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&hi2c1, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 0x10000);
/* Check the communication status */
if(status != HAL_OK)
{
/* Execute user timeout callback */
Error();
}
}
//—————————————
Еще одна удобная функцию для I2C
//—————————————
void Accel_IO_Write(uint16_t DeviceAddr, uint8_t RegisterAddr, uint8_t Value)
{
I2Cx_WriteData(DeviceAddr, RegisterAddr, Value);
}
//—————————————
Также напишем функцию для инициализации настроек акселерометра:
//—————————————
void AccInit(uint16_t InitStruct)
{
uint8_t ctrl = 0x00;
ctrl = (uint8_t) InitStruct;
Accel_IO_Write(0x32, LSM303DLHC_CTRL_REG1_A, ctrl);
ctrl = (uint8_t) (InitStruct << 8);
Accel_IO_Write(0x32, LSM303DLHC_CTRL_REG4_A, ctrl);
}
//—————————————
В следующей части нашего занятия мы закончим наконец-то полностью инициализацию акселерометра.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация на датчик
Купить отладочную плату можно здесь STM32F3-DISCOVERY
Смотреть ВИДЕОУРОК
Здравствуйте! Я пытаюсь подключить акселерометр LIS331DLH.
Не совсем понятно как найти в документации вот эти два адреса:
ctrl = Accel_IO_Read(0x32, 0x0F);
if(Accel_ReadID()==0x33) LD6_ON;
т.е. даже в Вас в даташите не было этих адресов.