STM Урок 51. Подключаем магнитометр LIS3MDL. Часть 1

 

 

 

Урок 51.

 

Часть 1

 

Магнитометр LIS3MDL

 

 

Сегодня мы продолжаем работу с датчиками, которые измеряют магнитную индукцию и называются магнитометрами. Мы рассматриваем и изучаем датчик-магнитометр, установленный на плате расширения X-NUCLEO-IKS01A1, предназначенной для работы с отладочной платой Nucleo. Мы будем подключать данную оценочную плату к плате Nucleo STM32F401RE. Выполнен данный датчик также с использованием технологии MEMS.

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

Датчик имеет следующие технические характеристики:

Диапазон показаний ±4/ ±8/ ±12/ ±16 gauss;

Чувствительность 1711 – 6842 LSB/gauss;

Среднеквадратичное значение уровня шума (RMS noise) при диапазоне ±12: 3.2 – 4.1 mgauss;

Отклонение от нуля ±1 mgauss при установке диапазона ±4 gauss.

Частота измерений 0,625 – 80 Гц.

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

Проект мы создадим из готового проекта, в котором мы работали с гироскопом, установленном на этой же плате расширения – из проекта Gyro_LSM6DS0, только назовём мы данный проект теперь соответственно Mag_LIS3MDL.

Файлы lsm6ds0.c и lsm6ds0.h соответственно переименуем в lis3mdl.c и lis3mdl.h.

Запустим проект Cube MX. Проверим, что скорость USART у нас выставлена 230400 bps. Если не такая, то установим именно такую

  image07

 

Убедимся в том, что прерывания от USART у нас включены

 

image09

 

Также нам нужен будет таймер, так как вместо бесконечного цикла мы будем использовать его. Задействовав таймер, мы сразу решим две проблемы. Во-первых, не нужно будет использовать задержку в процедуре считывания и обработки, что исключит простаивание и невозможность использования ресурсов МК. Во-вторых, теперь считывать оси мы будем только тогда, когда того захочет программа визуализации, тем самым исключим принятие одного и того же буфера на стороне ПК. Включим, например, TIM1

 

image08

 

Таймер сконфигурируем следующим образом

 

image11image10

 

Сгенерируем проект, откроем его. Настроим программатор на авторезет. Добавим файл lis3mdl.c. Скомпилируем проект.

По причине переименования файлов у нас будут ошибки. Для устранения данных ошибок мы исправим подключение заголовочных файлов в main.c и в lis3mdl.с

 

#include "stm32f4xx_hal.h"

#include "lis3mdl.h"

//——————————————-

 

В бесконечном цикле пока закомментируем код вызова функции считывания данных и отправки их в USART

 

  /* USER CODE BEGIN 3 */

                   //AccelGyro_Read();

  }

 

 

В файле lis3mdl.h удалим весь код и скопируем туда для экономии драгоценного времени заранее подготовленный код со всеми макросами и переменными из файла macro.txt

 

#ifndef LIS3MDL_H_

#define LIS3MDL_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 MAG_I2C_ADDRESS        0x3C

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

#define        LIS3MDL_MAG_WHO_AM_I_REG        0X0F

#define LIS3MDL_MAG_CTRL_REG1        0X20

#define        LIS3MDL_MAG_CTRL_REG2        0X21

#define        LIS3MDL_MAG_CTRL_REG3        0X22

#define LIS3MDL_MAG_CTRL_REG5        0X24

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

#define        LIS3MDL_MAG_WHO_AM_I        0x3D

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

#define        LIS3MDL_MAG_MD_CONTINUOUS        0x00

#define        LIS3MDL_MAG_MD_SINGLE        0x01

#define        LIS3MDL_MAG_MD_POWER_DOWN        0x02

#define        LIS3MDL_MAG_MD_POWER_DOWN_AUTO        0x0

#define        LIS3MDL_MAG_MD_MASK        0x03

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

#define        LIS3MDL_MAG_BDU_DISABLE        0x00

#define        LIS3MDL_MAG_BDU_ENABLE        0x40

#define        LIS3MDL_MAG_BDU_MASK        0x40

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

#define        LIS3MDL_MAG_DO_0_625Hz        0x00

#define        LIS3MDL_MAG_DO_1_25Hz        0x04

#define        LIS3MDL_MAG_DO_2_5Hz        0x08

#define        LIS3MDL_MAG_DO_5Hz        0x0C

#define        LIS3MDL_MAG_DO_10Hz        0x10

#define        LIS3MDL_MAG_DO_20Hz        0x14

#define        LIS3MDL_MAG_DO_40Hz        0x18

#define        LIS3MDL_MAG_DO_80Hz        0x1C

#define        LIS3MDL_MAG_DO_MASK        0x1C

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

#define        LIS3MDL_MAG_FS_4Ga        0x00

#define        LIS3MDL_MAG_FS_8Ga        0x20

#define        LIS3MDL_MAG_FS_12Ga        0x40

#define        LIS3MDL_MAG_FS_16Ga        0x60

#define        LIS3MDL_MAG_FS_MASK        0x60

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

#define        LIS3MDL_MAG_OM_LOW_POWER        0x00

#define        LIS3MDL_MAG_OM_MEDIUM        0x20

#define        LIS3MDL_MAG_OM_HIGH        0x40

#define        LIS3MDL_MAG_OM_ULTRA_HIGH        0x60

#define        LIS3MDL_MAG_OM_MASK        0x60

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

#define        LIS3MDL_MAG_TEMP_EN_DISABLE        0x00

#define        LIS3MDL_MAG_TEMP_EN_ENABLE        0x80

#define        LIS3MDL_MAG_TEMP_EN_MASK        0x80

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

#define LIS3MDL_MAG_OUTX_L    0X28

#define LIS3MDL_MAG_OUTX_H    0X29

#define LIS3MDL_MAG_OUTY_L    0X2A

#define LIS3MDL_MAG_OUTY_H    0X2B

#define LIS3MDL_MAG_OUTZ_L    0X2C

#define LIS3MDL_MAG_OUTZ_H    0X2D

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

void Mag_Ini(void);

void Mag_Read(void);

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

#endif /* LIS3MDL_H_ */

 

Функцию Accel_Gyro_Ini переименуем в Mag_Ini в файлах main.c и в lis3mdl.с

 

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

void Mag_Ini(void)

{

        Mag_Ini();

  /* USER CODE END 2 */

 

Следующая задача у нас – написать код инициализации датчика. И, как всегда, по сложившейся традиции, раз уж у нас подключение именно по шине I2C, начинаем мы её, конечно же, со считывания идентификатора микросхемы.

Исходя из подключения микросхемы, адрес мы выбираем 0x3C

 

image13

 

Регистр для чтения идентификатора используем WHO_AM_I (0Fh)

 

image12

 

В данной таблице мы также видим, переведя двоичный код в шестнадцатеричный, что идентификатор должен быть равен именно 0x3D.

Функцию Accel_ReadID переименуем в Mag_ReadID и в реализации, и в вызове

 

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

uint8_t Mag_ReadID(void)

{

        HAL_Delay(1000);

        if(Mag_ReadID()==0x68) LD2_ON;

 

Аналогичным образом поступим и с функциями Accel_IO_Read и Accel_IO_Write

 

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

uint8_t Mag_IO_Read(uint16_t DeviceAddr, uint8_t RegisterAddr)

{

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

void Mag_IO_Write(uint16_t DeviceAddr, uint8_t RegisterAddr, uint8_t Value)

{

 

Также подправим код в функции чтения идентификатора

 

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

uint8_t Mag_ReadID(void)

{

        uint8_t ctrl = 0x00;

        ctrl = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_WHO_AM_I_REG);

        return ctrl;

}

 

Исправим код в главной функции инициализации

 

        HAL_Delay(1000);

        if(Mag_ReadID()==LIS3MDL_MAG_WHO_AM_I) LD2_ON;

 

В функциях, которые мы пока не используем, закомментируем весь код, облачив его вот в такие теги /* */.

Скомпилируем код, прошьём контроллер и проверим результат нашей работы. Зелёный светодиод должен загореться

 

 

image27

 

 

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

 

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

 

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

Программа Hyper Terminal

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

Программа NS Mag Visual

 

 

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

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

 

 

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

 

STM32 Подключаем магнитометр LIS3MDL

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

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

*