Page d'accueil
Alim de labo
GBF
GBF num.
LCD graphiques
Oscilloscope
Journal Lumineux
Winamp LCD
Détecteur Métaux
Analyseur
Horloge
Minute Fer
PIC16F84 i2c
Prog. PIC
Ampli 70W
Ampli ponté 120W
Ampli MOS 200W
TempLogger
Ampli TV
Divers
LCDbin
Softs divers
Modélisme
VRML / OpenGL
Liens
Impression Typons

 

 

DS1615 - DS1616

 

Le DS1616 est un enregistreur de température (+ 3 entrées analogiques) autonome sur batterie 3V. Il possède un capteur interne capable de mesurer la température entre -40°C et +85°C, une horloge temps réelle (RTC) complète (jours / mois / année / heure / minute / seconde) et une mémoire de 2048 octets pour les échantillons. La RTC utilise un Quartz d’horloge à 32,768KHz. L’acquisition des entrées est faite à des intervalles variant entre 1 et 255 minutes. Il possède aussi une zone mémoire pour stocker l’histogramme des températures. Il y a aussi la gestion de dépassement de consigne (haute ou basse) et une alarme qui peuvent déclencher une interruption (INT). La communication se fait soit par port série avec contrôle par CRC16 soit par bus 3 fils (SCLK, I/O, /RST) sans contrôle de CRC16. Vous trouverez l’application du DS1615 avec le port série du PC dans l’article sur le TempLogger.

 


J’ai choisi d’interfacer le DS1616 avec mon GBF numérique via le bus 3 fils.

 

Organisation de la mémoire :

La mémoire est structurée en pages de 32 octets. La première page contient les paramètre d’horloge, d’acquisition et les divers registres de commande de la puce.
Les pages 128 à 191 contiennent les données enregistrés par le capteur de température, c’est donc essentiellement celle-ci que j’ai utilisé avec les pages 0 et 1.

 

 

Registres des pages 0 (adr 0x00 à 0x1F) et 1 (adr 0x20 à 0x3F) :



Description du programme ‘C’ de communication avec le DS1616 :

(Ce programme est aussi valable pour un DS1615 !)

Le DS1616 est relié au PIC16F877 via 3 fils :
//--- DS1616 : BUS 3 fils --- (temperature + horloge)
#define SCLK  RB0        // horloge (output)
#define I_O   RC0        // donnees (input / ouput)
#define RST   RC1        // validation bus (output)
#define TRIS_I_O TRISC0  // sens donnees (1 input, 0 output)
// Au demarrage TRIS_I_O = 1;

Liste des fonctions :

On retrouve ici la structure principale time1616 qui contient la RTC et les fonctions de base pour communiquer avec le DS1616.
Un transfert démarre par un “ds1616_start” puis on envoie et l’on reçoit des données avec “ds1616_send” et “ds1616_receive”. Le transfert se termine par un “ds1616_stop ”. Comme je le disais dans l’introduction, il n’y a pas de CRC16 avec ce type de connexion.
Au dessus de ces fonctions on a la fonction d’envoie d’une commande “ds1616_command”. La lecture et l’écriture des registres se fait par “ds1616_read_byte” et “ds1616_wr_byte”.
Tous les registres sont codés en BCD (binaire codé décimal) c’est à dire qu’ils contiennent deux nombres décimaux entre 0 et 9 dans chaque quartet (1/2 octet) ; exemple 10 est codé 0x10, 54 est codé 0x54...
Les échantillons de température sont stockés dans des pages, j’ai donc écrit la fonction “ ds1616_Read_Page” pour les lire.

 

//===================================================================
//   DS1616
//===================================================================
#define SAMPLE_RATE 0x000D
#define CONTROL1  0x000E
#define TEMPERATURE 0x0011
#define STATUS1  0x0014
#define CONTROL2  0x0029
#define STATUS2  0x002A

// Structure de la RTC
typedef struct{
 unsigned char sec;
 unsigned char min;
 unsigned char heure;
 unsigned char day;
 unsigned char jj;
 unsigned char mm;
 unsigned char yy;
}time1616;


void ds1616_start();        // demarre un transfert
void ds1616_stop();         // termine un transfert
void ds1616_send(unsigned char data);   // envoie une donnee
unsigned char ds1616_receive();     // reception d'une donnee
void ds1616_command(unsigned char command); // envoie une commande
void ds1616_wr_byte(unsigned char adr, unsigned char data); // ecrit un octet à l'adresse adr
unsigned char ds1616_read_byte(unsigned int adr);     // lit un octet à l'adresse adr

//=============================================================================
//   Fonctions DS1616 
//=============================================================================
void is_ds1616(unsigned char* val);   // ajoute 1 & teste si nombre BCD
void ds1616_set_date(time1616* montre);  // regle la date
void ds1616_set_heure(time1616* montre);  // regle l'heure
void ds1616_get_date(time1616* montre);  // affiche la date
void ds1616_get_heure(time1616* montre);  // affiche l'heure

unsigned char ds1616_temp();      // mesure et affiche la temperature
void ds1616_RTC();         // envoie la RTC sur le port serie
void ds1616_clear();        // efface la memoire de DataLog...
void ds1616_Begin_Mission(unsigned char rate);
void ds1616_End_Mission();
void ds1616_Read_Page(unsigned char page);

void ds1616_Data_log();

 

Maintenant que vous avez les bases, je vous donne le code source de ces fonctions. Si vous voulez plus d’informations sur le stockage des histogrammes ou d’autre fonction, je vous invite à regarder les datasheets DS1615, DS1616, et l’AN116.

 

//===================================================================
//   DS1616 horloge/temperature
//===================================================================
void
ds1616_start()
{
 SCLK = 0;
 RST = 1;
}
//===================================================================
void
ds1616_stop()
{
 TRIS_I_O = 1;     // input
 RST = 0;
 SCLK = 0;
}
//===================================================================
void
ds1616_send(unsigned char data)
{
 unsigned char tmp, d = data;
 TRIS_I_O = 0;     // output
 for(tmp=8; tmp>0; tmp--){
  SCLK = 0;
  if (d & 0x01) I_O = 1;
  else    I_O = 0;
  d = d>>1;
  SCLK = 1;
 }
 SCLK = 0;
}
//===================================================================
unsigned char
ds1616_receive()
{
 unsigned char tmp, d = 0;
 TRIS_I_O = 1;     // input
 SCLK = 0;
 for(tmp=0; tmp<8; tmp++){
  SCLK = 1;
  if (I_O = 1) bitset(d,tmp);
  //else bitclr(d,tmp);
  SCLK = 0;
 }
 return d;
}
//===================================================================
void
ds1616_command(unsigned char command)
{
// 0x44 : Specification Test, 0x55 : Read Data, 0xa5 : Clear Memory
 ds1616_start();
 ds1616_send(command);
 ds1616_stop();
}
//===================================================================
void
ds1616_wr_byte(unsigned char adr, unsigned char data)
{
 ds1616_start();
 ds1616_send(0x22);
 ds1616_send(adr & 0x7F); // a7=0
 ds1616_send(data);
 ds1616_stop();
}
//===================================================================
unsigned char
ds1616_read_byte(unsigned int adr)
{
 unsigned char tmp;
 ds1616_start();
 ds1616_send(0x33);
 ds1616_send(adr>>8);
 ds1616_send(adr&0x00FF);
 tmp = ds1616_receive();
 ds1616_stop();
 return tmp;
}
//===================================================================
void
is_ds1616(unsigned char* val)
{
 (*val)++;
 if (((*val) & 0x0F)>0x09) *val = ((*val) & 0xF0) + 0x10;  // si 0xY-A .. 0xY-F -> 0xY+1-0
 if (((*val) & 0xF0)>0x90) *val = ((*val) & 0x0F);
}
//===================================================================
void
ds1616_set_date(time1616* montre)
{
 if ((montre->day > 0x07)||(montre->day == 0x00)) montre->day = 0x01;
 if ((montre->jj > 0x31)||(montre->jj == 0x00))  montre->jj = 0x01;
 if ((montre->mm > 0x12)||(montre->mm == 0x00))  montre->mm = 0x01;
 if (montre->yy > 0x99) montre->yy = 0x00;
 ds1616_wr_byte(0x03, montre->day);
 ds1616_wr_byte(0x04, montre->jj);
 ds1616_wr_byte(0x05, montre->mm);
 ds1616_wr_byte(0x06, montre->yy);
}
//===================================================================
void
ds1616_set_heure(time1616* montre)
{
 if (montre->sec > 0x59)  montre->sec = 0x00;
 if (montre->min > 0x59)  montre->min = 0x00;
 if (montre->heure > 0x23)  montre->heure = 0x00;
 ds1616_wr_byte(0x00, montre->sec);
 ds1616_wr_byte(0x01, montre->min);
 ds1616_wr_byte(0x02, montre->heure);
}
//===================================================================
void
ds1616_get_date(time1616* montre)
{
// unsigned char day, jj, mm, yy;
 unsigned char dayTmp;
 char jour[] = "zzDILUMAMEJEVESA";
 ds1616_start();
 ds1616_send(0x33); // read page
 ds1616_send(0x00); // page 0
 ds1616_send(0x03); // page 0
 montre->day = ds1616_receive();
 montre->jj  = ds1616_receive();
 montre->mm  = ds1616_receive();
 montre->yy  = ds1616_receive();
 ds1616_stop();

 dayTmp = (montre->day) * 2;
 lcd_putchar(jour[dayTmp]);
 lcd_putchar(jour[dayTmp + 1]);
 lcd_putchar(' ');
 lcd_2ascii(montre->jj);
 lcd_putchar('/');
 lcd_2ascii(montre->mm);
 lcd_putchar('/');
 lcd_2ascii(montre->yy);
 lcd_putchar(' ');
}
//===================================================================
void
ds1616_get_heure(time1616* montre)
{
// unsigned char ss, mm, hh;
 ds1616_start();
 ds1616_send(0x33);  // read page
 ds1616_send(0x00);  // page 0
 ds1616_send(0x00);  // page 0
 montre->sec   = ds1616_receive();
 montre->min   = ds1616_receive();
 montre->heure = ds1616_receive();
 ds1616_stop();

 lcd_2ascii(montre->heure);
 lcd_putchar(':');
 lcd_2ascii(montre->min);
 lcd_putchar(':');
 lcd_2ascii(montre->sec);
}
//===================================================================
unsigned char
ds1616_temp()
{
 unsigned char temp, half;
 signed char Dtemp, DDtemp;
 if (!(ds1616_read_byte(CONTROL2)&0x40)) ds1616_wr_byte(CONTROL2, 0x40);
 // control2-> enable CS0 : temp
 ds1616_command(0x55);        // Read Data
 while(!(ds1616_read_byte(STATUS1)&0x80));  // attend DataReady
 temp = ds1616_read_byte(TEMPERATURE);   // read temperature

 lcd_line2();
 half = temp & 0x01;
 Dtemp = temp/2 - 40;
 if (Dtemp<0){
  lcd_putchar('-');
  Dtemp = -Dtemp;
 }
 else lcd_putchar(' ');
 DDtemp = Dtemp/10;
 if (DDtemp!=0) lcd_putchar(DDtemp+0x30);
 else lcd_putchar(' ');
 lcd_putchar(Dtemp%10+0x30);
 lcd_putchar(0xDF);   // °
 lcd_putchar('C');
 lcd_putchar(half*5+0x30); //0.5°C
 return temp;
}

//===================================================================
void
ds1616_RTC()
{
 tx232_puts("\x0d\x0dRTC/RAM");
 ds1616_Read_Page(0x00);
 ds1616_Read_Page(0x01);
}
//===================================================================
void
ds1616_clear()
{
/// unsigned char tmp;
/// for(tmp=0x16; tmp<0x20; tmp++) ds1616_wr_byte(tmp, 0x00);
 ds1616_wr_byte(CONTROL1, 0x40);     // control1-> enable OSC, enable CLEAR
 tempo_x65ms(4);
 ds1616_command(0xA5);        // Clear memory
//**
 while(ds1616_read_byte(CONTROL1)&0x40);  // attend Memory CLR=0
 tempo_x65ms(15);          // tempo 500us min
//**
/// ds1616_wr_byte(CONTROL1, 0x00);    // control1-> enable OSC, disable CLEAR
}
//===================================================================
void
ds1616_Begin_Mission(unsigned char rate)
{
// CONTROL1                           STATUS1
// /EOSC|CLR|0|SE|RO|TLIE|THIE|AIE ,  DR|MEM CLR|MIP|LOBAT|TLF|THF|ALMF
 ds1616_clear();          // efface memoire Data logging...
 ds1616_wr_byte(CONTROL2, 0x40);     // CS0 : Temp
 ds1616_wr_byte(CONTROL1, 0x08);     // roll over SE=0
 ds1616_wr_byte(SAMPLE_RATE, rate);
}
//===================================================================
void
ds1616_End_Mission()
{
 ds1616_wr_byte(STATUS1, 0x00);
}
//===================================================================
void
ds1616_Read_Page(unsigned char page)
{
 unsigned char tmp, tmp2 = 8, adrH, adrL;
 unsigned int address;

 address = 0x0020 * page;
 adrH = address >> 8;
 adrL = address & 0x00FF;

 ds1616_start();
 ds1616_send(0x33);    // read page
 ds1616_send(adrH);    // page H
 ds1616_send(adrL);    // page L
 for(tmp=0; tmp<0x20; tmp++){
  if (tmp2>7){
   tx232(0x0D);
   tx232_2ascii(adrH);
   tx232_2ascii(tmp+adrL);
   tx232(':');
   tmp2 = 0;
  }
  tx232(' ');
  tx232_2ascii(ds1616_receive());
  tmp2++;
 }
 ds1616_stop();
}
//===================================================================
void
ds1616_Data_log()
{
 unsigned char page;
 ds1616_RTC();      // rtc pour compteur sample, start day, time...
 tx232(0x0d);
 tx232_puts("Data log");
 for(page = 0x80; page<0xC0; page++) ds1616_Read_Page(page);
}
//===================================================================


 

Téléchargement du code source :

Il s’agit du programme du GBF numérique qui n’est pas encore terminé. Les fonctions d’horloge et de datalog fonctionnent correctement dans cette version.
On peut lire l’heure et la date, la régler, paramétrer l’intervalle d’échantillonage, démarrer une mission, l’arreter, envoyer les échantillons par port série à 115200 bps (8 bits, 1 stop, pas de parité).

 GBF + DS1616 v1

  GBF + DS1616 v2 (pb fréquencemètre)

 

 

       AVERTISSEMENT

Le contenu de ce site ne peut en aucun cas être utilisé à des fins lucratives (sauf autorisation).

Je ne peux en aucun cas être tenu pour responsable en cas d'accident ou autre.

 

Sébastien JEFFROY ©2003-2007         contact :   Sébastien JEFFROY