Технология на температурен сензор

Сонда за температурен сензор (Дизайн на функционални схеми на DS18B20 и PT100)

Схема на DS18B20 и конфигурация CUBEMAX

Сравнение между Сензор за температура PT100 сонда и DS18B20 модул
1) Основен принцип на получаване на сигнал
① Съпротивлението на PT100 се променя пропорционално на температурата (толкова по-висока е температурата, толкова по-голямо е съпротивлението), но промяната на съпротивлението е много малка, около 0.385 о / степен;
② Диапазонът на измерване на температурата на PT100 е -200℃ -200℃, и при 0℃, съпротивлението е точно равно на 100 о;
③ Работният ток на PT100 трябва да бъде по-малък от 5 mA;
④ Въпреки че съпротивлението на PT100 се променя пропорционално на температурата, нейната скорост на промяна (това е, K стойност K стойност K стойност) е различен в различните температурни диапазони.

2) PT100 таблица за промяна на температурната устойчивост

PT100 таблица за промяна на температурната устойчивост

3. PT100 задвижваща верига

PT100 задвижваща верига

PT100 задвижваща верига

1) Чрез метода на разделяне на напрежението, AD събира напрежение PT100, за да получи стойност на съпротивление за изчисляване на температурата
Стойността на устойчивост на PT100 във вода при стайна температура (25℃25℃25℃) е около 109.89 о.
Микроконтролерът извежда 3.3V напрежение, и напрежението, разделено на 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.3V на захранването stm32, ADC събра PT100 колебания на напрежението и грешката при разделяне на напрежението беше голяма. Решението за оптимизация е да се проектира верига с източник на постоянен ток. Чрез събиране на напрежението на PT100 и тока на източника на постоянен ток, съпротивлението на PT100 може да се получи, и тогава може да се получи температурната стойност.

2) Верига на източник на постоянен ток, базирана на LDO регулатор (MD5333)
В Интернет има много схеми за задвижване за тестване на PT100, като DC мостова верига, източник на постоянен ток на базата на операционен усилвател, и т.н. Авторът също прекара много време в избора на задвижваща верига, като се има предвид трудността на изработката на платката и броя на компонентите, и накрая избра веригата източник на постоянен ток, базирана на LDO регулатор (MD5333). Схемата на веригата е както следва:

Източник на постоянен ток на LDO регулатор (MD5333)

Източник на постоянен ток на LDO регулатор (MD5333)

В този момент, изборът на хардуер е основно завършен. Използваната платка за разработка е Zhengdian Atom F10ZET6 Elite Board

DS18B20 модул
За да тествате температурата в реално време и сравнението на температурата на PT100, модулът DS18B20 е добавен за тест за сравнение на калибриране

1) Въведение в DS18B20
DS18B20 е температурен сензор с една шина с тестов температурен диапазон от -55~+125 ℃ и точност от ±0,5 ℃. Температурата на полето се предава директно по цифров път с една шина, което значително подобрява способността за анти-взаимодействие на системата. Може директно да отчита измерената температура, и може да реализира метод за четене на 9~12-битова цифрова стойност чрез просто програмиране според действителните изисквания. Диапазонът на работното му напрежение е 3~5.5V, и използва различни форми на опаковане, което прави настройката на системата гъвкава и удобна. Зададената разделителна способност и алармената температура, зададени от потребителя, се съхраняват в EEPROM и се запазват след спиране на захранването.

Схема на DS18B20

Схема на DS18B20

2) Въведение в работното време на DS18B20
Всички устройства с една шина изискват строго синхронизиране на сигнала, за да се гарантира целостта на данните. DS18B20 има 6 типове сигнали: импулс за нулиране, пулс за реакция, пишете 0, пишете 1, прочети 0 и прочетете 1. Всички тези сигнали, с изключение на отговорния импулс, са синхронни сигнали, изпратени от хоста. И всички команди и данни се изпращат с ниския бит на байта първи.

DS18B20 импулс за нулиране и импулс за отговор

DS18B20 импулс за нулиране и импулс за отговор

① Импулс за нулиране и импулс за отговор
Всички комуникации по единичната шина започват с инициализираща последователност. Хостът извежда ниско ниво и поддържа ниското ниво за поне 480us, за да генерира импулс за нулиране. Тогава домакинът пуска автобуса, и 4.7K издърпващ резистор дърпа единичната шина високо, с време на забавяне от 15~60us, и влиза в режим на приемане (Rx). След това DS18B20 дърпа шината ниско за 60~240us, за да генерира импулс на отговор на ниско ниво.

Време за запис на DS18B20

Време за запис на DS18B20

② Напишете време
Времето за запис включва запис 0 време и пишете 1 синхронизация. Всички времена за запис изискват поне 60us, и е необходимо поне 1us време за възстановяване между два независими тайминга на запис. И двете времена за запис започват с хоста, който сваля автобуса. Пишете 1 синхронизация: хостът извежда ниско ниво, закъснения за 2us, и след това освобождава автобуса, забавяне 60us. Пишете 0 синхронизация: хостът извежда ниско ниво, закъснения за 60 us, и след това освобождава автобуса със закъснение от 2us.

DS18B20 Време за четене

DS18B20 Време за четене

③ Прочетете времето
Устройствата с една шина предават данни към хоста само когато хостът издаде време за четене. Следователно, след като хостът издаде команда за четене на данни, времето за четене трябва да се генерира незабавно, така че подчиненото устройство да може да предава данни. Всички времена на четене изискват поне 60us, и е необходимо поне 1us време за възстановяване между два независими тайминга на четене. Всяко време за четене се инициира от хоста, което сваля автобуса за поне 1us. Хостът трябва да освободи шината по време на времето за четене и да направи проба от състоянието на шината в рамките на 15us след началото на синхронизирането. Типичният процес на четене на времето е: хостът извежда ниско ниво на забавяне от 2us, след това хостът превключва на забавяне на режима на въвеждане от 12us, след това прочита текущото ниво на единичната шина, и след това забавя 50us.

DS18B20 отваря серийния порт за отпечатване на информация за температурата

DS18B20 отваря серийния порт за отпечатване на информация за температурата

След разбиране на времето за един автобус, нека да разгледаме типичния процес на отчитане на температурата на DS18B20. Типичният процес на отчитане на температурата на DS18B20 е: нулиране → изпращане на SKIPROM (0xCC) → изпрати команда за стартиране на преобразуване (0x44) → забавяне → нулиране → изпращане на команда SKIPROM (0xCC) → изпрати команда за памет (0xBE) → прочете два байта данни (т.е.. температура) непрекъснато → край.

3) Принципна диаграма и конфигурация CUBEMAX
От принципната диаграма, може да се види, че DS18B20 е активиран от PG11 порта за отваряне на серийния порт за отпечатване на информация за температурата

Схема на DS18B20 и конфигурация CUBEMAX

Схема на DS18B20 и конфигурация CUBEMAX

Интерфейс на сензор за температура и влажност DS18B20

Интерфейс на сензор за температура и влажност DS18B20

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(х) направете{ х ? \
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_проверка(невалиден); /* Проверете дали DS18B20 съществува */
кратко ds18b20_get_temperature(невалиден);/* Получете температура */

#endif

5. Инфрачервен модул за дистанционно управление
1) Протокол за кодиране на безжичен модул

Широко използваните методи за кодиране за инфрачервено дистанционно управление са: NEC протокол на ШИМ (широчинно-импулсна модулация) и RC-5 протокол на Philips PPM (импулсна модулация на позицията). Дистанционното управление, което идва с развойната платка, използва протокола NEC, който има следните характеристики:

1. 8-битов адрес и 8-битова дължина на инструкцията;

2. Адресът и командата се предават два пъти (за осигуряване на надеждност);

3. ШИМ импулсна модулация на позицията, с коефициент на запълване на предавания инфрачервен носител, представляващ “0” и “1”;

4. Носещата честота е 38Khz;

5. Битовото време е 1,125 ms или 2,25 ms;

В протокола NEC, как да зададете данните в протокола ‘0’ или „1“? Тук, инфрачервеният приемник и инфрачервеният предавател са разделени.

Инфрачервен предавател: Изпращане на данни от протокола „0“ = 560us на предаване на носещ сигнал + 560ни на предаване на сигнал от носител

Изпращане на данни на протокола „1“ = 560us предаване на носещ сигнал + 1680ни на предаване на сигнал от носител

Дефиницията на битовете на инфрачервения предавател е показана на фигурата по-долу

Инфрачервен приемник: Получаване на данни от протокола ‘0’ = 560us ниско ниво + 560ни високо ниво

Получаване на данни от протокола ‘1’ = 560us ниско ниво + 1680ни високо ниво

Форматът на данните на командата за дистанционно управление на NEC е: терминал за синхронизация, адресен код, адрес обратен код, контролен код, контролен обратен код. Кодът за синхронизация се състои от 9ms ниско ниво и 4,5ms високо ниво. Адресният код, адрес обратен код, контролен код, и контролният обратен код са всички 8-битови формати на данни. Те се изпращат в реда на нисък бит първи и висок бит последен. Инверсният код се използва за повишаване на надеждността на предаването.

Следователно, улавянето на входа може да се използва за измерване на ширината на импулса на високо ниво, за да се постигне декодиране на дистанционно управление.
2) Принципна диаграма и конфигурация CUBEMAX

От принципната диаграма, можем да видим, че безжичният модул е ​​активиран чрез щифта PB9 и се събира през 4 канали на TIM4:

Пинът по подразбиране на TIM4_CH4 не е PB9, така че трябва да се настрои ръчно, и настройката за прекъсване е включена едновременно

3) Кодова част
Уловете нарастващия ръб чрез функцията за обратно извикване на tim

По това време, декодираният сигнал може да бъде получен:

По това време, данните са по-сложни и могат да бъдат леко обработени:

Ефектът е следният:
Последните две цифри са декодираният и неговият обратен код. По това време, може да се дефинира като макрос за регулиране на температурния праг:

Ефектът е следният:

Инфрачервен код на част:

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @файл : main.c
* @накратко : Основно тяло на програмата
******************************************************************************
* @внимание
*
* <h2><център>&копие; Авторско право (c) 2024 STMicroelectronics.
* Всички права запазени.</център></h2>
*
* Този софтуерен компонент е лицензиран от ST под лиценз BSD 3-Clause,
* на “Лиценз”; Не можете да използвате този файл, освен в съответствие с
* Лиценз. Можете да получите копие от Лиценза на:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* КРАЙ НА ПОТРЕБИТЕЛСКИ КОД Заглавие */
/* Включва ——————————————————————*/
#включват “основен.ч”
#включват “тим.ч”
#включват “usart.h”
#включват “gpio.h”

/* Частно включва ———————————————————-*/
/* НАЧАЛО НА ПОТРЕБИТЕЛСКИ КОД Включва */
#включват “stdio.h”
#включват “низ.h”
#дефинирайте MAXUP 157
#дефинирайте MAXDOWN 87
#дефинирайте MINUP 221
#дефинирайте MINDOWN 61
/* ПОТРЕБИТЕЛСКИ КОД END Включва */

/* Частен typedef ———————————————————–*/
/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО PTD */

/* ПОТРЕБИТЕЛСКИ КОД КРАЙ ПТД */

/* Частна дефиниция ————————————————————*/
/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО PD */
/* ПОТРЕБИТЕЛСКИ КОД КРАЙ PD */

/* Частен макрос ————————————————————-*/
/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО ПОСЛЕД */

/* ПОТРЕБИТЕЛСКИ КОД END PM */

/* Частни променливи ———————————————————*/

/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО PV */
uint32_t upCount=0;
uint16_t Стойност нагоре=0;
uint16_t ValueDown=0;
uint8_t isUpCapt=1;
uint16_t ширина=0;
uint16_t буфер[128]={0};
uint16_t bufferId=0;
uint8_t rcvFalg=0;
/* ПОТРЕБИТЕЛСКИ КОД КРАЙ PV */

/* Частни функционални прототипи ———————————————–*/
void SystemClock_Config(невалиден);
/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО PFP */

/* ПОТРЕБИТЕЛСКИ КОД КРАЙ PFP */

/* Личен потребителски код ———————————————————*/
/* НАЧАЛО НА ПОТРЕБИТЕЛСКИ КОД 0 */
анулира HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
upCount++;
}
анулира 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;аз<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_Инициализация();

/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО Инициал */

/* ПОТРЕБИТЕЛСКИ КОД КРАЙ Нач */

/* Конфигурирайте системния часовник */
SystemClock_Config();

/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО SysInit */

/* ПОТРЕБИТЕЛСКИ КОД END SysInit */

/* Инициализирайте всички конфигурирани периферни устройства */
MX_GPIO_Инициал();
MX_TIM4_Инициал();
MX_USART1_UART_Инициал();
/* НАЧАЛО НА ПОТРЕБИТЕЛСКИ КОД 2 */

/* ПОТРЕБИТЕЛСКИ КОД КРАЙ 2 */

/* Безкраен цикъл */
/* ПОТРЕБИТЕЛСКИ КОД НАЧАЛО ДОКОГА */
HAL_GPIO_TogglePin(LED0_GPIO_Порт,LED0_Pin);
HAL_TIM_Base_Start_IT(&htim4);//Актуализирането на таймера генерира прекъсване
HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_4);//
докато (1)
{
ако(rcvFalg)
{
за(int i=0;аз<4;i++)
{
bitBuffer2num(бр);
sprintf(printbuff,”0xx “,бр[аз]);
HAL_UART_Предаване(&huart1,printbuff,стрен(printbuff),HAL_MAX_DELAY);
}
// sprintf(printbuff,”%u “,буфер[аз]);
// 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_Закъснение(1000);
/* ПОТРЕБИТЕЛСКИ КОД КРАЙ ДОКАТО */

/* НАЧАЛО НА ПОТРЕБИТЕЛСКИ КОД 3 */
}
/* ПОТРЕБИТЕЛСКИ КОД КРАЙ 3 */
}

/**
* @brief Конфигурация на системния часовник
* @retval Няма
*/
void SystemClock_Config(невалиден)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};