TERMOMETRO CON PIC18 E DS18B20

Semplice Termometro con Display LCD, Microcontrollore PIC18 o PIC16 e Sensore di Temperatura DS18B20…

 

 

 

 



 

INTRO

L’integrato DS18B20 è un sensore digitale di temperatura che permette di effettuare una misura in gradi Celsius con una definizione che va da 9bit ad un massimo di 12bit. Inoltre dispone di un allarme interno con la possibilità di fissare la temperatura di allarme su una memoria non volatile (ovvero che non si cancella allo spegnimento del dispositivo) e settare se avere l’allarme per temperature maggiori o minori di quella fissata.

La piedinatura è la seguente:

In questo articolo questo sensore viene usato per realizzare un termometro con tre cifre decimali dopo la virgola e la possibilità di visualizzare valori di temperatura negativi e positivi. Inoltre nel codice oltre alla funzione di visualizzazione su display LCD vi è una funzione che permette di ottenere il valore di temperatura per utilizzarlo in altre funzioni.

 



 

CODICE

Il codice è il seguente:

sbit LCD_RS at RB0_bit;                        //Connessione LCD
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;           //Display connesso a PORTB
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;

char text[8];                                  //Variabile di testo
unsigned temp;                                 //Variabile temperatura ricevuta
long temperatura;                              //Variabile temperatura

void LCD_Temp(unsigned int TempLetta) {        //Funzione visualizzazione temperatura
  char temp_intero;                            //Parte intera Temp

  if (TempLetta & 0x8000) {                    //Se Temp negativa
     text[0] = '-';                            //Scrivi -
     TempLetta = ~TempLetta + 1;               //Inverti temperatura letta
  }

  temp_intero = TempLetta >> 4 ;               //Shifta di 4 posizioni
  text[0] = (temp_intero/100)%10  + 48;        //Estrai centinaia
  text[1] = (temp_intero/10)%10 + 48;          //Estrai decine
  text[2] =  temp_intero%10     + 48;          //Estrai unità
  text[3] =  '.';                              //mostra ounto per dividere i decimali

  TempLetta &= 0x000F;                         //Isola la parte decimale
  TempLetta *= 625;                            //Moltiplica per 625 (ris iniziale 12bit)
  text[4] =  TempLetta/1000    + 48;           //Estrai decimi
  text[5] = (TempLetta/100)%10 + 48;           //Estrai centesimi
  text[6] = (TempLetta/10)%10  + 48;           //Estrai millesimi

  Lcd_Out(2, 5, text);                         //Mostra il testo con la temp
}

long Converti_Temp(unsigned int TempLetta) {   //Funzione Conversione temperatura
  unsigned int temp_intero;                    //Parte intera temp
  long temperatura;                            //Variabile con temperatura
  bit meno;                                    //Segno - o +
  meno = 0;                                    //Inizializza a 0 il meno
  
  if (TempLetta & 0x8000) {                   //Se Temp negativa
     TempLetta = ~TempLetta + 1;              //complemento a 1
     meno = 1;                                //Variabile meno = 1
  }

  temp_intero = TempLetta >> 4;               //Dividi parte intera
  TempLetta &= 0x000F;                        //Dividi parte decimale
  TempLetta *= 6250;

  temperatura = temp_intero * 100000;         //Unisci le due parti
  temperatura += TempLetta;

  if (meno)  temperatura /= (10);             //Se temp > 0 dividi per 10
  else temperatura /= 10;                     //Se temp < 0 dividi per -10

  return temperatura;                         //Ritora temperatura x 10000
}


void main() {                                 //Programma principale
  Lcd_Init();                                 //Inizializza LCD
  Lcd_Cmd(_LCD_CLEAR);                        //Pulisci LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                   //Spegni cursore
  Lcd_Out(1, 1, " Temperatura:   ");          //Prima riga mostra "Temperatura:"
  Lcd_Chr(2,13,223);                          //Mostra simbolo grado
  Lcd_Chr(2,14,'C');                          //Mostra C di centrigrado
  
  TRISB.F7 = 0;                               //Pin 28 uscita

  while(1) {                                  //Ciclo infinito
    Ow_Reset(&PORTB, 6);                      //Onewire reset
    Ow_Write(&PORTB, 6, 0xCC);                //Comando SKIP_ROM
    Ow_Write(&PORTB, 6, 0x44);                //Comando CONVERT_T

    Delay_us(120);                            //Aspetta 120us
    Ow_Reset(&PORTB, 6);                      //Onewire reset
    Ow_Write(&PORTB, 6, 0xCC);                //Comando SKIP_ROM
    Ow_Write(&PORTB, 6, 0xBE);                //Comando READ_SCRATCHPAD

    temp =  Ow_Read(&PORTB, 6);               //Leggi primo byte
    temp = (Ow_Read(&PORTB, 6) << 8) + temp;  //Leggi secondo byte

    LCD_Temp(temp);                           //Mostra valore temperatura
    temperatura = Converti_Temp(temp);        //Converti temperatura letta in valore dec
//La funzione Converti_Temp(temp) ritorna il valore di temp moltiplicato per 10000

    if (temperatura < 245000)  PORTB.F7 = 1;  //Se temp minore di 24.5°C pin 28 alto
    else PORTB.F7 = 0;                        //Se temp maggiore di 24.5°C pin 28 basso

    Delay_ms(1000);                           //Ritardo di 1 sec

  }
}

Viene prima di tutto inizializzata la connessione tra LCD e microcontrollore, poi si inizializzano alcune variabili e si realizza la prima funzione utile, ovvero quella per mostrare sul display LCD la temperatura.

Questa funzione riceve i dati dal sensore e li elabora estraendo le cifre di centinaia, decine, unità, decimi, centesimi e millesimi e una volta formata la stringa si va a visualizzare sul display.

La seconda funzione, molto simile va invece a estrarre un valore di temperatura dal dato ricevuto e in particolare ritorna il valore di temperatura moltiplicato 10000.

Nel programma principale si va inizializzare il display e si va a scrivere la stringa temperatura e il simbolo di grado centigrado.

Nel ciclo infinito si va a configurare il sensore di temperatura e poi si va a leggere il valore convertito. Questo valore convertito viene inviato alle due funzioni viste prima, con la prima si visualizza il valore su LCD mentre la seconda ritorna il valore di temperatura moltiplicato 10000. Questo valore può essere usato ad esempio in un ciclo “if” per accendere un LED in funzione della temperatura.

I fuses sono quelli di default di Mikroc e la frequenza di oscillazione è 8MHz.
 

SCHEMA

Lo schema è il seguente:

La tensione di alimentazione è 5V e giunge al positivo del sensore, al positivo del display LCD e al pin 20 del microcontrollore, mentre la massa è collegata ai pin 8 e 19. Il circuito di oscillazione è formato da C1, C2 e X1 ovvero un quarzo da 4MHz. Il microcontrollore è mantenuto in funzione grazie ad R3.

Il sensore è alimentato anch’esso a 5V e R1 è la resistenza di pull-up sulla linea dati. Il display LCD ha la retroilluminazione alimentata a 5V con una resistenza di protezione da 470 Ohm. I pin del display sono connessi come indicato nel codice con un resistore variabile connesso a VEE per regolare il contrasto. Tutti i pin del display non connessi sono collegati a GND.

 

DOWNLOAD

Potete scaricare la simulazione del circuito con PROTEUS e il codice compilato con MIKROC al seguente LINK!!!



 

[Voti Totali: 0 Media Voti: 0]
Segui la Nostra Pagina Facebook: Facebook

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *