STM Урок 39. Подключаем акселерометр LSM303DLHC. Часть 2

 

 

 

Урок 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();

}

 

Задержка добавлена с учетом на то, что датчику нужно какое-то время для включения. Т.е. если идентификатор совпадёт с идентификатором из даташита, то мы зажжем зеленый светодиод, а если нет, то вызовем обработчика ошибки, который зажжет нам красный светодиод. Прошьем контроллер и проверим это

 

image26

 

 

Если всё нормально и светодиод светится зелёный, продолжаем дальше. Если не так, то советую несколько раз передернуть плату, пройти по отладчику, повторить процесс. Такое бывает.

Внесем на будущее некоторые макроподстановки в файл 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 Следующая часть

 

Техническая документация на датчик

Программа SF Monitor

 

 

Купить отладочную плату можно здесь STM32F3-DISCOVERY

 

 

Смотреть ВИДЕОУРОК

 

STM Подключаем акселерометр LSM303DLHC

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*