Урок 41
Часть 1
Подключаем акселерометр LIS3DSH
Тема нашего сегодняшнего занятия – подключение более нового акселерометра по сравнению с тем, который мы использовали для изучения в уроке 39. Данный акселерометр – это также акселерометр, выполненный с использованием технологии MEMS – LIS3DSH.
Во-первых, данный акселерометр наряду с интерфейсом I2C может подключиться и с использованием интерфейса SPI, что делает более надёжной передачу данных и их использование. Во-вторых, данный акселерометр установлен на плате STM32F4 Discovery, с которой мы уже очень продолжительное время работаем, и она уже стала как родная. И это я считаю немаловажной мотивацией. Ну а в-третьих, имеет более совершенные технические характеристики:
Диапазон показаний ±2g/±4g/±6g/±8g/±16g;
Чувствительность 0.06-0.73 mg/digit;
Отклонение от нуля ±60 mg.
Ну а с остальными характеристиками, тонкостями, регистрами и другими подводными камнями акселерометра мы познакомимся в ходе его программирования.
Проект для Cube MX мы создадим из одного из прошлых проектов USB_OTG_CDC, так как вместо USART для передачи показаний акселерометра на ПК мы попробуем воспользоваться USB CDC Device, так как с ним работать более удобно ввиду необязательности использования каких-то промежуточных переходников. Назовем проект ACCEL407.
Запустим проект в Cube MX, отключим I2C, включим SPI1 в режим Full-Duplex Master
Ножки SPI оставим по умолчанию и никуда не перенаправляем
Включим еще 3 ножки. Одну для выбора чипа (CS), другие две для обнаружения прерываний. Возможно последние нам не понадобятся, но для порядка включим, чтобы по ошибки их не задействовать впоследствии на что-то еще.
Также включим на выход лапки портов для управления разноцветными светодиодами на плате
В настройках SPI изменим только скорость передачи
Также изменим настройки в GPIO у лапки порта PE3, выставив ему скорость Medium.
Зайдем в Project -> Settings и изменим там значения стека и кучи, чтобы USB-устройство после установки драйвера нам не давало ошибку (Код 10).
Сгенерируем проект и откроем его в Keil 5. Также по традиции настроим программатор на авторезет. Соберем проект.
Уберем всё, что касается символьного дисплея, так как он нам, скорее всего не потребуется. Уберем подключение библиотеки из main.h:
#include «stm32f4xx_hal.h»
#include «lcd.h»
Здесь оставим только передачу в USB, чтобы проверить, работает ли она.
/* USER CODE BEGIN 2 */
sprintf(str_tx,»USB Transmitrn»);
/* USER CODE END 2 */
В бесконечном цикле также оставим только то, что касается передачи в USB
while (1)
{
CDC_Transmit_FS((uint8_t*)str_tx, strlen(str_tx));
HAL_Delay(500);
/* USER CODE END WHILE */
Прошьем контроллер, чтобы убедиться в работоспособности порта USB и удалим теперь всю передачу, массив строки и подготовку строки:
/* Private variables ———————————————————*/
char str_rx[21];
/* USER CODE END PV */
—
/* USER CODE BEGIN 2 */
sprintf(str_tx,»USB Transmitrn»);
/* USER CODE END 2 */
—
while (1)
{
CDC_Transmit_FS((uint8_t*)str_tx, strlen(str_tx));
HAL_Delay(500);
/* USER CODE END WHILE */
—
char str_tx[21];
/* USER CODE END 1 */
Также из файла usbd_cdc_if.c удалим следующие строки, а одну строку раскомментируем обратно:
/* USER CODE BEGIN PRIVATE_VARIABLES */
extern char str_rx[21];
/* USER CODE END PRIVATE_VARIABLES */
—
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
strncpy(str_rx,(char*)Buf,*Len);
str_rx[*Len]=0;
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
Пересоберём на всякий случай проект, чтобы убедиться, что ошибок у нас нет.
Два файла для работы с акселерометром можно использовать с прошлого занятия, переименовав их подобающим образом, подключив к проекту и внеся некоторые изменения.
Названия, соответственно, изменятся на lis3dsh.h и lis3dsh.c. Заодно удалим из Inc и Src файлы lcd.h и lcd.c. Подключим данные файлы, добавив lis3dsh.c в проекте в группу Application/User, а lis3dsh.h подключив в main.h. Также внесем макроподстановки, наподобие тех, которые мы вносили в проекте под 3 discovery для удобного управления светодиодами.
#include «stm32f4xx_hal.h»
#include «lis3dsh.h»
//————————————————
#define LD_PORT GPIOD
#define LD3 GPIO_PIN_13 //ORANGE
#define LD4 GPIO_PIN_12 //GREEN
#define LD5 GPIO_PIN_14 //RED
#define LD6 GPIO_PIN_15 //BLUE
#define LD3_ON HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_SET) //ORANGE
#define LD4_ON HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_SET) //GREEN
#define LD5_ON HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_SET) //RED
#define LD6_ON HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_SET) //BLUE
#define LD3_OFF HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_RESET) //ORANGE
#define LD4_OFF HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_RESET) //GREEN
#define LD5_OFF HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_RESET) //RED
#define LD6_OFF HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_RESET) //BLUE
//————————————————
Состав данных файлов после внесения изменений.
Содержимое файла lis3dsh.h:
#ifndef LIS3DSH_H_
#define LIS3DSH_H_
#include «stm32f4xx_hal.h»
#include <string.h>
//————————————————
#define ABS(x) (x < 0) ? (-x) : x
//————————————————
#define LD_PORT GPIOD
#define LD3 GPIO_PIN_13 //ORANGE
#define LD4 GPIO_PIN_12 //GREEN
#define LD5 GPIO_PIN_14 //RED
#define LD6 GPIO_PIN_15 //BLUE
#define LD3_ON HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_SET) //ORANGE
#define LD4_ON HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_SET) //GREEN
#define LD5_ON HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_SET) //RED
#define LD6_ON HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_SET) //BLUE
#define LD3_OFF HAL_GPIO_WritePin(LD_PORT, LD3, GPIO_PIN_RESET) //ORANGE
#define LD4_OFF HAL_GPIO_WritePin(LD_PORT, LD4, GPIO_PIN_RESET) //GREEN
#define LD5_OFF HAL_GPIO_WritePin(LD_PORT, LD5, GPIO_PIN_RESET) //RED
#define LD6_OFF HAL_GPIO_WritePin(LD_PORT, LD6, GPIO_PIN_RESET) //BLUE
//————————————————
void Accel_Ini(void);
void Accel_ReadAcc(void);
//————————————————
#endif /* LIS3DSH_H_ */
Содержимое файла lis3dsh.c:
#include «lis3dsh.h»
//————————————
static void Error (void)
{
}
//—————————————
uint8_t Accel_IO_Read(uint16_t DeviceAddr, uint8_t RegisterAddr)
{
return 0;
}
//—————————————
void Accel_IO_Write(uint16_t DeviceAddr, uint8_t RegisterAddr, uint8_t Value)
{
}
//—————————————
uint8_t Accel_ReadID(void)
{
uint8_t ctrl = 0x00;
return ctrl;
}
//—————————————
void Accel_AccFilterConfig(uint8_t FilterStruct)
{
}
//—————————————
void AccInit(uint16_t InitStruct)
{
}
//—————————————
void Accel_GetXYZ(int16_t* pData)
{
}
//—————————————
void Accel_ReadAcc(void)
{
}
//—————————————
void Accel_Ini(void)
{
}
//—————————————
Вызовем инициализацию датчика в main();
/* USER CODE BEGIN 2 */
Accel_Ini();
/* USER CODE END 2 */
В функции-обработчике ошибки включим красный светодиод
static void Error (void)
{
LD5_ON;
}
Добавим хэндл нашего SPI:
#include «lis3dsh.h»
//————————————
extern SPI_HandleTypeDef hspi1;
В следующей части занятия мы мы попытаемся считать идентификатор данных, тем самым убедимся в правильных настройках шины и то, что мы работаем именно с этим датчиком.
Также напишем функцию записи данных в регистры акселерометра.
Предыдущий урок Программирование МК STM32 Следующая часть
Техническая документация на датчик
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Смотреть ВИДЕОУРОК
Добавить комментарий