ds1307 algorithme
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

ds1307 algorithme



  1. #1
    invitec4b571da

    ds1307 algorithme


    ------

    Bonjour, je suis actuellement sur l'étude du ds1307, j'ai compri a peu près son fonctionnement( utilisation bus I²C, écriture, lecture), je dois faire un programme mais je suis déjà un peu perdu pour faire un algorithme. Il permet de récupérer le jour et l'heure actuel toutes les secondes. Je pense partir en faisant la sauvegarde dans un tableau. Je souhaiterais savoir si je pars dans la bonne direction. Et si vous possédez des algorithmes de ce genre qui me premettent d'avancer, il suit preneur. Merci d'avance pour tous ceux qui me répondront.

    -----

  2. #2
    Jack
    Modérateur

    Re : ds1307 algorithme

    Tu ne dis pas si c'est un PC ou un microcontrôleur qui va piloter l'I2C, ni si tu possèdes déjà les fonctions de gestion du bus, ni en quel langage tu développes.

    Après, que tu ranges tes données dans un tableau ou pas a peu d'importance. Si ton langage le permet, je te conseille les structures (en C) ou les record (en Pascal). En basic, je ne sais pas si çà existe.

    A+

  3. #3
    invitec4b571da

    Re : ds1307 algorithme

    Merci pour la réponse, j'utilise un ds1307 avec un 16f873, ensuite cela sera connecté à des leds matrices qui afficherons les heures, les dates, un peu comme un planning sur un panneau d'affichage de dimension 175cm par 100cm qui servira pour le personnel de maison de retraite (c'est vous montrer la vision du projet). Moi, je ne travaille que sur la partie programmation, C'est donc le 16f873 qui pilote l'I²C. Je ne possède pas la gestion du bus à priorie, cela n'est pas précisé. Le langage sera surement en C. L'important est que je trouve un algorithme qui me permet de récupérer le jour et l'heure réelle toutes le secondes. Ceci permet de partir queleques heures, de revenir quoi qu'il s'est passé( panne de courant par exemple) le ds1307 sauvegarde l'heure grace à sa batterie de secours, lorsque le courant revient, il le transmet au pic 16f873 et l'heure repart à l'heure réelle et non celle ou il aurait coupé. Merci .

  4. #4
    mat64

    Re : ds1307 algorithme

    Bonjour,

    Euh...le 16F873 est doté d'un port I2C. Donc y'a plus rien à faire... Tu veux un algorithme pour faire quoi ?

    1 timer déclenche une interruption, dans l'it, lecture I2C qui place les valeurs récupérées dans des registres, et en tâche de fond tu mets à jour l'affichage de tes leds à partir des valeurs des registres. Même pas sur que ça vaille le coup de faire un dessin pour ça...

  5. A voir en vidéo sur Futura
  6. #5
    invite5637435c

    Re : ds1307 algorithme

    Voici une base fonctionnelle écrite sur MikroC pour un LCD qu'il te suffit d'adapter pour des afficheurs Leds, j'ai commenté pour t'aider à comprendre le principe:

    RTC_DS1307.h
    Code:
    //////////////////////////////////////////////////////////////////////////////////////
    ///   HULK28     DS1307 code source  (code C écrit sur MikroC v7.0.0.3)    ///
    //////////////////////////////////////////////////////////////////////////////////////
    
    # include "Config.h"
    
    
    // déclaration des variables
    
    unsigned short m,HourDate[7];
    char *txt, LCD_txt[3], text[16], seconde, minute, heure, jour, mois, annee;
    
    // prototypes des fonctions
    
    void RTC_Initial_values();  // Valeurs initiales de l'horloge
    void ds1307_write(unsigned short rtc_reg, unsigned short rtc_data); 
    void Read_DS1307(); 
    
    
    //==============================================================================
    //  Initialisation des registres de l'horloge
    //==============================================================================
    
    void RTC_Initial_values() 
    { 
     I2C_Start();                   // Active l'I2C
     I2C_Wr(DS1307_DevAdr_Wr);      // DS1307 en mode écriture 
     while (I2C_Is_Idle() == 0) ;   // on attend tant que le bus I2C est occupé (0= occupé,1=libre)
     I2C_Wr(0x00);                  // pointe sur le registre des secondes
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x00);                  // écrit la valeur 0 seconde
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x00);                  // écrit la valeur 0 dans le registre minute
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x0C);                  // écrit la valeur 12 dans le registre heure
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x05);                  // écrit la valeur 5 dans le registre jour (de la semaine)
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x14);                  // écrit la valeur 14 (n° du jour) dans le registre mois
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x11);                  // écrit la valeur 11 (n° du mois) dans le registre date
     while (I2C_Is_Idle() == 0) ; 
     I2C_Wr(0x07);                  // écrit la valeur 7 dans le registre année
     while (I2C_Is_Idle() == 0) ; 
     I2C_Stop();                    // Arrête l'I2C
    }
    
    //==============================================================================
    //         Fonction d'écriture dans les registres de l'horloge I2C DS1307
    //==============================================================================
    
    void ds1307_write(unsigned short rtc_reg, unsigned short rtc_data) 
    { 
     I2c_start(); 									// Active l'I2C
     I2c_Wr(DS1307_DevAdr_Wr);      // 1101 000 est l'adresse de l'horloge, le LSB indique le mode (0=W, 1=R) 
     I2c_Wr(rtc_reg);               // indique dans quel registre on veut écrire 
     I2c_Wr(rtc_data);              // écrit la donnée dans le registre 
     I2c_stop(); 										// Arrête l'I2C
    } 
    
    //==============================================================================
    //          Fonction de lecture des registres de l'horloge I2C DS1307
    //==============================================================================
    
    void Read_DS1307() 
       { 
        *(txt)=0; 				// initialise le pointeur txt
        I2C_Stop();				// arrêt de l'I2C
        delay_ms(50);
        I2C_Start();
        I2C_Wr(DS1307_DevAdr_Wr);	
        I2C_Wr(0);
        I2C_Repeated_Start();
        I2C_Wr(DS1307_DevAdr_Rd);
    
        m=I2C_Rd(1);              			// on lit le byte avec acquittement de l'esclave requis
        HourDate[6]=Bcd2Dec(m);   			// conversion BCD -> DECIMAL
        ByteToStr(HourDate[6],LCD_txt); // formatage Byte en string pour le LCD
        if (HourDate[6] < 10)						// Si dizaine de secondes <10 on fait apparaitre le 0 des dizaines
        {
         LCD8_Chr(2,14,'0');						// sur la ligne 2, colonne 14 du LCD
         LCD8_Chr(2,15,LCD_txt[2]);			// les secondes apparaissent ligne 2, colonne 15 du LCD
        }
        else  // sinon on affiche pas le 0 des dizaines de secondes
        {
         LCD8_Chr(2,14,LCD_txt[1]);
         LCD8_Chr(2,15,LCD_txt[2]);
        }
        while (I2C_Is_Idle() == 0) ;
    
        m=I2C_Rd(1);              // minute(s)
        HourDate[5]=Bcd2Dec(m);
        ByteToStr(HourDate[5],LCD_txt);
        if (HourDate[5] < 10)
        {
         LCD8_Chr(2,11,'0');
         LCD8_Chr(2,12,LCD_txt[2]);
        }
        else
        {
         LCD8_Chr(2,11,LCD_txt[1]);
         LCD8_Chr(2,12,LCD_txt[2]);
        }
        while (I2C_Is_Idle() == 0) ;
    
        m=I2C_Rd(1);                  // heure(s)
        HourDate[4]= Bcd2Dec(m);
        ByteToStr(HourDate[4],LCD_txt);
        if (HourDate[4] < 10)
        {
        LCD8_Chr(2,8,'0');
        LCD8_Chr(2,9,LCD_txt[2]);
        }
        else
        {
         LCD8_Chr(2,8,LCD_txt[1]);
         LCD8_Chr(2,9,LCD_txt[2]);
        }
        while (I2C_Is_Idle() == 0) ;
    		  
        m=I2C_Rd(1);              // jour(s) de la semaine
    		HourDate[3] = Bcd2Dec(m);
        while (I2C_Is_Idle() == 0) ;
    
        m=I2C_Rd(1);
        HourDate[2] = Bcd2Dec(m);  // date (n° du jour)
        ByteToStr(HourDate[2],LCD_txt);
        if (HourDate[2] < 10)
        {
        LCD8_Chr(1,8,'0');
        LCD8_Chr(1,9,LCD_txt[2]);
        }
        else
        {
        LCD8_Chr(1,8,LCD_txt[1]);
        LCD8_Chr(1,9,LCD_txt[2]);
        }
        while (I2C_Is_Idle() == 0) ;
    
        m = I2C_Rd(1);
        HourDate[1] = Bcd2Dec(m); // mois
        ByteToStr(HourDate[1],LCD_txt);
        if (mois < 10)
        {
        LCD8_Chr(1,11,'0');
        LCD8_Chr(1,12,LCD_txt[2]);
        }
        else
        {
        LCD8_Chr(1,11,LCD_txt[1]);
        LCD8_Chr(1,12,LCD_txt[2]);
        }
        
        while (I2C_Is_Idle() == 0) ;
    
        m = I2C_Rd(0);             // pas d'acquittement de l'esclave requis
    
        HourDate[0] = Bcd2Dec(m);  // année
        ByteToStr(HourDate[0],LCD_txt);
        if (HourDate[0] < 10)
        {
        LCD8_Chr(1,14,'0');
        LCD8_Chr(1,15,LCD_txt[2]);
        }
        else
        {
        LCD8_Chr(1,14,LCD_txt[1]);
        LCD8_Chr(1,15,LCD_txt[2]);
        }
        
        while (I2C_Is_Idle() == 0) ;
    
        I2C_Stop();
       }

  7. #6
    invite5637435c

    Re : ds1307 algorithme

    Un exemple d'utilisation dans un prog fonctionnel:

    horloge_LCD.c

    Code:
    // horloge_LCD.c
    // Ecrit pour PIC18F8722 par HULK28
    
    
    #include "RTC_DS1307.h"
    #include "Config.h"
    
    
    //*** définition des textes à afficher (stockés en ROM)
    
    //*  LCD 4x20       "12345678901234567890"
    
    
    const char *text1 = "Initialisation";        //14 caractères
    const char *text2 = "En cours....";          //11 caractères
    
    const char *Date = "Date:    /  /";					 //13 caractères
    const char *Time = "Heure:   :  :";					 //13 caractères
    
    const char *LCDmenu1 = "Reglage heures:";
    const char *LCDmenu2 = "Reglage minutes:";
    const char *LCDmenu3 = "Reglage secondes:";
    const char *LCDmenu4 = "Reglage date:";
    const char *LCDmenu5 = "Reglage mois:";
    const char *LCDmenu6 = "Reglage année:";
    
    
    //==============================================================================
    //                           Initialisation du PIC
    //==============================================================================
    
    void init_pic()
    {
    //Port A mesure des tensions analogiques
    
    ADCON1 = 0b00000110; //AN0~AN8 mes.An, autres digital A/D, Vref+(Vcc)/Vref-(Gnd)
    PORTA = 0XFF;
    TRISA = 0b11111111;  // RA0-RA7 en entrée.
    
    //Port B
    
    
    //Port C
    PORTC = 0x80; //1000 0000 :b7 entrée cavalier S1 à 1 par défaut.
    TRISC = 0x80; //Le port C en sortie sauf c7 en entrée.
    
    //Port D
    
    //Port E
    
    //Port F
    
    //Port G
    
    //Port H
    
    //Port J
    I2C_Init(100000);  // fréquence de travail du bus I2C=100KHz
    }
    
    //==============================================================================
    //          Fonction de transfert d'un texte en ROM -> RAM
    //==============================================================================
    
    void StrConstCpy(char row, char col, const char *source)
    
    {
    char *dest;
    char buf[21]; // buffer contient la taille maximum du texte source + 1 (LCD 2x20 donc 21 max)
    
    dest = buf;
    while(*source)
    *dest++=*source++;
    *dest=0;
    lcd8_Out(row,col,buf);
    }
    
    //==============================================================================
    //               Fonction d'écriture du masque date et time sur le LCD         
    //==============================================================================
    void Static_LCD_text(void)
    {
     strConstCpy(1,1,Date);
     strConstCpy(2,1,Time);
    
    }
    
    void affichage_accueil(void) // 
    {
      Lcd8_Config(&PORTJ,&PORTE,2,4,3,7,6,5,4,3,2,1,0);
      Lcd8_Cmd(LCD_CURSOR_OFF);    // curseur désactivé
      StrConstCpy(1,2,text1);
      Delay_ms(500);  // Tempo d'affichage entre la ligne 1 et 2
      StrConstCpy(2,2,text2);
      Delay_ms(500);  // Tempo d'affichage entre la ligne 1 et 2
      
    }
    
    //==============================================================================
    //               convertit un nombre hexadecimal en ascii
    //==============================================================================
    unsigned char
    hexa2ascii(unsigned char tmp)
    {
    	tmp += 0x30;
    	if (tmp>0x39) tmp+=7;
    	return tmp;
    }
    
    
    // Programme principal
    
    void main()
    {
      init_pic();
      Delay_ms(100);
      affichage_accueil();
      Delay_ms(1500);
      Lcd8_Cmd(LCD_CLEAR);
      Static_LCD_text();
      RTC_Initial_values();
      ds1307_write(0x07, 0b10010000);    // écriture des paramètres pour le registre de contrôle
         while(1)
          {
          Read_DS1307();
          PORTC.F1 = ~ PORTC.F1; // toggle sur une led pour vérifier le passage dans la boucle
          Delay_ms(300);
          }
    }
    Ce code est facilement adaptable pour un PIC16F87x, la bibliothèque RTC_DS1307.h sera inchangée.
    Il te suffit d'implanter des fonctions permettant de modifier les contenus des registres par des boutons poussoirs par exemple (SET, UP, DOWN).
    Amuse toi bien.
    @+

Discussions similaires

  1. Horloge ds1307
    Par inviteb5437249 dans le forum Électronique
    Réponses: 44
    Dernier message: 24/05/2011, 08h51
  2. Carte PIC meteo avec ds1307
    Par invite47dfc8ff dans le forum Électronique
    Réponses: 8
    Dernier message: 13/03/2010, 12h20
  3. DS1307 sur station meteo
    Par invited0101505 dans le forum Électronique
    Réponses: 21
    Dernier message: 09/11/2008, 21h24
  4. rôle d'une LED avec l'horloge DS1307
    Par inviteb5437249 dans le forum Électronique
    Réponses: 5
    Dernier message: 05/03/2007, 09h52
  5. Ds1307
    Par invite369c4784 dans le forum Électronique
    Réponses: 2
    Dernier message: 11/02/2007, 21h18
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...