STM Урок 43. Подключаем акселерометр LSM6DS3. Часть 1

 

 

 

Урок 43

 

Часть 1

 

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

 

 

        Сегодня мы рассмотрим датчик, который также в себе объединяет сразу два функционала – акселерометр и гироскоп. Данный акселерометр – это также акселерометр, выполненный с использованием технологии MEMS – LSM6DS3. Установлен он на плате расширения STEVAL-MKI160V1, которая в свою очередь вставляется в плату расширения X-NUCLEO-IKS01A1, предназначенной для работы с отладочной платой Nucleo. Мы будем подключать данную оценочную плату к плате Nucleo STM32F401RE.

        Данный акселерометр-гироскоп также наряду с интерфейсом I2C может подключиться и с использованием интерфейса SPI. Но мы будем использовать подключение именно по I2C.

Также использовать в рамках данного занятия мы данный датчик будем только как акселерометр. В качестве гироскопа мы его подключим на более поздних занятиях. По сравнению с рассмотренным нами на прошлом занятии акселерометром LSM6DS0, данный датчик имеет более лучшие характеристики::

        Диапазон показаний ±2g/±4g/±8g/±16g;

Чувствительность 0.061 – 0.49 mg/digit;

Отклонение от нуля ±40 mg.

Скорость считывания данных 12,5 Гц – 6,66 кГц.

С некоторыми остальными показателями, регистрами, значениями и другими тонкостями акселерометра мы познакомимся в ходе его программирования.

Для программирования данного датчика мы создадим проект Accel_LSM6DS3 из предыдущего проекта Accel_LSM6DS0. Кроме этого мы также переименуем файлы lsm6ds0.h и lsm6ds0.c соответственно в lsm6ds3.h и lsm6ds3.c.

Запустим проект в Cube MX. Ничего там не будем трогать, даже скорость USART оставим 256000 б/с. Сгенерируем проект для Keil, откроем его, включим программатор на авторезет, подключим файл lsm6ds0.c.

Исправим в файле main.h в строке ноль на тройку

 

#include "stm32f4xx_hal.h"

#include "lsm6ds3.h"

 

То же самое проделаем и в файле lsm6ds3.c

 

#include "lsm6ds3.h"

//———————————————

 

Соберем проект.

Удалять пока ничего не будем. Файл lsm6ds3.h изменим до следующего состояния, скопировав в него заранее подготовленный код вместе со всеми макросами:

 

#ifndef LSM6DS3_H_

#define LSM6DS3_H_

 

#include "stm32f4xx_hal.h"

#include <string.h>

//————————————————

#define ABS(x)         (x < 0) ? (-x) : x

//————————————————

#define LD2_Pin GPIO_PIN_5

#define LD2_GPIO_Port GPIOA

#define LD2_ON HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET) //GREEN

#define LD2_OFF HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)

//————————————————

#define LSM6DS3_ACC_GYRO_CTRL1_XL          0X10

#define LSM6DS3_ACC_GYRO_CTRL3_C          0X12

#define LSM6DS3_ACC_GYRO_FIFO_CTRL5          0X0A

#define LSM6DS3_ACC_GYRO_CTRL9_XL          0X18

//————————————————

#define LSM6DS3_ACC_GYRO_IF_INC_DISABLED        0x00

#define LSM6DS3_ACC_GYRO_IF_INC_ENABLED        0x04

#define LSM6DS3_ACC_GYRO_IF_INC_MASK 0x04

//————————————————

#define LSM6DS3_ACC_GYRO_BDU_CONTINUOS        0x00

#define LSM6DS3_ACC_GYRO_BDU_BLOCK_UPDATE        0x40

#define LSM6DS3_ACC_GYRO_BDU_MASK   0x40

//————————————————

#define LSM6DS3_ACC_GYRO_FIFO_MODE_BYPASS        0x00

#define LSM6DS3_ACC_GYRO_FIFO_MODE_FIFO        0x01

#define LSM6DS3_ACC_GYRO_FIFO_MODE_STREAM        0x02

#define LSM6DS3_ACC_GYRO_FIFO_MODE_STF        0x03

#define LSM6DS3_ACC_GYRO_FIFO_MODE_BTS        0x04

#define LSM6DS3_ACC_GYRO_FIFO_MODE_DYN_STREAM        0x05

#define LSM6DS3_ACC_GYRO_FIFO_MODE_DYN_STREAM_2        0x06

#define LSM6DS3_ACC_GYRO_FIFO_MODE_BTF        0x07

#define LSM6DS3_ACC_GYRO_FIFO_MODE_MASK   0x07

//————————————————

#define LSM6DS3_ACC_GYRO_ODR_XL_POWER_DOWN        0x00

#define LSM6DS3_ACC_GYRO_ODR_XL_13Hz        0x10

#define LSM6DS3_ACC_GYRO_ODR_XL_26Hz        0x20

#define LSM6DS3_ACC_GYRO_ODR_XL_52Hz        0x30

#define LSM6DS3_ACC_GYRO_ODR_XL_104Hz        0x40

#define LSM6DS3_ACC_GYRO_ODR_XL_208Hz        0x50

#define LSM6DS3_ACC_GYRO_ODR_XL_416Hz        0x60

#define LSM6DS3_ACC_GYRO_ODR_XL_833Hz        0x70

#define LSM6DS3_ACC_GYRO_ODR_XL_1660Hz        0x80

#define LSM6DS3_ACC_GYRO_ODR_XL_3330Hz        0x90

#define LSM6DS3_ACC_GYRO_ODR_XL_6660Hz        0xA0

#define LSM6DS3_ACC_GYRO_ODR_XL_13330Hz        0xB0

#define LSM6DS3_ACC_GYRO_ODR_XL_MASK        0xF0

//————————————————

#define LSM6DS3_ACC_GYRO_FS_XL_2g        0x00

#define LSM6DS3_ACC_GYRO_FS_XL_16g        0x04

#define LSM6DS3_ACC_GYRO_FS_XL_4g        0x08

#define LSM6DS3_ACC_GYRO_FS_XL_8g        0x0C

#define        LSM6DS3_ACC_GYRO_FS_XL_MASK        0x0C

//————————————————

#define        LSM6DS3_ACC_GYRO_XEN_XL_MASK        0x08

#define        LSM6DS3_ACC_GYRO_YEN_XL_MASK        0x10

#define        LSM6DS3_ACC_GYRO_ZEN_XL_MASK        0x20

#define        LSM6DS3_ACC_GYRO_XEN_XL_ENABLED        0x08

#define        LSM6DS3_ACC_GYRO_YEN_XL_ENABLED        0x10

#define        LSM6DS3_ACC_GYRO_ZEN_XL_ENABLED        0x20

//————————————————

#define LSM6DS3_ACC_GYRO_OUTX_L_XL          0X28

#define LSM6DS3_ACC_GYRO_OUTX_H_XL          0X29

#define LSM6DS3_ACC_GYRO_OUTY_L_XL          0X2A

#define LSM6DS3_ACC_GYRO_OUTY_H_XL          0X2B

#define LSM6DS3_ACC_GYRO_OUTZ_L_XL          0X2C

#define LSM6DS3_ACC_GYRO_OUTZ_H_XL          0X2D

//————————————————

void Accel_Ini(void);

void Accel_ReadAcc(void);

//————————————————

#endif /* LSM6DS3_H_ */

 

Назначение макросов обсудим в процессе написания кода. Соберем проект. Ошибочный код пока закомментируем.

 

 

Найдем в технической документации адрес, по которому мы будем обращаться по I2C (стр. 35). В данной плате расширения разработчики ножку SA0 соединили с общим проводом для того, чтобы мы могли использовать оба датчика, и чтобы не было одинаковых адресов. Поэтому мы будем использовать 0xD4.

 

image00

 

Найдем адрес регистра хранения идентификатора и сам идентификатор

 

image02

 

Исправим код в чтении идентификатора

 

        uint8_t ctrl = 0x00;

        ctrl = Accel_IO_Read(0xD4,0x0F);

        return ctrl;

 

Также исправим код в функции инициализации

 

        HAL_Delay(1000);

        if(Accel_ReadID()==0x69) LD2_ON;

        else Error();

 

Подключим контроллер, соберём код и проверим, считался ли у нас идентификатор

 

image15

 

Светодиод светится зелёным цветом, значит идентификатор считан правильно.

Теперь начнем писать настройку датчика перед использованием

 

void AccInit(uint16_t InitStruct)

{

        uint8_t value = 0;

        //автоувеличение адреса регистра

        value = Accel_IO_Read(0xD4,LSM6DS3_ACC_GYRO_CTRL3_C);

        value&=~LSM6DS3_ACC_GYRO_IF_INC_MASK;

        value|=LSM6DS3_ACC_GYRO_IF_INC_ENABLED;

        Accel_IO_Write(0xD4,LSM6DS3_ACC_GYRO_CTRL3_C,value);

 

Данным кодом мы обращаемся к управляющему регистру 3 и включаем там бит автоувеличения адреса регистра

 

image01

image04

 

Пока на сегодня закончим с инициализацией.

В следующей части занятия мы полностью закончим нашу работу с данным датчиком.

 

Предыдущий урок Программирование МК STM32 Следующая часть

 

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

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

Программа NS Port Monitor

 

 

Отладочную плату можно приобрести здесь Nucleo STM32F401RE

Оценочную плату можно приобрести здесь STM32 X-NUCLEO-IKS01A1

Приобрести платы с датчиком LSM6DS3 можно у следующих продавцов:

Надёжный продавец LSM6DS33 STEVAL-MKI160V1

Здесь дешевле LSM6DS33 STEVAL-MKI160V1

Здесь другая плата, намного дешевле, но от другого разработчика LSM6DS33

 

 

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

 

STM32 Подключаем акселерометр LSM6DS3

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

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

*