Порівняння між Датчик температури PT100 зонд і Модуль DS18B20
1) Основний принцип отримання сигналу
① Опір PT100 змінюється пропорційно температурі (чим вище температура, тим більший опір), але зміна опору дуже мала, приблизно 0.385 ох / ступінь;
② Діапазон вимірювання температури PT100 становить -200 ℃ -200 ℃, і при 0 ℃, опір точно дорівнює 100 ох;
③ Робочий струм PT100 має бути менше ніж 5 Ма;
④ Хоча опір PT100 змінюється пропорційно температурі, його швидкість зміни (тобто, K value K value K value) відрізняється в різних діапазонах температур.
2) Таблиця зміни температурного опору PT100
3. Схема приводу PT100
1) Через метод поділу напруги, AD збирає напругу PT100, щоб отримати значення опору для розрахунку температури
Значення стійкості PT100 у воді при кімнатній температурі (25℃25℃25℃) це приблизно 109.89 ох.
Мікроконтролер видає напругу 3,3 В, і напруга поділена на PT100 становить приблизно:
109.89 ∗ 0.005 = 0.54945 V
Значення AD, перетворене відповідно до формули перетворення AD, становить приблизно:
0.54945 / 3.3 ∗ 4096 = 681.98 ≈ 682
При підвищенні температури на один градус, припускаючи, що опір PT100 просто зростає 0.385 ох, зміна значення напруги, розділеної приблизно дорівнює:
0.385 ∗ 0.005 = 0.001925 V
Значення AD, перетворене відповідно до формули перетворення AD, становить приблизно:
0.001925 / 3.3 ∗ 4096 = 2.39 ≈ 2
В експерименті, було виявлено, що через нестабільну напругу 3,3 В блоку живлення stm32, АЦП збирав коливання напруги PT100, і помилка розподілу напруги була великою. Рішення для оптимізації полягає в розробці схеми джерела постійного струму. Збираючи напругу PT100 і струм джерела постійного струму, можна отримати опір PT100, і тоді можна отримати значення температури.
2) Схема джерела постійного струму на основі LDO регулятора (MD5333)
В Інтернеті є багато схем керування для тестування PT100, наприклад мостова схема постійного струму, схема джерела постійного струму на основі операційного підсилювача, тощо. Автор також витратив багато часу на вибір схеми руху, враховуючи складність виготовлення дошки та кількість компонентів, і, нарешті, вибрав схему джерела постійного струму на основі регулятора LDO (MD5333). Принципова схема виглядає наступним чином:
У цей момент, вибір обладнання в основному завершено. Використана плата розробки Zhengdian Atom F10ZET6 Elite Board
Модуль DS18B20
Для перевірки температури в реальному часі та порівняння температури PT100, додано модуль DS18B20 для порівняльного тесту калібрування
1) Знайомство з DS18B20
DS18B20 — це датчик температури з однією шиною з температурним діапазоном тестування -55~+125 ℃ і точністю ±0,5 ℃. Температура поля безпосередньо передається цифровим способом по одній шині, що значно покращує здатність системи проти перешкод. Він може безпосередньо зчитувати виміряну температуру, і може реалізувати 9~12-бітний метод читання цифрових значень шляхом простого програмування відповідно до фактичних вимог. Його робоча напруга становить 3~5,5 В, і він використовує різні форми упаковки, роблячи налаштування системи гнучкими та зручними. Встановлена роздільна здатність і температура сигналізації, встановлені користувачем, зберігаються в EEPROM і зберігаються після збою живлення.
2) Знайомство з робочим часом DS18B20
Усі пристрої з однією шиною вимагають суворої синхронізації сигналу для забезпечення цілісності даних. DS18B20 має 6 типи сигналів: скинути імпульс, відповідний імпульс, писати 0, писати 1, читати 0 і читати 1. Всі ці сигнали, крім відповідного імпульсу, є синхронними сигналами, які надсилає хост. І всі команди та дані надсилаються з молодшим бітом байта першим.
① Імпульс скидання та імпульс відповіді
Усі комунікації на одній шині починаються з послідовності ініціалізації. Хост видає низький рівень і підтримує низький рівень принаймні 480 мкс для генерації імпульсу скидання. Потім ведучий відпускає автобус, і підтягуючий резистор 4,7K тягне одну шину високо, з часом затримки 15~60 мкс, і переходить у режим прийому (Rx). Потім DS18B20 тягне низький рівень шини протягом 60 ~ 240 мкс для генерації імпульсу відповіді низького рівня.
② Напишіть час
Час запису включає запис 0 терміни і напишіть 1 терміни. Усі таймінги запису вимагають щонайменше 60 мкс, і принаймні 1 мкс потрібен час відновлення між двома незалежними таймінгами запису. Обидва моменти запису починаються з того, що хост зупиняє шину. Напишіть 1 терміни: хост видає низький рівень, затримки на 2 нас, а потім відпускає автобус, затримка 60us. Напишіть 0 терміни: хост видає низький рівень, затримки на 60us, а потім відпускає автобус із затримкою в 2 нас.
③ Зчитування часу
Пристрої з однією шиною передають дані на хост лише тоді, коли хост видає час читання. Отже, після того, як хост видає команду читання даних, час читання повинен бути згенерований негайно, щоб підлеглий пристрій міг передавати дані. Усі таймінги читання вимагають щонайменше 60 us, і принаймні 1 мкс потрібен час відновлення між двома незалежними часами читання. Кожен час читання ініціюється хостом, який тягне автобус принаймні на 1 нас. Хост повинен звільнити шину під час часу зчитування та перевірити стан шини протягом 15 мкс після початку відліку часу. Типовий процес читання часу: хост видає низький рівень затримки 2 мкс, потім хост перемикається в режим введення із затримкою 12 мкс, потім читає поточний рівень окремої шини, а потім затримує 50 нас.
Після розуміння синхронізації одного автобуса, давайте подивимося на типовий процес зчитування температури DS18B20. Типовий процес зчитування температури DS18B20 такий: скинути → відправити SKIPROM (0xCC) → надіслати команду запуску перетворення (0x44) → затримка → скинути → відправити команду SKIPROM (0xCC) → надіслати команду пам'яті (0xBE) → прочитати два байти даних (тобто. температура) постійно → кінець.
3) Принципова схема та конфігурація CUBEMAX
З принципової схеми, можна побачити, що DS18B20 увімкнено портом PG11 для відкриття послідовного порту для друку інформації про температуру
4) Кодова частина
Частина коду трансплантує бібліотеку ds18b20 Zhengdian Atom і вносить невеликі зміни
#ifndef __DS18B20_H
#визначити __DS18B20_H
#включити “тим.ч”
/***********************************************************************************/
/* Визначення контакту DS18B20 */
#визначте DS18B20_DQ_GPIO_PORT GPIOG
#визначити DS18B20_DQ_GPIO_PIN GPIO_PIN_11
#визначте DS18B20_DQ_GPIO_CLK_ENABLE() робити{ __HAL_RCC_GPIOG_CLK_ENABLE(); }поки(0) /* Увімкнути годинник порту PG */
/**********************************************************************************************/
/* Функція операції IO */
#визначити DS18B20_DQ_OUT(X) робити{ X ? \
HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_RESET); \
}поки(0) /* Вихід порту даних */
#визначте DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN) /* Введення порту даних */
uint8_t ds18b20_init(недійсний); /* Ініціалізувати DS18B20 */
uint8_t ds18b20_check(недійсний); /* Перевірте, чи існує DS18B20 */
короткий ds18b20_get_temperature(недійсний);/* Отримати температуру */
#endif
5. Інфрачервоний модуль дистанційного керування
1) Протокол кодування бездротового модуля
Широко використовуються методи кодування для інфрачервоного дистанційного керування: NEC протокол ШІМ (широтно-імпульсна модуляція) і протокол RC-5 Philips PPM (імпульсна позиційна модуляція). Пульт дистанційного керування, який постачається разом із платою розробки, використовує протокол NEC, який має такі особливості:
1. 8-бітова адреса та 8-бітна довжина інструкції;
2. Адреса і команда передаються двічі (для забезпечення надійності);
3. ШІМ імпульсна позиційна модуляція, з робочим циклом переданої інфрачервоної несучої, що представляє “0” і “1”;
4. Несуча частота 38 кГц;
5. Бітовий час становить 1,125 мс або 2,25 мс;
У протоколі NEC, як налаштувати дані в протоколі ‘0’ або «1»? тут, інфрачервоний приймач і інфрачервоний передавач розділені.
Інфрачервоний передавач: Надіслати дані протоколу «0» = 560 мкс передачі сигналу несучої + 560ми не передає сигнал несучої
Надіслати дані протоколу «1» = 560 мкс передачі сигналу несучої + 1680ми не передає сигнал несучої
Визначення бітів інфрачервоного передавача показано на малюнку нижче
Інфрачервоний приймач: Дані протоколу отримання «0» = низький рівень 560 мкс + 560нас високий рівень
Дані протоколу отримання «1» = низький рівень 560 мкс + 1680нас високий рівень
Формат даних команди дистанційного керування NEC такий: термінал синхронізації, код адреси, адресний інверсний код, контрольний код, контрольний інверсний код. Код синхронізації складається з низького рівня 9 мс і високого рівня 4,5 мс. Код адреси, адресний інверсний код, контрольний код, і контрольний інверсний код є 8-бітними форматами даних. Вони надсилаються в такому порядку: молодший біт першим і старший біт останнім. Інверсний код використовується для підвищення надійності передачі.
Отже, Захоплення вхідного сигналу можна використовувати для вимірювання ширини імпульсу високого рівня для досягнення декодування дистанційного керування.
2) Принципова схема та конфігурація CUBEMAX
З принципової схеми, ми бачимо, що бездротовий модуль увімкнено через контакт PB9 і збирає через 4 канали TIM4:
Стандартний контакт TIM4_CH4 не PB9, тому його потрібно налаштувати вручну, і налаштування переривання вмикається одночасно
3) Кодова частина
Зафіксуйте наростаючий фронт за допомогою функції зворотного виклику tim
В цей час, можна отримати декодований сигнал:
В цей час, дані є більш складними і можуть бути трохи оброблені:
Ефект наступний:
Останні дві цифри є розшифрованим і його зворотним кодом. В цей час, його можна визначити як макрос для налаштування порогу температури:
Ефект наступний:
Інфрачервоний код частини:
/* КОД КОРИСТУВАЧА ПОЧАТОК Заголовок */
/**
******************************************************************************
* @файл : main.c
* @коротко : Основне тіло програми
******************************************************************************
* @увага
*
* <h2><центр>&копія; Авторське право (в) 2024 STMicroelectronics.
* Всі права захищені.</центр></h2>
*
* Цей компонент програмного забезпечення ліцензовано ST згідно з ліцензією BSD 3-Clause,
* в “Ліцензія”; Ви не можете використовувати цей файл, окрім як відповідно до
* Ліцензія. Ви можете отримати копію Ліцензії за адресою:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Заголовок */
/* Включає в себе ——————————————————————*/
#включити “main.h”
#включити “тим.ч”
#включити “usart.h”
#включити “gpio.h”
/* Приватні включають ———————————————————-*/
/* КОД КОРИСТУВАЧА ПОЧАТОК Включає */
#включити “stdio.h”
#включити “рядок.h”
#визначити MAXUP 157
#визначте MAXDOWN 87
#визначити MINUP 221
#визначити MINDOWN 61
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА Включає */
/* Приватне визначення типу ———————————————————–*/
/* КОД КОРИСТУВАЧА ПОЧАТОК PTD */
/* КОД КОРИСТУВАЧА END PTD */
/* Приватне визначення ————————————————————*/
/* КОД КОРИСТУВАЧА ПОЧАТОК PD */
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА PD */
/* Приватний макрос ————————————————————-*/
/* КОД КОРИСТУВАЧА ПОЧАТОК PM */
/* КОД КОРИСТУВАЧА END PM */
/* Приватні змінні ———————————————————*/
/* КОД КОРИСТУВАЧА ПОЧАТОК PV */
uint32_t upCount=0;
uint16_t ValueUp=0;
uint16_t ValueDown=0;
uint8_t isUpCapt=1;
uint16_t ширина=0;
uint16_t буфер[128]={0};
uint16_t bufferId=0;
uint8_t rcvFalg=0;
/* КОД КОРИСТУВАЧА END PV */
/* Приватні прототипи функцій ———————————————–*/
void SystemClock_Config(недійсний);
/* КОД КОРИСТУВАЧА ПОЧАТОК PFP */
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА PFP */
/* Приватний код користувача ———————————————————*/
/* КОД КОРИСТУВАЧА ПОЧАТОК 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
upCount++;
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
якщо(isUpCapt)//Якщо це захоплення висхідного краю
{
ValueUp=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_4);
isUpCapt=0;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_4,TIM_ICPOLARITY_FALLING);
upCount=0;
}
інше{
ValueDown=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_4);
isUpCapt=1;
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_4,TIM_ICPOLARITY_RISING);
width=ValueDown+upCount*65536-ValueUp;
якщо(ширина>4400&&ширина<4600)
{
bufferId=0;
буфер[bufferId++]= ширина;
}
інакше, якщо(bufferId>0)
{
буфер[bufferId++]= ширина;
якщо(bufferId>32)
{
rcvFalg=1;
bufferId=0;
}
}
}
}
void bitBuffer2num(char num[])
{
кількість[0]=0;
кількість[1]=0;
кількість[2]=0;
кількість[3]=0;
для(int i=0;i<32;i++)
{
якщо(буфер[i+1]<1000)
{
кількість[i/8]= кількість[i/8]<<1;
}
інше
{
кількість[i/8]= кількість[i/8]<<1;
кількість[i/8]|=0x01;
}
}
}
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА 0 */
/**
* @brief Точка входу програми.
* @retval int
*/
int main(недійсний)
{
/* КОД КОРИСТУВАЧА ПОЧАТОК 1 */
char printbuff[128]={0};
char num[4]={0};
символьний ключ=0;
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА 1 */
/* Конфігурація MCU——————————————————–*/
/* Скидання всіх периферійних пристроїв, Ініціалізує інтерфейс Flash і Systick. */
HAL_Init();
/* КОД КОРИСТУВАЧА ПОЧАТОК Ініц */
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА Поч */
/* Налаштувати системний годинник */
SystemClock_Config();
/* КОД КОРИСТУВАЧА ПОЧАТОК SysInit */
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА SysInit */
/* Ініціалізуйте всі налаштовані периферійні пристрої */
MX_GPIO_Init();
MX_TIM4_Ініціал();
MX_USART1_UART_Init();
/* КОД КОРИСТУВАЧА ПОЧАТОК 2 */
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА 2 */
/* Нескінченний цикл */
/* КОД КОРИСТУВАЧА BEGIN WHILE */
HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
HAL_TIM_Base_Start_IT(&htim4);//Оновлення таймера генерує переривання
HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_4);//
поки (1)
{
якщо(rcvFalg)
{
для(int i=0;i<4;i++)
{
bitBuffer2num(кількість);
sprintf(printbuff,”0xx “,кількість[i]);
HAL_UART_Передача(&huart1,printbuff,стрен(printbuff),HAL_MAX_DELAY);
}
// sprintf(printbuff,”%u “,буфер[i]);
// HAL_UART_Передача(&huart1,printbuff,стрен(printbuff),HAL_MAX_DELAY);
// }
HAL_UART_Передача(&huart1,”\r\n”,2,HAL_MAX_DELAY);
rcvFalg=0;
}
printf(“%d\r\n”,кількість[3]);
якщо(кількість[3]==157)
{
printf(“111111\r\n”);
}
HAL_Delay(1000);
/* КОД КОРИСТУВАЧА END WHILE */
/* КОД КОРИСТУВАЧА ПОЧАТОК 3 */
}
/* КІНЕЦЬ КОДУ КОРИСТУВАЧА 3 */
}
/**
* @brief Конфігурація системного годинника
* @retval Жодного
*/
void SystemClock_Config(недійсний)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
English
Afrikaans
العربية
বাংলা
bosanski jezik
Български
Català
粤语
中文(简体)
中文(漢字)
Hrvatski
Čeština
Nederlands
Eesti keel
Suomi
Français
Deutsch
Ελληνικά
हिन्दी; हिंदी
Magyar
Bahasa Indonesia
Italiano
日本語
한국어
Latviešu valoda
Lietuvių kalba
македонски јазик
Bahasa Melayu
Norsk
پارسی
Polski
Português
Română
Русский
Cрпски језик
Slovenčina
Slovenščina
Español
Svenska
ภาษาไทย
Türkçe
Українська
اردو
Tiếng Việt









