VL53L0 и STM32F103C8T6

от автора

О том, как подключить VL53L0 к STM32F103C8T6 и сделать так, чтобы всё работало.

Изначально я хотел использовать времяпролетный датчик VL53L5, но нашел VL53L0, который заметно дешевле и попроще. Затем начал искать для него библиотеку и нашел её на официальном сайте STMicroelectronics, однако запустить VL53L0 с ней не вышло. В итоге, отыскал рабочую библиотеку на GitHub с использованием STM32F401 и переделал её для работы с STM32F103.

Прежде всего, запускаем CubeIDE и настраиваем проект

  1. Во вкладке RCC выбираю Crystal/Ceramic Resonator

  2. Во вкладке SYS выбираю Serial Wire

  3. Во вкладке Connectivity включаю I2C1 и USART2

    Включение I2C1

    Включение I2C1
    Включение USART2

    Включение USART2
  4. Выход PB9 устанавливаю, как GPIO_EXTI9

  5. Затем перехожу во вкладку NVIC и ставлю галочку на EXTI line interrupts

  6. Во вкладе GPIO ставлю следующие настройки

  7. Выставляю максимальную частоту 72 Гц

  8. И создаю проект

Затем необходимо добавить саму библиотеку для VL53L0. Для этого:

  1. Нужно скачать библиотеку с GitHub — https://github.com/lamik/VL53L0X_API_INT_STM32_HAL

  2. Заходим в архив VL53L0X_API_INT_STM32_HAL, каталог Drivers и копируем папку VL53L0X.

  3. Затем находим папку с проектом и переходим в каталог Drivers и помещаем в него скопированную папку VL53L0X.

  4. В папке VL53L0X переходим в каталог platform, потом в папку src, открываем файл vl53l0x_platform.c, например, в блокноте или любом другом редакторе текста и меняем строку #include «stm32f4xx_hal.h» на #include «stm32f1xx_hal.h». После этого, возвращаемся в каталог platform и в папке inc открываем файл vl53l0x_platform.h и также меняем строку #include «stm32f4xx_hal.h» на #include «stm32f1xx_hal.h».

    Изменение файла vl53l0x_platform.c

    Изменение файла vl53l0x_platform.c
    Изменение файла vl53l0x_platform.h

    Изменение файла vl53l0x_platform.h
  5. Теперь переключаемся в CubeIDE. В боковой панеле справа один раз нажимаем на наш проект и жмем сочетание клавиш Alt + Enter или нажимаем на File в верхнем левом углу и жмем Properties

  6. Раскрываем список, нажимая на галочку возле C/C++ General, и из выпадающего списка выбираем пункт Paths and Symbols

  7. Нажимаем на кнопку Add справа и добавляем путь до папки Inc, находящейся в каталоге Drivers, в папке VL53L0, в каталоге Core

    Жмем на File system

    Жмем на File system
    Нажимаем ОК

    Нажимаем ОК

    То же самое проделываем для папки Inc, только находящейся в каталоге platform

    Добавление папки Inc из каталога platform

    Добавление папки Inc из каталога platform
    Результат

    Результат

    Жмём Apply.

  8. Теперь нажмем на галочку возле C/C++ Build и в выпадающем списке нажмем на Settings. Затем перейдем в MCU/MPU Settings и поставим галочку возле Use float with printf from newlib-nano. Также нам нужен hex-файл, для этого перейдем в MCU/MPU Post build outputs и поставим галочку возле Convert to Intel Hex file

    Жмем Apply и Apply and Close

Наконец, переходим к коду.

Подключаем библиотеку для работы с VL53L0

/* USER CODE BEGIN Includes */ #include "vl53l0x_api.h" #include "stdio.h" /* USER CODE END Includes */

Инициализируем переменные для вывода измерений и работы датчика

/* USER CODE BEGIN PV */ uint8_t Message[64]; uint8_t MessageLen;  VL53L0X_RangingMeasurementData_t RangingData; VL53L0X_Dev_t  vl53l0x_c; // center module VL53L0X_DEV    Dev = &vl53l0x_c;  volatile uint8_t TofDataRead; /* USER CODE END PV */

Добавил собственные функции для вывода данных через UART

/* USER CODE BEGIN 0 */ void String_write(char sx[]) {     HAL_UART_Transmit(&huart2, (uint8_t *)sx, strlen(sx), 100); }  void String_writeln(char sx[]) {     String_write(sx);     char cr[] = "\r\n";     HAL_UART_Transmit(&huart2, (uint8_t *)cr, strlen(cr), 100); }  void Int_write(int32_t x) {     char buf[BUFSIZ];     sprintf(buf, "%ld", x);     String_write(buf); }  void Int_writeln(int32_t x) {     Int_write(x);     char cr[] = "\r\n";     HAL_UART_Transmit(&huart2, (uint8_t *)cr, strlen(cr), 100); }  void Float_write(float x) {     char buf[BUFSIZ];     sprintf(buf, "%f", x);     String_write(buf); }  void Float_writeln(float x) {     Float_write(x);     char cr[] = "\r\n";     HAL_UART_Transmit(&huart2, (uint8_t *)cr, strlen(cr), 100); } /* USER CODE END 0 */

Инициализация переменных

/* USER CODE BEGIN 1 */ uint32_t refSpadCount; uint8_t isApertureSpads; uint8_t VhvSettings; uint8_t PhaseCal;   /* USER CODE END 1 */

Вывод сообщения через UART и объявление функций для начала измерений

/* USER CODE BEGIN 2 */   MessageLen = sprintf((char*)Message, "msalamon.pl VL53L0X Continuous mode\n\r");   HAL_UART_Transmit(&huart2, Message, MessageLen, 100);    Dev->I2cHandle = &hi2c1;   Dev->I2cDevAddr = 0x52;    HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);    VL53L0X_WaitDeviceBooted( Dev );   VL53L0X_DataInit( Dev );   VL53L0X_StaticInit( Dev );   VL53L0X_PerformRefCalibration(Dev, &VhvSettings, &PhaseCal);   VL53L0X_PerformRefSpadManagement(Dev, &refSpadCount, &isApertureSpads);   VL53L0X_SetDeviceMode(Dev, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING);   VL53L0X_StartMeasurement(Dev);    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);   /* USER CODE END 2 */

Вывод измерений через UART в мм на одной строке

/* USER CODE BEGIN WHILE */   while (1)   {   if(TofDataRead == 1)       {     /*MessageLen = sprintf((char*)Message, "Measured distance: %i\n\r", RangingData.RangeMilliMeter);     HAL_UART_Transmit(&huart2, Message, MessageLen, 100);*/     String_write("Measured distance: ");     Int_write(RangingData.RangeMilliMeter);     String_write(" mm   \r");       TofDataRead = 0;       HAL_Delay(50);       }     /* USER CODE END WHILE */

Вывод измерений в реальном времени при помощи прерываний

/* USER CODE BEGIN 4 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_9) { VL53L0X_GetRangingMeasurementData(Dev, &RangingData); VL53L0X_ClearInterruptMask(Dev, VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); TofDataRead = 1; } } /* USER CODE END 4 */

Нажимаем на молоток на верхней панели. В консоли должна быть похожая картина

Схема подключения

Теперь надо загрузить программу в микроконтроллер, для этого буду использовать CubeProgrammer. Подключаем STM32F103C8T6 при помощи st-link к компьютеру

Подключение к STM32

Подключение к STM32

Укажем путь до hex-файла, который находится в папке Debug. Перед этим переведем джампер на плате в положение boot 1 и нажмем на кнопку.

Нажимаем на кнопку Start Programming

Для того, чтобы увидеть результат измерений понадобится программа Putty. Подключаем UART к ПК и заходим в диспетчер устройств и смотрим, под каким com-портом он определился, в моем случае COM7

Жму на него два раза и выставляю, чтобы значение Bits per second было 115200.

Затем, захожу в Putty. Выбираю Connection type: serial, указываю com-порт и скорость. Нажимаю open.

Получаю расстояние в миллиметрах, которое изменяется в реальном времени

Вот таким образом можно подключить VL53L0 к STM32F103 и получать расстояние до объектов, которое изменяется в реальном времени.


ссылка на оригинал статьи https://habr.com/ru/articles/925242/