PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Программирование микроконтроллеров » STM32 - Чтение температуры со встроенного датчика


STM32 - Чтение температуры со встроенного датчика

Сообщений 1 страница 2 из 2

1

В STM32F103C8T6 есть встроенный датчик температуры, (по видимому состоящий из двух диодов, включенных последовательно), который подключен к одному из каналов АЦП. Что-то похожее есть в некоторых моделях МК AVR.
Датчик не калиброванный и с одной и той же прошивкой, может показывать разную температуру в различных экземплярах МК. Поэтому для точных измерений (без калибровки) он не подходит, но как пример работы с АЦП подойдет.
В даташите написано про датчик не очень много. Это вся информация (поместилась на половине страницы даташита).

http://s7.uploads.ru/zrK8o.png

Для расчета температуры служит формула.

Temperature = (V_25-V_sense)/Avg_Slope + 25

Где V_25 и Avg_Slope это данные из даташита, а V_sense - измеренное напряжение на датчике температуры. Все напряжения должны быть в вольтах. Температура будет рассчитана в градусах по Цельсию.
После расчета данные будут выводится с МК через USB и отобраюатся в компьютерной программе. Почему так? Мне так проще, а заодно узнаем как работать с USB.

Создаем проекты EmBitz и STM32CubeMX как писал ранее.
Теперь в STM32CubeMX настроим периферию МК. Нужно выбрать тактовый генератор, настроить тактиование отдельных модулей МК, а так же сконфигурировать АЦП и USB.
На вкладке "Pinout" начнем по порядку сверху вниз конфигурировать модули. Открываем раздел ADC1 и выбираем канал датчика температуры.

http://s6.uploads.ru/t/z4Zf5.png

Далее в разделе RCC нужно включить внешний высокочастотный резонатор.

http://s5.uploads.ru/ZnSzJ.png

Дальше в разделе USB нужно включить этот модуль.

http://s8.uploads.ru/xVJ5X.png

Теперь нужно в разделе "USB Device" выбрать тип USB устройства. Нам нужен HID.

http://sg.uploads.ru/eRv70.png

Скриншот всех изменений, который были сделаны.

http://s2.uploads.ru/t/3ezki.png

Теперь переходим на вкладку "Clock configuration".
Задача проста. Настроить тактирование таким образом чтобы ядро и модули МК тактировались от внешнего резонатора. На модуль USB поступала частота 48 МГц, а так же на других модулях частота на была больше или меньше допустимой (подсвечивается красным).
Должно получится примерно так.

http://s9.uploads.ru/t/gMnHu.png

Теперь переходим на вкладку "Сonfiguration", где можно настроить выбранные модули.

http://s3.uploads.ru/t/3HwjC.png

Сначала настроим АЦП. Кликаем по кнопке "ADC1".
Откроется окно. Настраиваем все также.

http://s3.uploads.ru/t/OMrv6.png

Теперь кликаем по кнопке "USB_Device". Откроется окно.

http://s8.uploads.ru/t/2wxZ8.png

То что находится в разделе "Basic parameters" изменять не нужно - подойдут параметры по умолчанию.
Параметр USBD_CUSTOM_HID_REPORT_DESC_SIZE это размер дескриптора HID_Report (о нем поговорим позже). Его размер в данной программе 33 байта.
Параметр USBD_CUSTOMHID_OUTREPORT_BUF_SIZE определяет размер буфера приема данных из компьютера.

Переходим на вкладку "Device descriptor". Настраиваем как на скриншоте.

http://sh.uploads.ru/t/9txuG.png

Сохраняем настройки нажав на кнопку OK.

Теперь генерируем код и экспортируем его в EmBitz.

В EmBitz открываем файл "usbd_custom_hid_if.c", находящийся в папке Sources\Src проекта.

http://s7.uploads.ru/t/mWSGZ.png

В нем находим массив CUSTOM_HID_ReportDesc_FS и вставляем в него код HID дескриптора. Должно получится.

Код:
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
    0x06 , 0x00 , 0xFF,             // Usage_page(vendor Defined Page 1)
    0x09 , 0x01,                    // Usage(vendor Usage 1)
    0xA1 , 0x02,                    // Collection(logical)
// Описание конечной точки, типа Input
    0x09 , 0x01,                    // Usage(pointer)
    0x15 , 0x00,                    // Logical_minimum(0)
    0x25 , 0xFF,                    // Logical_maximum(255)
    0x75 , 0x08,                    // Report_size(8)
    0x95 , 0x02,                    // Report_count(2)
    0x81 , 0x02,                    // Input( , Var , Abs)
// Описание конечной точки, типа Output
    0x09 , 0x01,                    // Usage(pointer)
    0x15 , 0x00,                    // Logical_minimum(0)
    0x26 , 0xFF , 0,                // Logical_maximum(255)
    0x75 , 0x08,                    // Report_size(8)
    0x95 , 0x02,                    // Report_count(2)
    0x91 , 0x02,                    // Output(data , Var , Abs)
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION	             */

};

Сохраняем файл.
Теперь открываем файл main.c , находящийся в папке Sources\Src проекта.
В него нужно добавить идентификатор USB

Код:
USBD_HandleTypeDef  *hUsbDevice_0;

а также константы из даташита, для датчика температуры.

Код:
#define tV_25   1.34f      // Напряжение (в вольтах) на датчике при температуре 25 °C.
#define tSlope  0.0043f    // Изменение напряжения (в вольтах) при изменении температуры на градус.
#define Vref    3.3f       // Образцовое напряжение АЦП (в вольтах).

Теперь в функции main нужно до цикла while добавить объявление переменных.

Код:
    int16_t Result=0;
    float temp;

а в цикле while, код чтения данных с АЦП, преобразования его в температуру и передачи в компьютер.

Код:
    HAL_Delay(1000);       // Задержка 1000 мс.
    HAL_ADC_Start(&hadc1); // Запуск АЦП.
    if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) // Ожидание завершения преобразования.
    {
        Result = HAL_ADC_GetValue(&hadc1); // Считывание с АЦП.

        temp = (float) Result/4096*Vref;   // Напряжение в вольтах на датчике.
        temp = (tV_25-temp)/tSlope + 25;   // Температура в градусах.
        temp = temp * 16;                  // Приводим данные к формату DS18B20.
        Result = (int16_t) temp;

        USBD_CUSTOM_HID_SendReport(hUsbDevice_0, &Result, 2); // Передача данных компьютеру.
    }
    HAL_ADC_Stop(&hadc1); // Остановка АЦП.

Программа написана. Как видим, большинство кода было сгенерировано программной STM32CubeMX. Нам же понадобилось добавить HID_Report, пару переменных и констант, а также несколько строк кода, считывающих температуру с АЦП и передающих ее в компьютер.
Программа написана так, что работает с компьютерной программой из другого проекта.

Скриншот программы.

http://s0.uploads.ru/sjwfv.png

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

Файлы (программа для компьютера с исходником в папке PC). http://pure-basic.narod.ru/forum_files/ … rmoADC.zip
Разработка программы МК велась в EmBitz 0.42 и STM32CubeMX 4.14.0.

0

2

Добрый день, Петр. Очень полезная статья, благодарю. Есть небольшая неточность: temp = (temp-tV_25)/tSlope + 25;   // Температура в градусах.

0


Вы здесь » PureBasic - форум » Программирование микроконтроллеров » STM32 - Чтение температуры со встроенного датчика