Tehnologia senzorului de temperatură

Sondă cu senzor de temperatură (Proiectarea circuitelor funcționale ale DS18B20 și PT100)

Schema DS18B20 și configurația CUBEMAX

Comparație între Senzor de temperatură PT100 sondă și Modul DS18B20
1) Principiul de bază al achiziției semnalului
① Rezistența lui PT100 se modifică proporțional cu temperatura (cu atât temperatura este mai mare, cu atât rezistența este mai mare), dar schimbarea rezistenței este foarte mică, despre 0.385 Oh / grad;
② Gama de măsurare a temperaturii de PT100 este de -200 ℃ -200 ℃, și la 0 ℃, Rezistența este exact egală cu 100 Oh;
③ Curentul de lucru al PT100 ar trebui să fie mai mic de 5 MA;
④ Deși rezistența PT100 se modifică proporțional cu temperatura, rata de modificare a acesteia (adică, K valoarea k valoarea k valoare) este diferit în diferite intervale de temperatură.

2) PT100 Tabelul de schimbare a rezistenței la temperatură

PT100 Tabelul de schimbare a rezistenței la temperatură

3. Circuit de acționare PT100

Circuit de acționare PT100

Circuit de acționare PT100

1) Prin metoda diviziei tensiunii, AD colectează tensiunea PT100 pentru a obține valoarea de rezistență pentru a calcula temperatura
Valoarea de rezistență a PT100 în apă la temperatura camerei (25℃ 25 ℃ 25 ℃) este despre 109.89 Oh.
Microcontroller iese de 3,3 V de tensiune, iar tensiunea împărțită la PT100 este aproximativ:
109.89 ∗ 0.005 = 0.54945 V

Valoarea anunțului convertită în funcție de formula de conversie a anunțului este aproximativ:
0.54945 / 3.3 ∗ 4096 = 681.98 ≈ 682

Când temperatura crește cu un grad, presupunând că rezistența PT100 se ridică doar 0.385 Oh, Valoarea de modificare a tensiunii împărțite este aproximativ egală cu:
0.385 ∗ 0.005 = 0.001925 V

Valoarea anunțului convertită în funcție de formula de conversie a anunțului este aproximativ:
0.001925 / 3.3 ∗ 4096 = 2.39 ≈ 2

În experiment, S -a constatat că, din cauza tensiunii instabile de 3,3V a sursei de alimentare STM32, ADC a colectat fluctuații de tensiune PT100 și eroarea de divizare a tensiunii a fost mare. Soluția de optimizare este de a proiecta un circuit sursă de curent constant. Prin colectarea tensiunii PT100 și a curentului sursei de curent constant, Rezistența PT100 poate fi obținută, Și atunci se poate obține valoarea temperaturii.

2) Circuit sursă de curent constant bazat pe regulatorul LDO (MD5333)
Există multe circuite de conducere pentru testarea PT100 pe Internet, cum ar fi circuitul de punte DC, Circuit sursă de curent constant bazat pe amplificator operațional, etc. De asemenea, autorul a petrecut mult timp în selectarea circuitului de conducere, Având în vedere dificultatea de a face consiliul de administrație și numărul de componente, și în cele din urmă a ales circuitul sursă de curent constant bazat pe regulatorul LDO (MD5333). Diagrama circuitului este următoarea:

Circuitul sursă de curent constant al regulatorului LDO (MD5333)

Circuitul sursă de curent constant al regulatorului LDO (MD5333)

În acest moment, Selecția hardware a fost finalizată practic. Consiliul de dezvoltare utilizat este Zhengdian Atom F10zet6 Elite Board

Modul DS18B20
Pentru a testa temperatura în timp real și comparația temperaturii PT100, Se adaugă modulul DS18B20 pentru testul de comparare a calibrării

1) Introducere în DS18B20
DS18B20 este un senzor de temperatură cu un singur autoturism cu un interval de temperatură de testare de -55 ~+125 ℃ și o precizie de ± 0,5 ℃. Temperatura câmpului este transmisă direct într-o manieră digitală cu un singur automat, ceea ce îmbunătățește foarte mult capacitatea anti-interferență a sistemului. Poate citi direct temperatura măsurată, și poate realiza o metodă de citire a valorii digitale de 9 ~ 12 biți printr-o programare simplă în conformitate cu cerințele reale. Intervalul său de tensiune de funcționare este de 3 ~ 5.5V, și folosește o varietate de forme de ambalare, făcând setarea sistemului flexibil și convenabil. Rezoluția setată și temperatura de alarmă setată de utilizator sunt stocate în EEPROM și sunt încă salvate după eșecul de alimentare.

DS18B20 Proiectare circuit

DS18B20 Proiectare circuit

2) Introducere în DS18B20 Timpul de lucru
Toate dispozitivele cu un singur bus necesită o sincronizare strictă a semnalului pentru a asigura integritatea datelor. DS18B20 are 6 Tipuri de semnal: Resetați pulsul, puls de răspuns, scrie 0, scrie 1, citire 0 și citește 1. Toate aceste semnale, cu excepția pulsului de răspuns, sunt semnale sincrone trimise de gazdă. Și toate comenzile și datele sunt trimise cu bitul scăzut al octetului mai întâi.

DS18B20 Reset Puls și Puls de răspuns

DS18B20 Reset Puls și Puls de răspuns

① Resetați pulsul și pulsul de răspuns
Toate comunicațiile din autobuzul unic încep cu o secvență de inițializare. Gazda produce un nivel scăzut și menține nivelul scăzut pentru cel puțin 480us pentru a genera un impuls de resetare. Apoi gazda eliberează autobuzul, iar rezistența de tracțiune de 4,7k trage un singur autobuz ridicat, cu un timp de întârziere de 15 ~ 60us, și intră în modul de primire (Rx). Apoi DS18B20 trage autobuzul scăzut pentru 60 ~ 240us pentru a genera un impuls de răspuns la nivel scăzut.

DS18B20 SCRIE TRMAND

DS18B20 SCRIE TRMAND

② Scrierea calendarului
Timpul de scriere include scrierea 0 sincronizare și scriere 1 sincronizare. Toate calendarul de scriere necesită cel puțin 60us, Și este necesar cel puțin 1 timp de recuperare între două calendaruri de scriere independente. Ambele o cale de scriere încep cu gazda care trage în jos autobuzul. Scrie 1 sincronizare: gazda produce un nivel scăzut, întârzieri pentru 2us, și apoi eliberează autobuzul, întârzierea 60us. Scrie 0 sincronizare: gazda produce un nivel scăzut, întârzieri pentru 60us, și apoi eliberează autobuzul cu o întârziere de 2us.

DS18B20 CITIȚI CITEȘTE

DS18B20 CITIȚI CITEȘTE

③ Citiți calendarul
Dispozitivele cu un singur bus transmite date către gazdă numai atunci când gazda emite o sincronizare de citire. Prin urmare, După emiterea gazdei, o comandă de citire a datelor, O sincronizare citită trebuie generată imediat, astfel încât sclavul să poată transmite date. Toate calendarul citit necesită cel puțin 60us, Și este necesar cel puțin 1 timp de recuperare între două calendaruri de citire independente. Fiecare calendar citit este inițiat de gazdă, ceea ce trage în jos autobuzul cel puțin 1us. Gazda trebuie să elibereze autobuzul în timpul calendarului de citire și să probeze starea autobuzului în 15 ani după începerea calendarului. Procesul tipic de sincronizare a cititului este: Gazda produce o întârziere la nivel scăzut de 2us, Apoi gazda trece la întârzierea modului de intrare de 12us, apoi citește nivelul actual al autobuzului unic, Și apoi întârzie 50us.

DS18B20 deschide portul serial pentru a imprima informațiile de temperatură

DS18B20 deschide portul serial pentru a imprima informațiile de temperatură

După înțelegerea calendarului autobuzului, Să aruncăm o privire asupra procesului tipic de citire a temperaturii DS18B20. Procesul tipic de citire a temperaturii DS18B20 este: Resetare → Trimite skiprom (0XCC) → Trimite comanda de conversie Start (0x44) → Întârziere → Resetare → Trimite comanda skiprom (0XCC) → Trimite comanda de memorie (0Xbe) → Citiți doi octeți de date (adică. temperatură) continuu → capăt.

3) Diagrama schematică și configurația Cubemax
Din diagrama schematică, Se poate observa că DS18B20 este activat de portul PG11 pentru a deschide portul serial pentru a imprima informațiile de temperatură

Schema DS18B20 și configurația CUBEMAX

Schema DS18B20 și configurația CUBEMAX

DS18B20 Interfață senzor de temperatură și umiditate

DS18B20 Interfață senzor de temperatură și umiditate

4) Partea de cod
Partea de cod transplant biblioteca DS18B20 a Atomului Zhengdian și face ușoare modificări

#ifndef __ds18b20_h
#Definiți __DS18B20_H

#include “Tim.H”
/***********************************************************************************/
/* Definiție PIN DS18B20 */

#Definiți DS18B20_DQ_GPIO_PORT GPIOG
#Definiți DS18B20_DQ_GPIO_PIN GPIO_PIN_11
#Definiți DS18B20_DQ_GPIO_CLK_ENABLE() do{ __Hal_rcc_gpiog_clk_enable(); }în timp ce(0) /* Activare ceas de port PG */

/**********************************************************************************************/

/* Funcția de funcționare IO */
#Definiți DS18B20_DQ_OUT(x) do{ 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); \
}în timp ce(0) /* Ieșire port de date */
#Definiți DS18B20_DQ_IN HAL_GPIO_READPIN(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN) /* Intrare a portului de date */

uint8_t ds18b20_init(gol); /* Inițializați DS18B20 */
uint8_t ds18b20_check(gol); /* Verificați dacă există DS18B20 */
scurt DS18B20_GET_TEMPERATURA(gol);/* Obțineți temperatură */

#endif

5. Modul de control la distanță infraroșu
1) Protocol de codificare a modulului wireless

Metodele de codificare utilizate pe scară largă pentru telecomanda cu infraroșu sunt: Protocolul NEC al PWM (modularea lățimii pulsului) și protocolul RC-5 al Philips PPM (modularea poziției pulsului). Telecomanda care vine cu placa de dezvoltare folosește protocolul NEC, care are următoarele caracteristici:

1. 8-Adresa de biți și lungimea instrucțiunii pe 8 biți;

2. Adresa și comanda sunt transmise de două ori (pentru a asigura fiabilitatea);

3. Modularea poziției pulsului PWM, cu ciclul de serviciu al transportatorului cu infraroșu transmis reprezentând “0” și “1”;

4. Frecvența purtătorului este de 38kHz;

5. Timpul de biți este de 1.125ms sau 2,25ms;

În protocolul NEC, Cum se stabilește datele în protocol la ‘0’ sau „1”? Aici, Receptorul infraroșu și emițătorul cu infraroșu sunt separate.

Emițător cu infraroșu: Trimiteți datele privind protocolul „0” = 560us de transmitere a semnalului purtătorului + 560SUA fără transmisie a semnalului de transport

Trimiteți datele privind protocolul „1” = 560us de transmitere a semnalului purtătorului + 1680SUA fără transmisie a semnalului de transport

Definiția de biți a emițătorului infraroșu este prezentată în figura de mai jos

Receptor infraroșu: Primiți date protocol „0” = 560us nivel scăzut + 560Nivelul înalt al SUA

Primiți datele privind protocolul „1” = 560us nivel scăzut + 1680Nivelul înalt al SUA

Formatul de date al comenzii de control de la distanță NEC este: Terminal de sincronizare, Cod de adresă, Adresați codul invers, Cod de control, Controlul codului invers. Codul de sincronizare este format dintr -un nivel scăzut de 9ms și un nivel înalt de 4,5ms. Codul de adresă, Adresați codul invers, Cod de control, și Codul invers de control sunt toate formatele de date pe 8 biți. Sunt trimiși în ordinea bitului scăzut și mai mare înalt. Codul invers este utilizat pentru a crește fiabilitatea transmisiei.

Prin urmare, Captarea de intrare poate fi utilizată pentru a măsura lățimea pulsului nivelului ridicat pentru a obține decodarea controlului la distanță.
2) Diagrama schematică și configurația Cubemax

Din diagrama schematică, Putem vedea că modulul wireless este activat prin pinul PB9 și se colectează prin intermediul 4 canale de TIM4:

PIN -ul implicit al TIM4_CH4 nu este PB9, Deci trebuie să fie setat manual, iar setarea de întrerupere este pornită în același timp

3) Partea de cod
Capturați marginea în creștere prin funcția de apel Tim

În acest moment, Semnalul decodat poate fi obținut:

În acest moment, Datele sunt mai complexe și pot fi ușor procesate:

Efectul este următorul:
Ultimele două cifre sunt decodate și codul său invers. În acest moment, Poate fi definit ca macro pentru a regla pragul de temperatură:

Efectul este următorul:

Cod de piesă infraroșu:

/* Codul utilizatorului începe antetul */
/**
******************************************************************************
* @fişier : mână.c
* @scurt : Corpul programului principal
******************************************************************************
* @Atenţie
*
* <H2><centru>&copie; Drepturi de autor (c) 2024 Stmicroelectronics.
* Toate drepturile rezervate.</centru></H2>
*
* Această componentă software este licențiată de ST în conformitate cu licența de 3 clauze BSD,
* cel “Licenţă”; Nu puteți utiliza acest fișier decât în ​​conformitate cu respectarea
* Licenţă. Puteți obține o copie a licenței la:
* OpenSource.org/licenses/BSD-3-Clauze
*
******************************************************************************
*/
/* Antetul codului utilizatorului */
/* Include ——————————————————————*/
#include “Main.H”
#include “Tim.H”
#include “usart.h”
#include “gpio.h”

/* Private include ———————————————————-*/
/* Codul utilizatorului începe include */
#include “stdio.h”
#include “String.H”
#Definiți maxup 157
#Definiți MaxDown 87
#Definiți Minup 221
#Definiți Mindown 61
/* Endul codului utilizatorului include */

/* Typedef privat ———————————————————–*/
/* Codul utilizatorului începe PTD */

/* Codul utilizatorului End Ptd */

/* Private Defini ————————————————————*/
/* Codul utilizatorului începe PD */
/* Cod utilizator capăt pd */

/* Macro privat ————————————————————-*/
/* Codul utilizatorului începe pm */

/* Codul utilizatorului final pm */

/* Variabile private ———————————————————*/

/* Codul utilizatorului începe PV */
uint32_t upcount = 0;
uint16_t valueUp = 0;
uint16_t evaluate = 0;
uint8_t isupcapt = 1;
uint16_t lățime = 0;
UINT16_T Buffer[128]={0};
uint16_t Bufferid = 0;
uint8_t rcvfalg = 0;
/* Codul utilizatorului PV PV */

/* Prototipuri de funcții private ———————————————–*/
void Systemclock_config(gol);
/* Codul utilizatorului începe PFP */

/* Codul utilizatorului end pfp */

/* Cod de utilizator privat ———————————————————*/
/* Codul utilizatorului începe 0 */
void hal_tim_periodelapsedCallback(Tim_handletypedef *htim)
{
Upcount ++;
}
void hal_tim_ic_captureCallback(Tim_handletypedef *htim)
{
dacă(isupcapt)//Dacă este în creștere a capturii de margine
{
ValureUp = Hal_tim_ReadCaptureDValue(Htim htim,Tim_channel_4);
isupCapt = 0;
__Hal_tim_set_capturepolarity(Htim htim,Tim_channel_4, tim_icpolarity_falling);
Upcount = 0;
}
altfel{
EvaluateDown = hal_tim_readcapteuredValue(Htim htim,Tim_channel_4);
isupCapt = 1;
__Hal_tim_set_capturepolarity(Htim htim,Tim_channel_4, tim_icpolarity_rising);
Lățime = evaluată+Upcount*65536-ValueUp;
dacă(lăţime>4400&&lăţime<4600)
{
Bufferrid = 0;
tampon[Bufferid ++]= lățime;
}
altfel dacă(Bufferid>0)
{
tampon[Bufferid ++]= lățime;
dacă(Bufferid>32)
{
rcvfalg = 1;
Bufferrid = 0;
}
}
}
}
void bitbuffer2num(Char num[])
{
num[0]= 0;
num[1]= 0;
num[2]= 0;
num[3]= 0;
pentru(int i = 0;i<32;I ++)
{
dacă(tampon[I+1]<1000)
{
num[I/8]= num[I/8]<<1;
}
altfel
{
num[I/8]= num[I/8]<<1;
num[I/8]|= 0x01;
}
}
}
/* CODUL UTILIZATOR 0 */

/**
* @Brief punctul de intrare a aplicației.
* @retval int
*/
int Main(gol)
{
/* Codul utilizatorului începe 1 */
Char PrintBuff[128]={0};
Char num[4]={0};
CHAR CHAR = 0;
/* CODUL UTILIZATOR 1 */

/* Configurare MCU——————————————————–*/

/* Resetați toate perifericele, Inițializează interfața flash și Sysistent. */
Hal_init();

/* Codul utilizatorului începe init */

/* Init codul utilizatorului init */

/* Configurați ceasul sistemului */
Systemclock_config();

/* Codul utilizatorului începe sysinit */

/* Codul utilizatorului sysinit */

/* Inițializează toate perifericele configurate */
Mx_gpio_init();
Mx_tim4_init();
MX_USART1_UART_INIT();
/* Codul utilizatorului începe 2 */

/* CODUL UTILIZATOR 2 */

/* Buclă infinită */
/* Codul utilizatorului începe în timp ce */
Hal_gpio_togglepin(Led0_gpio_port,Led0_pin);
Hal_tim_base_start_it(&htim4);//Actualizarea cronometrului generează o întrerupere
Hal_tim_ic_start_it(&htim4, tim_channel_4);//
în timp ce (1)
{
dacă(rcvfalg)
{
pentru(int i = 0;i<4;I ++)
{
Bitbuffer2num(num);
sprintf(Printbuff,”0xx “,num[i]);
Hal_uart_transmit(&Huart1, PrintBuff,Strlen(Printbuff),Hal_max_delay);
}
// sprintf(Printbuff,”%u “,tampon[i]);
// Hal_uart_transmit(&Huart1, PrintBuff,Strlen(Printbuff),Hal_max_delay);
// }
Hal_uart_transmit(&Huart1,”\r\n”,2,Hal_max_delay);
rcvfalg = 0;
}
printf(“%d\r\n”,num[3]);
dacă(num[3]== 157)
{
printf(“111111\r\n”);
}
Hal_delay(1000);
/* Codul utilizatorului se termină în timp ce */

/* Codul utilizatorului începe 3 */
}
/* CODUL UTILIZATOR 3 */
}

/**
* @Brief Configurare ceas de sistem
* @Retval Niciun
*/
void Systemclock_config(gol)
{
Rcc_oscinittipedef rcc_oscinitstruct = {0};
Rcc_clkinittipedef rcc_clkinitstruct = {0};