Horloge DS1307
Répondre à la discussion
Affichage des résultats 1 à 21 sur 21

Horloge DS1307



  1. #1
    invite67c9851b

    Horloge DS1307


    ------

    Bonjour,

    je sollicite votre aide pour un problème sur lequel je planche depuis plusieurs semaines.

    Je réalise un programmateur pour gérer un aquarium et j'ai un souci sur l'affichage de la date et de l'heure récupérer sur un DS1307.

    Le programme ci dessous est écrit en Mikropascal. la compilation n'indique pas d'erreur. pourtant, lors de la simulation sur ISIS, le LCD, je n'affiche que des 0.
    Après beaucoup de recherche, je pense qu'il y a un problème sur l'initialisation du bus I2C.

    Le schéma du montage est en pièce jointe.

    quelqu'un a-t-il une idée lumineuse sur le sujet?

    Merci pour votre aide.

    program ds_1307;

    var
    seconds, minutes, hours: byte;
    day, date, month, year: byte;
    i:byte;
    compteur : byte;
    text1 : ARRAY[8] of char;

    procedure Time_Read;
    begin
    I2C_Stop;
    delay_ms(50);
    I2C_Start; // start signal
    I2C_Wr(%11010000); // Address DS1307, see DS1307 datasheet
    I2C_Wr(0); // Start from address 0
    I2C_Repeated_Start; // repeated start signal
    I2C_Wr(%11010001); // Address DS1307 for reading R/W=1
    seconds := I2C_Rd(1); // Read seconds byte
    while (I2C_Is_Idle() = 0) do nop;
    minutes := I2C_Rd(1); // Read minutes byte
    while (I2C_Is_Idle() = 0) do nop;
    hours := I2C_Rd(1); // Read hours byte
    while (I2C_Is_Idle() = 0) do nop;
    day := I2C_Rd(1); // Read day byte
    while (I2C_Is_Idle() = 0) do nop;
    date := I2C_Rd(1); // Read date byte
    while (I2C_Is_Idle() = 0) do nop;
    month := I2C_Rd(1); // Read weekday/month byte
    while (I2C_Is_Idle() = 0) do nop;
    year := I2C_Rd(1); // Read year byte
    while (I2C_Is_Idle() = 0) do nop;

    for i:= 1 to 56 do //lire la RAM (vide)
    I2C_Rd(1);

    I2C_Rd(0);

    while (I2C_Is_Idle() = 0) do nop;
    I2C_Stop; // Issue stop signal

    compteur := compteur + 1;
    ByteToStr(compteur,text1);
    LCD_Out(1,15,text1);

    end;

    procedure Time_Decode;
    begin
    seconds := Bcd2Dec((seconds and 0xF0) shr 4) * 10 + Bcd2Dec(seconds and 0x0F);
    minutes := Bcd2Dec((minutes and 0xF0) shr 4) * 10 + Bcd2Dec(minutes and 0x0F);
    hours := Bcd2Dec((hours and 0xF0) shr 4) * 10 + Bcd2Dec(hours and 0x0F);
    year := Bcd2Dec((year and 0xF0) shr 4) * 10 + Bcd2Dec(year and 0x0F);
    date := Bcd2Dec((date and 0x30) shr 4) * 10 + Bcd2Dec(date and 0x0F);
    month := Bcd2Dec((month and 0x10) shr 4) * 10 + Bcd2Dec(month and 0x0F);
    end;

    procedure Time_Display_LCD;
    var
    day_t, day_o, month_t, month_o, year_t, year_o : char;
    sec_t, sec_o, min_t, min_o, hour_t, hour_o : char;

    begin

    day_t := (day / 10) + 48;
    day_o := (day mod 10) + 48;
    month_t := (month / 10) + 48;
    month_o := (month mod 10) + 48;
    year_t := (year / 10) + 48;
    year_o := (year mod 10) + 48;
    sec_t := (seconds / 10) + 48;
    sec_o := (seconds mod 10) + 48;
    min_t := (minutes / 10) + 48;
    min_o := (minutes mod 10) + 48;
    hour_t := (hours / 10) + 48;
    hour_o := (hours mod 10) + 48;


    Lcd_Chr(1, 7, day_t);
    Lcd_Chr(1, 8, day_o);
    Lcd_Chr(1, 10, month_t);
    Lcd_Chr(1, 11, month_o);
    Lcd_Chr(1, 13, year_t);
    Lcd_Chr(1, 14, year_o);
    Lcd_Chr(2, 7, hour_t);
    Lcd_Chr(2, 8, hour_o);
    Lcd_Chr(2, 10, min_t);
    Lcd_Chr(2, 11, min_o);
    Lcd_Chr(2, 13, sec_t);
    Lcd_Chr(2, 14, sec_o);
    end;

    //----------------- Main procedure
    begin

    PORTC := %00011000;
    TRISC := %00011000;
    // I2C comm init
    I2C_Init(100000);

    Lcd_Init(PORTD); // Initialize LCD
    Lcd_Cmd(LCD_CLEAR); // Clear LCD display
    Lcd_Cmd(LCD_CURSOR_OFF); // Turn cursor off
    LCD_Out(1,1,'Date:'); // Prepare and output static text on LCD
    LCD_Chr(1,9,'/');
    LCD_Chr(1,12,'/');
    LCD_Out(2,1,'Time:');
    LCD_Chr(2,9,':');
    LCD_Chr(2,12,':');
    Delay_ms(500);
    compteur :=0;

    while true do
    begin
    Time_Read; // Read time from RTC (DS1307)
    Time_Decode; // Decode (format) date and time
    Time_Display_LCD; // Display on LCD
    delay_ms(500);
    end;
    end.

    -----
    Images attachées Images attachées  

  2. #2
    invite67c9851b

    Re : Horloge DS1307

    Bonjour,

    Le code ci-dessous fonctionne, le problème principal venait de ISIS et des deux résistances pull-up du bus I2C. Sous ISIS, il y a une option pour les faires fonctionner en mode analogique au lieu de digital.


    program ds_1307;

    var
    seconds, minutes, hours: byte;
    day, month, year: byte;
    i:byte;

    procedure Time_Read;
    begin
    I2C_Stop;
    delay_ms(50);
    I2C_Start; // start signal
    I2C_Wr(%11010000); // Address DS1307, see DS1307 datasheet
    I2C_Wr(0); // Start from address 0
    I2C_Repeated_Start; // repeated start signal
    I2C_Wr(%11010001); // Address DS1307 for reading R/W=1
    seconds := I2C_Rd(1); // Read seconds byte
    while (I2C_Is_Idle() = 0) do nop;
    minutes := I2C_Rd(1); // Read minutes byte
    while (I2C_Is_Idle() = 0) do nop;
    hours := I2C_Rd(1); // Read hours byte
    while (I2C_Is_Idle() = 0) do nop;
    I2C_Rd(1); // Non utilisé jour de la semaine
    while (I2C_Is_Idle() = 0) do nop;
    day := I2C_Rd(1); // Read date byte
    while (I2C_Is_Idle() = 0) do nop;
    month := I2C_Rd(1); // Read weekday/month byte
    while (I2C_Is_Idle() = 0) do nop;
    year := I2C_Rd(1); // Read year byte
    while (I2C_Is_Idle() = 0) do nop;

    for i:= 1 to 56 do //lire la RAM (vide)
    I2C_Rd(1);

    I2C_Rd(0);

    while (I2C_Is_Idle() = 0) do nop;
    I2C_Stop; // Issue stop signal

    end;

    procedure Time_Decode;
    begin
    seconds := ((seconds and 0xF0) shr 4) * 10 + (seconds and 0x0F);
    minutes := ((minutes and 0xF0) shr 4) * 10 + (minutes and 0x0F);
    hours := ((hours and 0xF0) shr 4) * 10 + (hours and 0x0F);
    year := ((year and 0xF0) shr 4) * 10 + (year and 0x0F);
    day := ((day and 0x30) shr 4) * 10 + (day and 0x0F);
    month := ((month and 0x10) shr 4) * 10 + (month and 0x0F);
    end;

    procedure Time_Display_LCD;
    var
    day_t, day_o, month_t, month_o, year_t, year_o : char;
    sec_t, sec_o, min_t, min_o, hour_t, hour_o : char;

    begin

    day_t := (day / 10) + 48;
    day_o := (day mod 10) + 48;
    month_t := (month / 10) + 48;
    month_o := (month mod 10) + 48;
    year_t := (year / 10) + 48;
    year_o := (year mod 10) + 48;
    sec_t := (seconds / 10) + 48;
    sec_o := (seconds mod 10) + 48;
    min_t := (minutes / 10) + 48;
    min_o := (minutes mod 10) + 48;
    hour_t := (hours / 10) + 48;
    hour_o := (hours mod 10) + 48;


    Lcd_Chr(1, 1, day_t);
    Lcd_Chr(1, 2, day_o);
    Lcd_Chr(1, 4, month_t);
    Lcd_Chr(1, 5, month_o);
    Lcd_Chr(1, 7, year_t);
    Lcd_Chr(1, 8, year_o);
    Lcd_Chr(2, 1, hour_t);
    Lcd_Chr(2, 2, hour_o);
    Lcd_Chr(2, 4, min_t);
    Lcd_Chr(2, 5, min_o);
    Lcd_Chr(2, 7, sec_t);
    Lcd_Chr(2, 8, sec_o);
    end;

    //----------------- Main procedure
    begin

    PORTC := %00011000;
    TRISC := %00011000;
    // I2C comm init
    I2C_Init(100000);

    Lcd_Init(PORTD); // Initialize LCD
    Lcd_Cmd(LCD_CLEAR); // Clear LCD display
    Lcd_Cmd(LCD_CURSOR_OFF); // Turn cursor off
    LCD_Chr(1,3,'/');
    LCD_Chr(1,6,'/');
    LCD_Chr(2,3,':');
    LCD_Chr(2,6,':');
    Delay_ms(500);

    while true do
    begin
    Time_Read; // Read time from RTC (DS1307)
    Time_Decode; // Decode (format) date and time
    Time_Display_LCD; // Display on LCD
    delay_ms(500);
    end;
    end.

  3. #3
    Gérard

    Re : Horloge DS1307

    Maintenant, il faut passer à la vraie vie.
    Câblage et essais.

  4. #4
    invite7a49d0d5

    Cool Re : Horloge DS1307

    Citation Envoyé par graindemais Voir le message
    Bonjour,
    Le code ci-dessous fonctionne, (...)
    Bonjour,

    moi ça m'étonnerais beaucoup qu'il fonctionne,
    car je ne vois pas dans le code la mise à 1 du
    bit de démarrage de l'horloge...(bit 7 adresse 00, nommé CH)

    donc l'horloge "n'avance" pas et reste sur 000000...

    et après chaque dés-alimentation, il faut re-positionner CH sur 1...
    pour faire "re-démarrer" l'horloge...

    en fait, à chaque premier accès/première lecture de l'heure,
    il faut commencer par vérifier ce bit CH, pour vérifier que
    l'horloge ne s'est pas arrêtée...

    vede
    ;O]
    ________________________
    Vive les PICS ;O]

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

    Re : Horloge DS1307

    C'est vrai que sur ISIS, le DS1307 se synchronise sur l'horloge du PC et se lance automatiquement.
    Je garde cela en mémoire pour les premier test. mais d'après la Datasheet du DS1307, le bit de démarrage doit être à 0 pour lancer l'horloge.

    Merci pour cette info.

  7. #6
    invite7a49d0d5

    Cool Re : Horloge DS1307

    re ;O]

    en effet, il faut le "mettre" à 0 pour démarrer l'horloge...
    (et il est à 1 "par défaut", et il se re-met à 1 dés que dés-alimenté...)...

  8. #7
    invite7a49d0d5

    Cool Résolu (pour l'instant ;O])

    Bon'Dimanche za toutes zé tous ;O]

    vede
    ;O]
    ___________________________
    VIVE les PICS ;O]

  9. #8
    invite67c9851b

    Re : Horloge DS1307

    Bonjour,

    Je reviens après quelques jours.
    Le programme de base fonctionne, et j'ai voulu ajouter une fonction pour l'affichage de la température à partir d'un DS18B20.

    Le programme pour afficher la température fonctionne, pourtant quand j'assemble les deux programmes, le système se bloque lors de l'affichage.
    En simulation sous ISIS, j'ai un message "[PIC16 CORE] PC=0x006. Stack underflow executing RETURN instruction".

    je peux lancer soit "DS18B20_temperature_Read" soit "DS1307_Time_Read;" mais pas les deux en même temps.
    Je pense à un problème de tempo sur l'affichage?
    Code:
    //************************************************
    program Programm_DS1307_DS18B20;
    
    var
      seconds, minutes, hours: byte;
      day, month, year: byte;
      i, j1, j2  : byte;
      text       : ARRAY[12] of char;
      RawTemp    : Word;
      Positive   : Boolean;
    
    const
    //PCFG3:PCFG0-RE2-RE1-RE0-RA5-RA3-RA2-RA1-RA0
    //   011x      D   D   D   D   D   D   D   D
      Conf_port = %10000110;         // configure RA et RE pin as digital I/O
    //******************************************************************************
    //lire l'heure du DS1307
    //******************************************************************************
    procedure DS1307_Time_Read;
    var
      day_t, day_o, month_t, month_o, year_t, year_o : char;
      sec_t, sec_o, min_t, min_o, hour_t, hour_o : char;
    
    begin
      I2C_Stop;
      delay_ms(50);
      I2C_Start;              // start signal
      I2C_Wr(%11010000);      // Address DS1307, see DS1307 datasheet
      I2C_Wr(0);              // Start from address 0
      I2C_Repeated_Start;     // repeated start signal
      I2C_Wr(%11010001);      // Address DS1307 for reading R/W=1
      seconds := I2C_Rd(1);   // Read seconds byte
      while (I2C_Is_Idle() = 0) do  nop;
      minutes := I2C_Rd(1);   // Read minutes byte
      while (I2C_Is_Idle() = 0) do  nop;
      hours := I2C_Rd(1);     // Read hours byte
      while (I2C_Is_Idle() = 0) do  nop;
      I2C_Rd(1);              // Non utilisé jour de la semaine
      while (I2C_Is_Idle() = 0) do  nop;
      day := I2C_Rd(1);      // Read date byte
      while (I2C_Is_Idle() = 0) do  nop;
      month := I2C_Rd(1);     // Read weekday/month byte
      while (I2C_Is_Idle() = 0) do  nop;
      year := I2C_Rd(1);      // Read year byte
      while (I2C_Is_Idle() = 0) do  nop;
    
      for i:= 1 to 56 do      //lire la RAM (vide)
      I2C_Rd(1);
    
      I2C_Rd(0);
    
      while (I2C_Is_Idle() = 0) do  nop;
      I2C_Stop;               // Issue stop signal
    
    //******************************************************************************
    //decode l'heure avant affichage
    //******************************************************************************
    
      seconds := ((seconds and 0xF0) shr 4) * 10 + (seconds and 0x0F);
      minutes := ((minutes and 0xF0) shr 4) * 10 + (minutes and 0x0F);
      hours := ((hours and 0xF0)  shr 4) * 10 + (hours and 0x0F);
      year := ((year and 0xF0) shr 4) * 10 + (year and 0x0F);
      day := ((day and 0x30) shr 4) * 10 + (day and 0x0F);
      month := ((month and 0x10) shr 4) * 10 + (month and 0x0F);
    
    //******************************************************************************
    //affichage de l'heure sur l'ecran LCD
    //******************************************************************************
    
      day_t := (day / 10) + 48;
      day_o := (day mod 10) + 48;
      month_t := (month / 10) + 48;
      month_o := (month mod 10) + 48;
      year_t := (year / 10) + 48;
      year_o := (year mod 10) + 48;
      sec_t := (seconds / 10) + 48;
      sec_o := (seconds mod 10) + 48;
      min_t := (minutes / 10) + 48;
      min_o := (minutes mod 10) + 48;
      hour_t := (hours / 10) + 48;
      hour_o := (hours mod 10) + 48;
    
    
      Lcd_Chr(1, 1, day_t);
      Lcd_Chr(1, 2, day_o);
      Lcd_Chr(1, 4, month_t);
      Lcd_Chr(1, 5, month_o);
      Lcd_Chr(1, 7, year_t);
      Lcd_Chr(1, 8, year_o);
      Lcd_Chr(2, 1, hour_t);
      Lcd_Chr(2, 2, hour_o);
      Lcd_Chr(2, 4, min_t);
      Lcd_Chr(2, 5, min_o);
    
    end;
    //******************************************************************************
    //initialyse la sonde de temperature du DS18B20 a 12 bit
    //******************************************************************************
    Procedure DS18B20_Initialize;     //setup DS18B20 and others
    Begin
      { $4E Write to RAM dummy $FF to TH & TL, $7F to ctrl reg for 12-bit}
       ow_reset(PORTA,0);                    // onewire reset signal
       ow_write(PORTA,0,$CC);                // issue command to DS1820
       ow_write(PORTA,0,$4E);                // issue command to DS1820
       ow_write(PORTA,0,$FF);                // issue command to DS1820
       ow_write(PORTA,0,$FF);                // issue command to DS1820
       ow_write(PORTA,0,$7F);                // Set for 12 bit output
    End;
    //******************************************************************************
    //convertir la temperature du DS18B20
    //******************************************************************************
    Procedure DS18B20_AddDecimal(Var Str : String[12]);    {adds decimal point }
    
    Begin
       {shift the string one place to the left to make room for decimal point}
       For i := 0 to (Length(Str)-2) Do
       Begin
          str[i] := str[i+1]
       End;
       Str[Length(str)-2] := '.';
    End;
    //******************************************************************************
    //lecture de la temperature du DS18B20
    //******************************************************************************
    Procedure DS18B20_temperature_Read;
    
    begin
           ow_reset(PORTA,0);                    // onewire reset signal
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$44);
                                                 // start temperature conversion
           j1 := 0;
            Repeat                               // end of conversion cycle is
              j1 := ow_read(PortA,0);           // indicated by a non-zero
           Until j1 > 0;                        // output to polling
    
           ow_reset(PORTA,0);                    // at this point temp is in memory
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$BE);                // read scratchpad memory
    
           j1 := ow_read(PORTA,0);               // get Low Byte result
           j2 := ow_read(PORTA,0);               // get High byte resujlt
    
           RawTemp := j2;                        // Raw now holds the 16-bit
           RawTemp := RawTemp shl 8;             // output, with sign bit and
           RawTemp := RawTemp + j1;              // maximum resolution information
                                                 // result in units of 0.0625 deg C
           Positive := True;
           If RawTemp.15 = %1 Then               // is temp < 0C?
           Begin
              Positive := False;
              RawTemp := $0000-RawTemp;          // 2's complement fix up for < 0C
           End;
    
           RawTemp := (10 * RawTemp);         // muultiply by 10 &
           RawTemp := RawTemp shr 4;          // divide by 16 to get degrees x 10
    
           WordToStr(RawTemp,text);
           DS18B20_AddDecimal(text);
           If Positive Then
              lcd_chr(2,9,'+')                // add + or - sign. Will not be
              ELSE                            // properly aligned due to leading
              lcd_chr(2,9,'-');               // spaces that should be removed
    
           lcd_out(2,10,text);
    
           lcd_chr(2,15,223);                 // #176 'degree' character for Windows
           lcd_chr(2,16,'C');                  // not #223. #67 = C
    
           Delay_ms(500);
    
    end;
    //******************************************************************************
    //Programme principal
    //******************************************************************************
    begin
    
    INTCON := 0;                        //supprimer toutes les interruptions
    
    adcon1 := Conf_port;                // configure RA0 pin as digital I/O
    PORTA  := 255;                      // initialize porte to 255
    TRISA  := 255;                      // designate porte as input
    PORTC := %00011000;
    TRISC := %00011000;
    
    I2C_Init(100000);                   //initialiser I2C à 100KHz
    
    Lcd_Init(PORTD);          // Initialize LCD
    Lcd_Cmd(LCD_CLEAR);       // Clear LCD display
    Lcd_Cmd(LCD_CURSOR_OFF);  // Turn cursor off
    LCD_Chr(1,3,'/');
    LCD_Chr(1,6,'/');
    LCD_Chr(2,3,':');
    Delay_ms(500);
    
    DS18B20_Initialize;
    
    while true do
    begin
    
        DS18B20_temperature_Read;
        DS1307_Time_Read;        
        delay_ms(500);
    
    end;
    
    end.
    //**************************************************
    Merci pour votre aide.
    et bon dimanche.
    Dernière modification par Jack ; 08/05/2010 à 10h23.

  10. #9
    Jack
    Modérateur

    Re : Horloge DS1307

    C'est tout de même plus lisible avec les balises "code", non?

    A+

  11. #10
    invite67c9851b

    Re : Horloge DS1307

    Merci, C'est TOP.
    Je ferais attention la prochaine fois.

  12. #11
    Jack
    Modérateur

    Re : Horloge DS1307

    petit graindemais deviendra grand ...

  13. #12
    RISC

    Re : Horloge DS1307

    Salut,

    Un message de type Stack underflow c'est très violent (plantage assuré du micro...).
    Cela signifie que tu as un problème avec la pile qui peut venir de :
    1/ le compilateur trouve un "return" (begin) alors qu'il n'y a pas eu de call (end)
    2/ un saut sauvage de type "goto" à une procédure (ou equivalent en pascal) au lieu d'avoir fait un call
    3/ une erreur dans les parametres passes dans la pile
    4/ une restauration de la pile superieure à ce que l'on avait empilé (exemple PUSH, PUSH et à la fin de la routine ou de l'interruption POP, POP, POP
    5/ un CALL à une routine d'interruption

    Il y a d'autres raisons mais tu as de très fortes chances que ton PB viennent d'une des raisons ci-dessus

    a+

  14. #13
    invite005518f8

    Re : Horloge DS1307

    Bonjour

    Mais ton programme n’est pas complet, comment tu fais la mise a l’heure ou
    l’initialisation du ds1307 ?

    je bloque dessus et moi je suis sur picbasic pro, moi je veux utiliser un terminal
    et envoyer une trame sur la rs232.
    du style :

    ' COMHssmmhhDJJMMAA
    ' D = Day
    ' sauf erreur dimanche = 1, lundi = 2, .... samedi = 7
    ' exemple : COMH 0204075060510 07h04m02 jeudi 06/05/2010

    Car il faut faire la conversion décimale/bcd .

    A+

  15. #14
    invite67c9851b

    Re : Horloge DS1307

    Bonsoir,

    Pour l'instant, le programme est en cours d'assemblage. j'ai une routine pour mettre à jour l'heure à partir du PC par liaison RS232 mais je ne l'ai pas intégrer car j'ai juste une liaison parallèle sur le PC. je regarderai plus tard.
    Lors de la simulation sur ISIS, l'heure se synchronise directement sur horloge du PC.

    Tu peux regarder le post suivant http://forums.futura-sciences.com/pr...pilote-17.html, il y a plein d'idées à prendre.

    Bonne soirée.

  16. #15
    invite005518f8

    Re : Horloge DS1307

    salut

    Bon courage

    A+

  17. #16
    invite67c9851b

    Re : Horloge DS1307

    Bonsoir,

    Je n'ai toujours pas trouver la solution...

    mais sur le site suivant, peut-etre un début de réponse :

    http://www.sixca.com/eng/articles/clock/

    apparemment, il faut activer ou désactiver la gestion des interruption suivant que l'on va lire ou écrire sur le bus I2C ou onewire.


    Code:
       enable_interrupts(INT_EXT);
       enable_interrupts(GLOBAL);
    
       while(true)
       {
          disable_interrupts(INT_EXT);
          if (fs_flag==0)
          {
             show_temp();            //lecture temperature DS1820 (onewire)
          }
          enable_interrupts(INT_EXT);
          for (u=0;u<20;u++)
          {
             show_time(fs_flag);  //lecture DS1307 (I2C)
          }
    
       }

    Ce code est en C pour le Compiler : CCS V 3.222

    Quelqu'un connait-il les fonctions :

    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);
    disable_interrupts(INT_EXT);

    en Mikropascal V3.0.

    Merci pour votre aide.

  18. #17
    invite67c9851b

    Re : Horloge DS1307

    Bonjour,

    Je poste ici deux codes :

    Mikropascal 3.0.0.4 :

    Code:
    program Automate_Aquarium_Lowcost;
    
    var
      seconds, minutes, hours: byte;
      day,Wday, month, year: byte;
      i, j1, j2  : byte;
      text       : ARRAY[5] of char;
      RawTemp    : Word;
      Positive   : Boolean;
    
    //******************************************************************************
    //lire l'heure du DS1307
    //******************************************************************************
    procedure DS1307_Time_Read;
    var
      day_t, day_o, month_t, month_o, year_t, year_o : char;
      sec_t, sec_o, min_t, min_o, hour_t, hour_o : char;
    
    begin
      I2C_Stop;
      delay_ms(50);
      I2C_Start;              // start signal
      I2C_Wr(%11010000);      // Address DS1307, see DS1307 datasheet
      I2C_Wr(0);              // Start from address 0
      I2C_Repeated_Start;     // repeated start signal
      I2C_Wr(%11010001);      // Address DS1307 for reading R/W=1
      seconds := I2C_Rd(1);   // Read seconds byte
      while (I2C_Is_Idle() = 0) do  nop;
      minutes := I2C_Rd(1);   // Read minutes byte
      while (I2C_Is_Idle() = 0) do  nop;
      hours := I2C_Rd(1);     // Read hours byte
      while (I2C_Is_Idle() = 0) do  nop;
      Wday :=I2C_Rd(1);       // Read Day of week
      while (I2C_Is_Idle() = 0) do  nop;
      day := I2C_Rd(1);      // Read date byte
      while (I2C_Is_Idle() = 0) do  nop;
      month := I2C_Rd(1);     // Read weekday/month byte
      while (I2C_Is_Idle() = 0) do  nop;
      year := I2C_Rd(1);      // Read year byte
      while (I2C_Is_Idle() = 0) do  nop;
    
      for i:= 1 to 56 do      //lire la RAM (vide)
      I2C_Rd(1);
    
      I2C_Rd(0);
    
      while (I2C_Is_Idle() = 0) do  nop;
      I2C_Stop;               // Issue stop signal
    
    //******************************************************************************
    //decode l'heure avant affichage
    //******************************************************************************
    
      seconds := ((seconds and 0xF0) shr 4) * 10 + (seconds and 0x0F);
      minutes := ((minutes and 0xF0) shr 4) * 10 + (minutes and 0x0F);
      hours := ((hours and 0xF0)  shr 4) * 10 + (hours and 0x0F);
      Wday :=(Wday and 0x07);
      year := ((year and 0xF0) shr 4) * 10 + (year and 0x0F);
      day := ((day and 0x30) shr 4) * 10 + (day and 0x0F);
      month := ((month and 0x10) shr 4) * 10 + (month and 0x0F);
    
    //******************************************************************************
    //affichage de l'heure sur l'ecran LCD
    //******************************************************************************
    
      day_t := (day / 10) + 48;
      day_o := (day mod 10) + 48;
      month_t := (month / 10) + 48;
      month_o := (month mod 10) + 48;
      year_t := (year / 10) + 48;
      year_o := (year mod 10) + 48;
      sec_t := (seconds / 10) + 48;
      sec_o := (seconds mod 10) + 48;
      min_t := (minutes / 10) + 48;
      min_o := (minutes mod 10) + 48;
      hour_t := (hours / 10) + 48;
      hour_o := (hours mod 10) + 48;
    
      case Wday of
      1: Lcd_out(1,10,'DIMAN');
      2: Lcd_out(1,10,'LUNDI');
      3: Lcd_out(1,10,'MARDI');
      4: Lcd_out(1,10,'MERCR');
      5: Lcd_out(1,10,'JEUDI');
      6: Lcd_out(1,10,'VENDR');
      7: Lcd_out(1,10,'SAMED');
      end;
    
    
      Lcd_Chr(1, 1, day_t);
      Lcd_Chr(1, 2, day_o);
      Lcd_Chr(1,3,'/');
      Lcd_Chr(1, 4, month_t);
      Lcd_Chr(1, 5, month_o);
      Lcd_Chr(1,6,'/');
      Lcd_Chr(1, 7, year_t);
      Lcd_Chr(1, 8, year_o);
      Lcd_Chr(2, 1, hour_t);
      Lcd_Chr(2, 2, hour_o);
      Lcd_Chr(2,3,':');
      Lcd_Chr(2, 4, min_t);
      Lcd_Chr(2, 5, min_o);
      Lcd_Chr(2,6,':');
      Lcd_Chr(2, 7, sec_t);
      Lcd_Chr(2, 8, sec_o);
    
    end;
    //******************************************************************************
    //convertir la temperature du DS18B20
    //******************************************************************************
    Procedure DS18B20_AddDecimal(Var Str : String[12]);    {adds decimal point }
    
    Begin
       {shift the string one place to the left to make room for decimal point}
       For i := 0 to (Length(Str)-2) Do
       Begin
          str[i] := str[i+1]
       End;
       Str[Length(str)-2] := '.';
    End;
    //******************************************************************************
    //lecture de la temperature du DS18B20
    //******************************************************************************
    Procedure DS18B20_temperature_Read;
    
    begin
           //initialize
           ow_reset(PORTA,0);                    // onewire reset signal
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$4E);                // issue command to DS1820
           ow_write(PORTA,0,$FF);                // issue command to DS1820
           ow_write(PORTA,0,$FF);                // issue command to DS1820
           ow_write(PORTA,0,$7F);                // Set for 12 bit output
           //read temp
           ow_reset(PORTA,0);                    // onewire reset signal
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$44);
                                                 // start temperature conversion
           j1 := 0;
            Repeat                               // end of conversion cycle is
              j1 := ow_read(PortA,0);           // indicated by a non-zero
           Until j1 > 0;                        // output to polling
    
           ow_reset(PORTA,0);                    // at this point temp is in memory
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$BE);                // read scratchpad memory
    
           j1 := ow_read(PORTA,0);               // get Low Byte result
           j2 := ow_read(PORTA,0);               // get High byte resujlt
    
           RawTemp := j2;                        // Raw now holds the 16-bit
           RawTemp := RawTemp shl 8;             // output, with sign bit and
           RawTemp := RawTemp + j1;              // maximum resolution information
                                                 // result in units of 0.0625 deg C
           Positive := True;
           If RawTemp.15 = %1 Then               // is temp < 0C?
           Begin
              Positive := False;
              RawTemp := $0000-RawTemp;          // 2's complement fix up for < 0C
           End;
    
           RawTemp := (10 * RawTemp);         // muultiply by 10 &
           RawTemp := RawTemp shr 4;          // divide by 16 to get degrees x 10
    
           WordToStr(RawTemp,text);
           DS18B20_AddDecimal(text);
           If Positive Then
              lcd_chr(2,9,'+')                // add + or - sign. Will not be
              ELSE                            // properly aligned due to leading
              lcd_chr(2,9,'-');               // spaces that should be removed
    
           lcd_out(2,10,text);
    
           lcd_chr(2,15,223);                 // #176 'degree' character for Windows
           lcd_chr(2,16,'C');                  // not #223. #67 = C
    
           Delay_ms(200);
    
    end;
    //******************************************************************************
    //Programme principal
    //******************************************************************************
    begin
    
    //PCFG3:PCFG0-RE2-RE1-RE0-RA5-RA3-RA2-RA1-RA0
    //   011x      D   D   D   D   D   D   D   D
    ADCON1 := %10000110;         // configure RA et RE pin as digital I/O
    
    PORTA  := 1;                         // initialize porte to 255
    PORTB  := 1;                         // initialize porte to 255
    PORTC  := 0;                         // initialize porte to 255
    PORTE  := 1;                         // initialize porte to 255
    TRISA  := 1;                         // designate porte as input
    TRISB  := 1;                         // designate porte as input
    TRISC  := 0;                         // designate porte as input
    TRISE  := 1;                         // designate porte as input
    
    Lcd_Init(PORTD);                    // Initialize LCD
    Lcd_Cmd(LCD_CLEAR);                 // Clear LCD display
    Lcd_Cmd(LCD_CURSOR_OFF);            // Turn cursor off
    Delay_ms(500);
    
    I2C_Init(100000);                   //initialiser I2C à 100KHz
    
    while true do
    begin
        DS18B20_temperature_Read;
        Delay_ms(500);
        DS1307_Time_Read;
        Delay_ms(500);
    end;
    
    end.
    A suivre...

  19. #18
    invite67c9851b

    Re : Horloge DS1307

    La suite :

    Mikropascal pro 3.20 (version évaluation)

    Code:
    program Automate_Aquarium_Lowcost;
    
    var
      seconds, minutes, hours: byte;
      day,Wday, month, year: byte;
      i, j1, j2  : byte;
      text       : ARRAY[5] of char;
      RawTemp    : Word;
      Positive   : Boolean;
    // Lcd module connections
    var LCD_RS : sbit at RD2_bit;
    var LCD_EN : sbit at RD3_bit;
    var LCD_D4 : sbit at RD4_bit;
    var LCD_D5 : sbit at RD5_bit;
    var LCD_D6 : sbit at RD6_bit;
    var LCD_D7 : sbit at RD7_bit;
    
    var LCD_RS_Direction : sbit at TRISD2_bit;
    var LCD_EN_Direction : sbit at TRISD3_bit;
    var LCD_D4_Direction : sbit at TRISD4_bit;
    var LCD_D5_Direction : sbit at TRISD5_bit;
    var LCD_D6_Direction : sbit at TRISD6_bit;
    var LCD_D7_Direction : sbit at TRISD7_bit;
    // End Lcd module connections
    //******************************************************************************
    //lire l'heure du DS1307
    //******************************************************************************
    procedure DS1307_Time_Read;
    var
      day_t, day_o, month_t, month_o, year_t, year_o : char;
      sec_t, sec_o, min_t, min_o, hour_t, hour_o : char;
    
    begin
      I2C1_Stop;
      delay_ms(50);
      I2C1_Start;              // start signal
      I2C1_Wr(%11010000);      // Address DS1307, see DS1307 datasheet
      I2C1_Wr(0);              // Start from address 0
      I2C1_Repeated_Start;     // repeated start signal
      I2C1_Wr(%11010001);      // Address DS1307 for reading R/W=1
      seconds := I2C1_Rd(1);   // Read seconds byte
      while (I2C1_Is_Idle() = 0) do  nop;
      minutes := I2C1_Rd(1);   // Read minutes byte
      while (I2C1_Is_Idle() = 0) do  nop;
      hours := I2C1_Rd(1);     // Read hours byte
      while (I2C1_Is_Idle() = 0) do  nop;
      Wday :=I2C1_Rd(1);       // Read Day of week
      while (I2C1_Is_Idle() = 0) do  nop;
      day := I2C1_Rd(1);      // Read date byte
      while (I2C1_Is_Idle() = 0) do  nop;
      month := I2C1_Rd(1);     // Read weekday/month byte
      while (I2C1_Is_Idle() = 0) do  nop;
      year := I2C1_Rd(1);      // Read year byte
      while (I2C1_Is_Idle() = 0) do  nop;
    
      for i:= 1 to 56 do      //lire la RAM (vide)
      I2C1_Rd(1);
    
      I2C1_Rd(0);
    
      while (I2C1_Is_Idle() = 0) do  nop;
      I2C1_Stop;               // Issue stop signal
    
    //******************************************************************************
    //decode l'heure avant affichage
    //******************************************************************************
    
      seconds := ((seconds and 0xF0) shr 4) * 10 + (seconds and 0x0F);
      minutes := ((minutes and 0xF0) shr 4) * 10 + (minutes and 0x0F);
      hours := ((hours and 0xF0)  shr 4) * 10 + (hours and 0x0F);
      Wday :=(Wday and 0x07);
      year := ((year and 0xF0) shr 4) * 10 + (year and 0x0F);
      day := ((day and 0x30) shr 4) * 10 + (day and 0x0F);
      month := ((month and 0x10) shr 4) * 10 + (month and 0x0F);
    
    //******************************************************************************
    //affichage de l'heure sur l'ecran LCD
    //******************************************************************************
    
      day_t := (day / 10) + 48;
      day_o := (day mod 10) + 48;
      month_t := (month / 10) + 48;
      month_o := (month mod 10) + 48;
      year_t := (year / 10) + 48;
      year_o := (year mod 10) + 48;
      sec_t := (seconds / 10) + 48;
      sec_o := (seconds mod 10) + 48;
      min_t := (minutes / 10) + 48;
      min_o := (minutes mod 10) + 48;
      hour_t := (hours / 10) + 48;
      hour_o := (hours mod 10) + 48;
    
      case Wday of
      1: Lcd_out(1,10,'DIMAN');
      2: Lcd_out(1,10,'LUNDI');
      3: Lcd_out(1,10,'MARDI');
      4: Lcd_out(1,10,'MERCR');
      5: Lcd_out(1,10,'JEUDI');
      6: Lcd_out(1,10,'VENDR');
      7: Lcd_out(1,10,'SAMED');
      end;
    
      Lcd_Chr(1, 1, day_t);
      Lcd_Chr(1, 2, day_o);
      Lcd_Chr(1,3,'/');
      Lcd_Chr(1, 4, month_t);
      Lcd_Chr(1, 5, month_o);
      Lcd_Chr(1,6,'/');
      Lcd_Chr(1, 7, year_t);
      Lcd_Chr(1, 8, year_o);
      Lcd_Chr(2, 1, hour_t);
      Lcd_Chr(2, 2, hour_o);
      Lcd_Chr(2,3,':');
      Lcd_Chr(2, 4, min_t);
      Lcd_Chr(2, 5, min_o);
      Lcd_Chr(2,6,':');
      Lcd_Chr(2, 7, sec_t);
      Lcd_Chr(2, 8, sec_o);
    
    end;
    //******************************************************************************
    //convertir la temperature du DS18B20
    //******************************************************************************
    Procedure DS18B20_AddDecimal(Var Str : String[12]);    {adds decimal point }
    
    Begin
       {shift the string one place to the left to make room for decimal point}
       For i := 0 to (Length(Str)-2) Do
       Begin
          str[i] := str[i+1]
       End;
       Str[Length(str)-2] := '.';
    End;
    //******************************************************************************
    //lecture de la temperature du DS18B20
    //******************************************************************************
    Procedure DS18B20_temperature_Read;
    
    begin
           //initialize
           ow_reset(PORTA,0);                    // onewire reset signal
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$4E);                // issue command to DS1820
           ow_write(PORTA,0,$FF);                // issue command to DS1820
           ow_write(PORTA,0,$FF);                // issue command to DS1820
           ow_write(PORTA,0,$7F);                // Set for 12 bit output
           //read temp
           ow_reset(PORTA,0);                    // onewire reset signal
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$44);
                                                 // start temperature conversion
           j1 := 0;
            Repeat                               // end of conversion cycle is
              j1 := ow_read(PortA,0);           // indicated by a non-zero
           Until j1 > 0;                        // output to polling
    
           ow_reset(PORTA,0);                    // at this point temp is in memory
           ow_write(PORTA,0,$CC);                // issue command to DS1820
           ow_write(PORTA,0,$BE);                // read scratchpad memory
    
           j1 := ow_read(PORTA,0);               // get Low Byte result
           j2 := ow_read(PORTA,0);               // get High byte resujlt
    
           RawTemp := j2;                        // Raw now holds the 16-bit
           RawTemp := RawTemp shl 8;             // output, with sign bit and
           RawTemp := RawTemp + j1;              // maximum resolution information
                                                 // result in units of 0.0625 deg C
           Positive := True;
           If RawTemp.15 = %1 Then               // is temp < 0C?
           Begin
              Positive := False;
              RawTemp := $0000-RawTemp;          // 2's complement fix up for < 0C
           End;
    
           RawTemp := (10 * RawTemp);         // muultiply by 10 &
           RawTemp := RawTemp shr 4;          // divide by 16 to get degrees x 10
    
           WordToStr(RawTemp,text);
           DS18B20_AddDecimal(text);
           lcd_out(2,10,text);
           If Positive Then
              lcd_chr(2,10,'+')                // add + or - sign. Will not be
              ELSE                            // properly aligned due to leading
              lcd_chr(2,10,'-');               // spaces that should be removed
    
    
           lcd_chr(2,15,223);                 // #176 'degree' character for Windows
           lcd_chr(2,16,'C');                  // not #223. #67 = C
    end;
    //******************************************************************************
    //Programme principal
    //******************************************************************************
    begin
    //PCFG3:PCFG0-RE2-RE1-RE0-RA5-RA3-RA2-RA1-RA0
    //   011x      D   D   D   D   D   D   D   D
    ADCON1 := %10000110;         // configure RA et RE pin as digital I/O
    
    PORTA  := 1;                         // initialize porte to 255
    PORTB  := 1;                         // initialize porte to 255
    PORTC  := 0;                         // initialize porte to 255
    PORTE  := 1;                         // initialize porte to 255
    TRISA  := 1;                         // designate porte as input
    TRISB  := 1;                         // designate porte as input
    TRISC  := 0;                         // designate porte as input
    TRISE  := 1;                         // designate porte as input
    Lcd_Init();                          // Initialize LCD
    Lcd_Cmd(_LCD_CLEAR);                 // Clear LCD display
    Lcd_Cmd(_LCD_CURSOR_OFF);            // Turn cursor off
    Delay_ms(500);
    
    I2C1_Init(100000);                   //initialiser I2C à 100KHz
    
    while true do
    begin
        DS18B20_temperature_Read;
        Delay_ms(500);
        DS1307_Time_Read;
        Delay_ms(500);
    end;
    
    end.
    Le premier provoque une erreur lors de la simulation, le second fonctionne.
    La seule différence concerne l'initialisation de l'écran.

    Mon problème actuel est que c'est la compilation avec la version d'évaluation qui fonctionne et que je suis a la imite de 2K pour cette version alors que ce programme est loin d'être complet.

    Avez-Vous une idée pour que la compilation avec la version 3.0.0.4 puisse fonctionner?

    Merci pour votre aide.

  20. #19
    invite67c9851b

    Re : Horloge DS1307 (Résolu)

    Bonjour,

    Après bien des recherches, je suis finalement passé à Mikropascal 3.8.

    Le programme fonctionne en simulation sur ISIS et les premiers tests sur l'automate sont concluants

    Il ne reste que quelques leds à souder avant les derniers essais.

    Merci pour votre aide.

    Je met en pièce jointe le fichier source pour les amateurs.

    Automate.zip

  21. #20
    bhl

    Re : Horloge DS1307

    slt les ga pouvez vous nous le mettre en mikroc puisque la traduction est un peu dur.

    merci!

  22. #21
    Gérard

    Re : Horloge DS1307

    Citation Envoyé par bhl Voir le message
    slt les ga pouvez vous nous le mettre en mikroc puisque la traduction est un peu dur.

    merci!
    Le gars n'est pas revenu depuis 4 ans et tu crois qu'il va lire ton message ?

Discussions similaires

  1. Horloge ds1307
    Par Benjiboubou dans le forum Électronique
    Réponses: 44
    Dernier message: 24/05/2011, 07h51
  2. Programmer une horloge a temps réel( ds1307 ) avec un P18f452 par I2C
    Par invite70c217d4 dans le forum Électronique
    Réponses: 2
    Dernier message: 08/04/2009, 19h39
  3. ds1307 algorithme
    Par invitec4b571da dans le forum Électronique
    Réponses: 5
    Dernier message: 13/03/2008, 23h42
  4. Ds1307
    Par invite369c4784 dans le forum Électronique
    Réponses: 2
    Dernier message: 11/02/2007, 20h18
  5. Horloge lumineuse, horloge mecanique et Einstein
    Par pidofra dans le forum Physique
    Réponses: 6
    Dernier message: 22/03/2006, 15h21
Découvrez nos comparatifs produits sur l'informatique et les technologies.