Урок 39
Подключаем акселерометр LSM303DLHC
Часть 1
С сегодняшнего урока мы начинаем изучать нелёгкую, но интересную тему – подключение датчиков, выполненных с использованием технологии MEMS.
Так как у меня появилось несколько плат расширений X-NUCLEO, я решил сделать цикл уроков по снятию и обработке показаний с датчиков MEMS, установленных на них. Но так как датчики, установленные на этих платах, не отличаются особой простотой, я решил начать изучение с более простых датчиков MEMS, установленных на других платах. Думаю, и вам тоже так будет проще изучить данную тему. Как говорится, от простого к сложному.
Сначала мы начнем цикл занятий именно с акселерометров, потому что они мне показались проще, скорее всего из-за того, что об их программировании я хотя бы что-то слышал и видел.
Начнем мы изучение с акселерометра-магнетометра, установленного на плате STM32F3Discovery. Этот датчик именуется LSM303DLHC. И изучим мы именно одну его часть – акселерометр.
Посмотрим схему на нашу плату F3. Увидим там подключение нашего акселерометра-магнетометра
Технические характеристики этого датчика описаны в даташите на него, ссылку на который я дам в конце статьи. Основные характеристики, которые нам понадобятся – это те, что он 16-битный, т.к. существуют еще и акселерометры 8-битные старого типа, но я думаю их мы не будем касаться, ибо это уже не актуально.
Также нам нужны следующие характеристики:
интерфейс для снятия показаний – I2C;
Диапазон показаний ±2g / ±4g / ±8g / ±16g;
Чувствительность 1-12 мг/LSB
Отклонение от нуля ±60 mg.
С остальными характеристиками, тонкостями, регистрами и другими подводными камнями акселерометра мы познакомимся в ходе его программирования.
Запустим Cube MX. Создадим новый проект. Выберем контроллер STM32F303VCTx.
Включим тактирование от кварцевого резонатора.
Настроим Clock Configuration на максимум (нажмите на картинку для увеличения)
Включим лапки портов, отвечающих за управление светодиодами на плате, на выход
Включим I2C1 переопределим ножки на PB6 и PB7, так как именно к данным ножкам у нас подключен акселерометр.
Также включим на вход остальные ножки портов, к которым подключены остальные ножки акселерометра (ножки прерываний). Скорее всего мы в рамках нашего занятия не воспользуемся ими, но для порядка все равно включим, чтобы не перепутать и не задействовать их ещё для чего-то.
Ещё включим USART2. По нему мы будем передавать снятые показания с датчика на ПК (нажмите на картинку для увеличения).
Идём в Configuration и сделаем следующие настройки. Скорость USART выставим 115200 bps. В принципе, пока больше ничего не будем трогать.
Настроим проект. Для этого идём в Project -> Settings. В верхней строке назовем проект Accel. В следующей строке выберем место, в котором будет находиться наш проект, также выберем среду программирования – MDK-ARM V5
В Configuration в настройках USART2 настроим скорость 115200 bps.
Сохраним изменения настроек нажатием кнопки «Ok».
Сгенерируем код, откроем проект, настроим программатор на авторезет, как обычно. Скомпилируем проект.
Создадим файл main.h, включив в него некоторые макроподстановки, предоставляющие нам удобство в дальнейшем работать с лапками портов для светодиодов:
#ifndef MAIN_H_
#define MAIN_H_
#include «stm32f3xx_hal.h»
#define LD_PORT GPIOE
#define LD3 GPIO_PIN_9 //RED1
#define LD4 GPIO_PIN_8 //BLUE1
#define LD5 GPIO_PIN_10 //ORANGE1
#define LD6 GPIO_PIN_15 //GREEN1
#define LD7 GPIO_PIN_11 //GREEN2
#define LD8 GPIO_PIN_14 //ORANGE2
#define LD9 GPIO_PIN_12 //BLUE2
#define LD10 GPIO_PIN_13 //RED2
#define LD3_ON HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_SET) //RED1
#define LD4_ON HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_SET) //BLUE1
#define LD5_ON HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_SET) //ORANGE1
#define LD6_ON HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_SET) //GREEN1
#define LD7_ON HAL_GPIO_WritePin(LD_PORT, LD7, GPIO_PIN_SET) //GREEN2
#define LD8_ON HAL_GPIO_WritePin(LD_PORT, LD8, GPIO_PIN_SET) //ORANGE2
#define LD9_ON HAL_GPIO_WritePin(LD_PORT, LD9, GPIO_PIN_SET) //BLUE2
#define LD10_ON HAL_GPIO_WritePin(LD_PORT, LD10, GPIO_PIN_SET) //RED2
#define LD3_OFF HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_RESET) //RED1
#define LD4_OFF HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_RESET) //BLUE1
#define LD5_OFF HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_RESET) //ORANGE1
#define LD6_OFF HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_RESET) //GREEN1
#define LD7_OFF HAL_GPIO_WritePin(LD_PORT, LD7, GPIO_PIN_RESET) //GREEN2
#define LD8_OFF HAL_GPIO_WritePin(LD_PORT, LD8, GPIO_PIN_RESET) //ORANGE2
#define LD9_OFF HAL_GPIO_WritePin(LD_PORT, LD9, GPIO_PIN_RESET) //BLUE2
#define LD10_OFF HAL_GPIO_WritePin(LD_PORT, LD10, GPIO_PIN_RESET) //RED2
#endif /* MAIN_H_ */
Подключим данный файл в main.c
/* USER CODE BEGIN Includes */
#include «main.h»
/* USER CODE END Includes */
Также создадим два файла в Src и Inc с соответственными именами lsm303dlhc.c и lsm303dlhc.h по наименованию нашего датчика.
Подключим файл lsm303dlhc.h в файле main.h
#include «stm32f3xx_hal.h»
#include «lsm303dlhc.h»
Также подключим его и в lsm303dlhc.c.
Содержание данного файла:
#ifndef LSM303DLHC_H_
#define LSM303DLHC_H_
#include «stm32f3xx_hal.h»
#include <string.h>
//————————————————
#define ABS(x) (x < 0) ? (-x) : x
//————————————————
#define LD_PORT GPIOE
#define LD3 GPIO_PIN_9 //RED1
#define LD4 GPIO_PIN_8 //BLUE1
#define LD5 GPIO_PIN_10 //ORANGE1
#define LD6 GPIO_PIN_15 //GREEN1
#define LD7 GPIO_PIN_11 //GREEN2
#define LD8 GPIO_PIN_14 //ORANGE2
#define LD9 GPIO_PIN_12 //BLUE2
#define LD10 GPIO_PIN_13 //RED2
#define LD3_ON HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_SET) //RED1
#define LD4_ON HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_SET) //BLUE1
#define LD5_ON HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_SET) //ORANGE1
#define LD6_ON HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_SET) //GREEN1
#define LD7_ON HAL_GPIO_WritePin(LD_PORT, LD7, GPIO_PIN_SET) //GREEN2
#define LD8_ON HAL_GPIO_WritePin(LD_PORT, LD8, GPIO_PIN_SET) //ORANGE2
#define LD9_ON HAL_GPIO_WritePin(LD_PORT, LD9, GPIO_PIN_SET) //BLUE2
#define LD10_ON HAL_GPIO_WritePin(LD_PORT, LD10, GPIO_PIN_SET) //RED2
#define LD3_OFF HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_RESET) //RED1
#define LD4_OFF HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_RESET) //BLUE1
#define LD5_OFF HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_RESET) //ORANGE1
#define LD6_OFF HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_RESET) //GREEN1
#define LD7_OFF HAL_GPIO_WritePin(LD_PORT, LD7, GPIO_PIN_RESET) //GREEN2
#define LD8_OFF HAL_GPIO_WritePin(LD_PORT, LD8, GPIO_PIN_RESET) //ORANGE2
#define LD9_OFF HAL_GPIO_WritePin(LD_PORT, LD9, GPIO_PIN_RESET) //BLUE2
#define LD10_OFF HAL_GPIO_WritePin(LD_PORT, LD10, GPIO_PIN_RESET) //RED2
//————————————————
#endif /* LSM303DLHC_H_ */
Для подключения любого внешнего устройства, как мы уже знаем, требуется первоначальная инициализация.
Поэтому создадим функцию в файле lsm303dlhc.c
#include «lsm303dlhc.h»
//—————————————
void Accel_Ini(void)
{
}
Создадим для нее прототип в заголовочном файле lsm303dlhc.h
//————————————————
void Accel_Ini(void);
//————————————————
#endif /* LSM303DLHC_H_ */
и вызовем в главной функции main()
/* USER CODE BEGIN 2 */
Accel_Ini();
/* USER CODE END 2 */
Также ещё мы знаем, что в инициализации немаловажную роль играет считывание идентификатора устройства, причем не сколько для того, чтобы узнать, то ли мы устройство присоединили, сколько для того, чтобы удостовериться, что мы с данным устройством успешно общаемся по шине и не думать, что какие-то глюки у нас происходят по причине неправильного соединения. Напишем еще одну функцию в lsm303dlhc.c
#include «lsm303dlhc.h»
//—————————————
uint8_t Accel_ReadID(void)
{
uint8_t ctrl = 0x00;
return ctrl;
}
В следующей части нашего занятия мы продолжим писать инициализацию данного датчика. Напишем удобные функции чтения и записи регистров акселерометра, используя шину I2C, а также считаем из датчика его идентификатор.
Предыдущий урок Программирование МК STM32 Следующая часть
Техническая документация на датчик
Купить отладочную плату можно здесь STM32F3-DISCOVERY
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий