Problème codage lecture heure RTC MCP79410

Bonsoir.
J’essaie, pour m'entrainer question codage, de lire les registres d'un RTC MCP79410 via I2C, mais j'obtiens des résultats très bizarres, ce que je lis ne correspond pas à ce que j'écris dans le module. datasheet

J'ai l'impression de ne pas très bien savoir utiliser la bibliothèque Wire.

Pour lire par exemple le registre des heures à l'adresse 0x2 (p.18 datasheet), j'ai utilisé la fonction clockReadH() suivante:

short clockReadH(void){
    
    uint8_t td, od, h;
    uint8_t read = ramRead(0x2);
    
    if(read == -1) return 0;
   
    read &= (0b00111111);
    td = ((read & (0b00110000))>>4)*10;
    od = read & (0b00001111);

    return td+od;
  
}//clockReadH()

avec ramRead():

short ramRead(uint8_t addr){
    uint8_t nbBytes=1;
    
    Wire.beginTransmission(RTC_SRAM_CTRL_REG); //=0b1101111 (p.10 datasheet)
    Wire.write(addr);
    uint8_t i = Wire.endTransmission(true);

    if(i!=0) return -1;

    i = Wire.requestFrom(RTC_SRAM_CTRL_REG,nbBytes,true);

    if (i == nbBytes) return Wire.read();
    else return -1;
    
}//ramRead()

La fonction avec laquelle j'écris dans le registre des heures avant lecture est :

bool clockSet(uint8_t h, uint8_t mn, uint8_t s){ //activer le quartz oscillation
    
    if(h>24 || mn >60 || s > 60) return 0;
    
    uint8_t g, p;

    uint8_t a=0;

    Serial.print("consigne h: ");
    Serial.println(h,DEC);
    Serial.print("consigne mn: ");
    Serial.println(mn,DEC);
    
    do{//desactivation oscillateur nécessaire avant màj
      disableST();
      delay(500);
      a++;
      if(a>=4) return 0;
    }while(isOSCRUN()==true);

    g = ((uint8_t)h/10)<<4;
    p = (uint8_t)h%10;
    h = (g+p);
    ramWrite(0X2, (ramRead(0X2)|h));
    delay(20);

    g = ((uint8_t)mn/10)<<4;
    p = (uint8_t)mn%10;
    mn = (g+p);
    ramWrite(RTCMIN_REG, (ramRead(RTCMIN_REG)|mn));
    delay(20);

    g = ((uint8_t)s/10)<<4;
    p = (uint8_t)s%10;
    s = (g+p);
    ramWrite(RTCSEC_REG, (ramRead(RTCSEC_REG)|s));
    delay(20);

    a=0;
    do{//reactivation oscillateur
      enableST();
      delay(500);
      a++;
      if(a>=4) return 0;
    }while(isOSCRUN()==false);

    Serial.print("registre h: ");
    Serial.println(ramRead(0x2),BIN);//registre des heures
    Serial.print("registre mn: ");
    Serial.println(ramRead(0x2),BIN);
    
    return 1;
    
}

et la fonction ramWrite() qui va avec

uint8_t ramWrite(uint8_t addr, uint8_t data){

    Wire.beginTransmission(RTC_SRAM_CTRL_REG);
    Wire.write(addr);
    Wire.write(data);
    uint8_t i = Wire.endTransmission(true);

    return i;
    
}//ramWrite()

Quelques heures maintenant que je planche dessus et je n'arrive pas à comprendre d'où vient mon erreur.

Est-ce moi qui utilise mal les fonctions de la biblio Wire ? Ou une autre erreur fondamentale de codage ?
Par exemple, je ne comprend pas à quel moment la fonction rajoute un 1 binaire à l'adresse de l'esclave pour ce dernier sache qu'on est en mode ecriture, je suis perdu la dessus.

Un exemple d'erreur, alors que la consigne est clockSet(20,1,15); voici ce que j'obtiens comme résultats :
image
20h19mn38s ald de la consigne 20h1mn,15s
Les registres h et mn correspondent bien à ce qui est lu ("il est:20h19...), mais ne correspondent pas à la consigne d'entrée

Merci de vouloir bien m'aider
(PS: j'ai raccourci volontairement le code pour ne pas alourdir le post, mais si besoin, je poste l'ensemble)

edit: rajout fonction ramWrite()

essayez un truc comme cela tapé ici donc sans garantie

#include <Wire.h>
#define RTC_SRAM_CTRL_REG 0x6F // Adresse I2C du RTC MCP79410

// Fonction pour convertir le format BCD en décimal
uint8_t bcdToDecimal(uint8_t bcd) {
  return (bcd / 16 * 10) + (bcd % 16);
}

bool readRTC(uint8_t &heures, uint8_t &minutes, uint8_t &secondes) {
  Wire.beginTransmission(RTC_SRAM_CTRL_REG);
  Wire.write(0x00); // Adresse du registre des secondes
  if (Wire.endTransmission(false) != 0) return false; // Erreur lors de la transmission
  if (Wire.requestFrom(RTC_ADDR, 3, true) != 3) return false; // Erreur lors de la réception des données

  secondes = bcdToDecimal(Wire.read() & 0x7F); // Masquage du bit CH (Clock Halt)
  minutes  = bcdToDecimal(Wire.read());
  heures   = bcdToDecimal(Wire.read() & 0x3F); // Masquage du format 24 heures

  return true; 
}

// -----------------------------------

void setup() {
  Serial.begin(115200);
  Wire.begin();
}

void loop() {
  uint8_t heures, minutes, secondes;
  if (readRTC(heures, minutes, secondes)) {
    Serial.print("Heures: ");   Serial.print(heures);
    Serial.print(":");
    Serial.print("Minutes: ");  Serial.print(minutes);
    Serial.print(":");
    Serial.print("Secondes: "); Serial.println(secondes);
  } else {
    Serial.println("Erreur lors de la lecture du RTC.");
  }

  delay(1000); // Attente d'une seconde
}


Merci @J-M-L problème trouvé à l'instant, il y avait donc une erreur dans la fonction clockSet(), je ne mettais pas à zéro les registres avant d'y inserer les nouvelles valeurs, je faisais un mix entre anciennes et nouvelles valeurs ! ^^

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.