Урок 51.
Часть 2
Магнитометр LIS3MDL
В прошлой части нашего урока мы добавили все макросы, которые вносят удобства в чтение и написание кода, начали писать функцию инициализации и проверили код на практике.
Продолжим инициализацию датчика.
Переименуем функцию GyroInit в MagInit, а функцию AccelInit удалим со всем содержимым, чтобы не мешалась
//———————————————
void MagInit(uint16_t InitStruct)
{
Также исправим и раскомментируем вызов данной функции в главной функции инициализации датчика, а вызов функции инициализации акселерометра также и здесь удалим
LD2_OFF;
MagInit(ctrl);
LD2_ON;
Продолжаем писать инициализацию, постепенно раскомментировывая и подправляя код в функции
uint8_t value = 0;
//пока выключим датчик (MD = 0x02)
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG3);
value&=~LIS3MDL_MAG_MD_MASK;
value|=LIS3MDL_MAG_MD_POWER_DOWN;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG3,value);
/*
Здесь мы используем регистр CTRL_REG3 (22h) и устанавливаем определённым образом его биты MD1 и MD0 с целью пока выключить датчик
Пишем дальше код
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG3,value);
//Enable BDU
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG5);
value&=~LIS3MDL_MAG_BDU_MASK;
value|=LIS3MDL_MAG_BDU_ENABLE;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG5,value);
Здесь мы работаем уже с другим управляющим регистром – с CTRL_REG5 (24h) и включим в нём бит BDU, смысл которого мы уже изучили в предыдущих занятиях
Дальше устанавливаем частоту считывания показаний с осей
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG5,value);
//Включим Data Rate 80 Гц
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1);
value&=~LIS3MDL_MAG_DO_MASK;
value|=LIS3MDL_MAG_DO_80Hz;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1,value);
Здесь мы используем регистр CTRL_REG1 (20h) и устанавливаем там биты, отвечающие за частоту считывания показаний
Пишем код инициализации дальше
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1,value);
//Full scale selection 4 gauss
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG2);
value&=~LIS3MDL_MAG_FS_MASK;
value|=LIS3MDL_MAG_FS_4Ga;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG2,value);
Здесь мы программируем следующий регистр – CTRL_REG2 (21h), включая в нём биты, отвечающие за диапазон показаний магнитометра
Пишем дальше
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG2,value);
//Включим режим высокой производительности по осям X и Y
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1);
value&=~LIS3MDL_MAG_OM_MASK;
value|=LIS3MDL_MAG_OM_HIGH;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1,value);
Здесь мы работаем также с регистром первым, который мы уже изучили, только работаем с другими битами, отвечающими за производительность датчика по осям X и Y
Отключим температурный датчик
//Отключим температурный датчик
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1);
value&=~LIS3MDL_MAG_TEMP_EN_DISABLE;
value|=LIS3MDL_MAG_OM_HIGH;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1,value);
Здесь мы также работаем с другим битом того же регистра
Осталось только включить датчик. Для этого в инициализацию добавим следующий код
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG1,value);
//включим датчик (MD = 0x00)
value = Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG3);
value&=~LIS3MDL_MAG_MD_MASK;
value|=LIS3MDL_MAG_MD_CONTINUOUS;
Mag_IO_Write(MAG_I2C_ADDRESS,LIS3MDL_MAG_CTRL_REG3,value);
Здесь мы просто отключили оба бита MD, тем самым включили режим автоматического преобразования
Инициализация на этом, в принципе, завершена.
Соберём код, прошьём контроллер и проверим, не погаснет ли у нас светодиод.
Если всё нормально, то начнём писать код считывания показаний с осей магнитометра.
Функцию Gyro_GetXYZ переименуем в Mag_GetXYZ, а функцию Accel_GetXYZ удалим со всем содержимым
//———————————————
void Mag_GetXYZ(int16_t* pData)
{
Для считывания показаний с осей магнитометра используем регистры с адресами 0x28 – 0x2D
Раскомментируем код и внесём изменения в функцию считывания показаний
//———————————————
void Mag_GetXYZ(int16_t* pData)
{
uint8_t buffer[6];
uint8_t i=0;
buffer[0]=Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_OUTX_L);
buffer[1]=Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_OUTX_H);
buffer[2]=Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_OUTY_L);
buffer[3]=Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_OUTY_H);
buffer[4]=Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_OUTZ_L);
buffer[5]=Mag_IO_Read(MAG_I2C_ADDRESS,LIS3MDL_MAG_OUTZ_H);
for(i=0;i<3;i++)
{
pData[i] = ((int16_t)((uint16_t)buffer[2*i+1]<<8)+buffer[2*i]);
}
}
//———————————————
Функцию AccelGyro_Read также переименуем в Mag_Read
//———————————————
void Mag_Read(void)
{
Команду на считывание данных мы будем уже давать не в бесконечном цикле, а в обработчике прерывания от таймера, причем не просто так, а при определённых условиях.
Во-первых, нам надо сначала этот таймер запустить в функции main(). Также запустим там и считывание данных с USART
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2, (uint8_t*) str, 8);
HAL_TIM_Base_Start_IT(&htim1);
Mag_Ini();
/* USER CODE END 2 */
Теперь создадим обработчик прерывания по флагу окончания счёта таймера и вызовем там команду чтения и обработки данных осей магнитометра в зависимости от сложившихся условий. Условия таковы: должно быть прерывание именно от первого таймера и буфер чтения USART должен быть заполнен. После вызова функции чтения осей опять вызываем функцию чтения по прерывания из порта USART
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1) //если будет несколько таймеров, чтобы попасть именно в нужный
{
if(huart2.RxXferCount==0)
{
Mag_Read();
HAL_UART_Receive_IT(&huart2, (uint8_t*) str, 8);
}
}
}
/* USER CODE END 4 */
В следующей части занятия мы закончим писать функции чтения и обработки показаний датчика с его трёх осей и посмотрим их с помощью нескольких программ на ПК.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация на датчик
Отладочную плату можно приобрести здесь Nucleo STM32F401RE
Оценочную плату можно приобрести здесь STM32 X-NUCLEO-IKS01A1
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий