Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Digression autour de la RTC et MPLABX (CLOSED)
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2598
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » dim. 15 oct. 2023 16:10

bonjour à tous,


MPLABX dispose de 2 variables __DATA__ et __TIME__ liées au compilateur XC8 2.36 C90
permettant de signaler par exemple, la date fraicheur du programme :
Compile le Oct 15 2023 a 14:29:37 UTC
avec version XC8 : 2360


L'idée est d'exploiter ces 2 infos pour initialiser une RTC DS3231 via I2C1

nota: j'ai supposé que MLPAB delivre dans _DATA__ le nom du mois avec seulement les 3 premiers caracteres
et que le format ( longueur de texte est constant)

ATTENTION aux notions aux valeurs pouvant représenter de l'ascii, du binaire, ou du BCD ...
La RTC nécessite du BCD !
Dommage, Le numéro du jour dans la semaine n'est pas transmis par MLPAB
et on en a besoin pour cette appli "chaudiere".

Recherche de ce jour via le calcul du Jour Julien fonction ( an,mois,jour)
pour déterminer jS : jour de semaine (jS évolue de 0=Lundi à Dimanche=6)
qui sera assigné au parametre #04 de la RTC
:-D on peut donc ainsi initialiser completement la RTC !
(malgré quand même un peu de code supplementaire ! ... (mais c'est un 18F27K42 avec 128ko)

ça marche ! MAIS ....

:sad: Le seul bemol est que le TIME MPLABX est en retard de la duree de compilation
(variable !) estimée ici à 1mn 20" à la premiere compilation
et 49 sec ... aux suivantes ( avec 12go de RAM sur le PC WIN10, et plusieurs minutes avec seulement 4Go de RAM)
ce n'est donc pas le Perrou !
... mais on peut toujours rectifier ce retard au temps

sachant que le terminal YAT , permet de mesurer exactement cette différence de temps ... option ...view...show time Stamp

à la seconde compilation, sans modif de code source...

(14:59:25.467) Datas PC System
(14:59:25.467) Oct 15 2023
(14:59:25.519) 14:58:37
...etc ....

(14:59:38.327) 00000
(14:59:39.341) BAV=2
(14:59:40.691) Recu :BAV=2
(14:59:40.703) 00001 Dimanche 15/10/23 14H58M52S
(14:59:43.102) 00002 Dimanche 15/10/23 14H58M54S
ecart= 59:43 - 58:54 = 0mn 49sec

L'autre probleme est le flag automatique ETE / HIVER qui dépend du moment de compilation
car sauvé en EEPROM et relu ensuite ..
cela implique de garder
- une possibilite MANUELLE de rectifier le contenu RTC ( dialogue operateur via BP et LCD) (déja prevu et ok)
- ou via la liaison UART (dialogue Operateur) en envoyant la sequence d'init sous la forme :
U;15;10;23;14;20;06;# pour 15 octobre 2023 , 14H20, Dimanche \r\n") (deja prevu et ok)

idea ! Conclusion : fausse bonne idée ... mais intéressera peut être quelqu'un. ?

mais ça m'a permis de dépoussiérer un vieux programme écris en Turbo C 2.00, il y a quelques décennies (CALANDAR.C)
Transposable facilement en XC8

:sifflotte: ( en ASM intel 80386 ce n'aurait pas été aussi facile ! comme quoi le langage C est (assez) universel .

(14:59:25.467) Datas PC System
(14:59:25.467) Oct 15 2023
(14:59:25.519) 14:58:37
(14:59:25.519)
(14:59:25.519) recup datas (en BCD !!) pour init RTC
(14:59:25.519) Mois = Oct..mois trouve =10
(14:59:25.519) , jour = 15, Annee = 23
(14:59:25.519) JMA= 15/10/23 , time 14:58:37
(14:59:25.519)
(14:59:25.519) Test jour Julien
(14:59:25.519) date 29/08/1996 -> jour julien # 2450325 Jeudi jour # 3
(14:59:25.519) date aujourd'hui 15/10/2023 -> jour julien # 2460233 Dimanche jour # 6
(14:59:25.519)
(14:59:25.519) MAJ RTC !
(14:59:25.519) ATTENTION : Possibilité de forçage init RTC , inhibée pendant les tests
(14:59:25.519) Re-Lecture et affichage des 8 registres RTC DS3231
(14:59:25.622) Temperature DS3231 => 24.75°C
(14:59:25.668) Horaire d' ETE
(14:59:25.854) adresse LCD= 32 soit 0X20
(14:59:25.854)
(14:59:25.854) Sequence d'Init LCD 4x20 via I2C1 PCF8574
(14:59:25.854) .123456789A
(14:59:26.003) version Carte PCB chaudiere : LCD Blanc à l'adresse 0x20 !
(14:59:26.231) Chargement caracteres Speciaux en CGRAM
(14:59:26.415) ECO....
(14:59:26.469) BARRE_G
(14:59:26.475) BARRE_D
(14:59:26.505) BARREGD
(14:59:26.535) FLECH H
(14:59:26.565) FLECH_B
(14:59:26.594) 1/2Heur
(14:59:26.634) DEGREC
(14:59:27.653)
(14:59:27.653) Config et Init One Wire
(14:59:27.715)
(14:59:27.715) Rechargement corrections capteurs DS18B20 depuis Eeprom
(14:59:27.715) T1Cor= -0.021
(14:59:27.715) T2Cor= -0.021
(14:59:27.715) T3Cor= 0.042
(14:59:27.715)
(14:59:27.850) Mesures 3 temperatures Corrigees :
(14:59:28.430) INT_mes= 23.667°C
(14:59:28.486) EXT_mes= 23.729°C
(14:59:28.555) EAU_mes = 23.854°C
(14:59:30.603)
(14:59:30.603) Init Compteur 24 bits SMT1, avec choix clock 4=> 500KHz tick=2uS
(14:59:30.713) Test SMT1 avec delay 100mS , Nb Tics 49997 L2=99994 uS
(14:59:30.743)
(14:59:30.743)
(14:59:30.743)
(14:59:30.743) Lecture table programmes horaire en eeprom
(14:59:37.913)
(14:59:38.275) Duree Affichage LCD , Nb Tics 178186 L2=356372 uS
(14:59:38.327) Init Timer1 100mS et SMT1 compteur 24bits
(14:59:38.327) Reaffectation RC5 (SW6 inout) en Sortie pour Alarme L5
(14:59:38.327) 00000
(14:59:39.341) BAV=2
(14:59:40.691) Recu :BAV=2
(14:59:40.703) 00001 Dimanche 15/10/23 14H58M52S
(14:59:43.102) 00002 Dimanche 15/10/23 14H58M54S


la partie code associée à ce test

Code : Tout sélectionner



const char Prefixe_Mois
[12][4]={ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};


// ----date et RTC -----
long Jour_Julien;
const char All_Jour_Semaine[]="LuMaMeJeVeSaDiEr";
const  char Jour0[]="Lundi ";
const  char Jour1[]="Mardi ";
const  char Jour2[]="Mercredi ";
const  char Jour3[]="Jeudi ";
const  char Jour4[]="Vendredi ";
const  char Jour5[]="Samedi ";
const  char Jour6[]="Dimanche ";
const  char Jour7[]="Error ";
const  char * JourSemaine[]={Jour0,Jour1,Jour2,Jour3,Jour4,Jour5,Jour6,Jour7};

char time[]="00H00M00S";
char date[]="00/00/00";

long jour2jul(char jour , char mois , int annee);
char *j_txt(long n , char *num);

   
long jour2jul
(char jour , char mois , int annee)
{
 long jule, gregorien, a , j , m;
/* Attention, cette routine ne doit etre appellee que si on est sur
   que le jour fourni en param?tre existe !!!!!! */
= (long)annee;
= (long)mois;
= (long)jour;
// On commence par faire un ajustement pour les annnees negatives 
    if (annee < 0)    a++;
    jule = ((489L *- 481 ) >>4) + j + 1721423L - (((a&3)+7)>>2)*((m+13)>>4)    + ((1461L*(a-1))>>2);
   /* Avant le 04/10/1582 on est en calendrier julien, et en calendrier  gregorien apres le 15/10/1582 */
    if (jule <= 2299160L)
        return jule;
    /* En calendrier gregorien les ajustements ? faire sont :
       - les annees divisibles par 100 ne sont pas bissextiles
       - les annees divisibles par 400 sont bissextiles.
    */
     gregorien = jule - (a/100L - a/400L - 2L);
     if ( ( (a%100) == 0 ) && (< 3) && ( (a%400) != 0)) gregorien++;
    return gregorien;
}

char *j_txt(long n , char *num)
{
char c;
    if (< 0L)
        c = 6 - (char)((-n-1)%7);
    else
    c 
= (char)(n%7);
    *num = c;
    return (char *)JourSemaine[c];
}


  // ------------ dans le main.c ---------------------------
   
    sprintf
(txt," Compile le %s a %s UTC\r\n avec version XC8 :  %d \r\n", __DATE__, __TIME__,__XC8_VERSION);
    Print(txt);
    CRLF1();
        
    __delay_xSec
(2);


    CPrint(" Init_I2C() à 100Khz;\r\n");
    Init_I2C(); //SCLK=  500Khz / 5 = 100Khz
    CPrint(" Test presence devices sur Bus I2C1\r\n");
    Test_Presence_I2C_devices();
    CRLF1();
    CPrint(" #1 Active sortie RTC SQW=1Hz: \r\n");
    CPrint(" GO\r\n");
    // set SQW output  Start oscillateur
    tmp[0]=0x40; // data 
    I2C1_Write1ByteRegister(DS3231_ADDR,0x0E, tmp[0]);
    CPrint(" ok\r\n");
    __delay_ms(100);
    
    
    CPrint
("\r\n Datas PC System \r\n");
    sprintf(txt,"%s", __DATE__); // Oct 14 2023     11 cars
    Print(txt);CRLF1();
    sprintf(CRam1,"%s", __TIME__);
    Print(CRam1);CRLF1(); //15:02:12       8 cars
    CRLF1();
    CPrint(" recup datas (en BCD !!) pour init RTC \r\n");
    // decodage pour le Numero du mois
    *(txt+3)=0; CPrint("Mois = ");Print(txt);
    i=0;
    do
    
{ 
        if 
(strcmp( &Prefixe_Mois[i],txt) ==)
         {
             sprintf(Tampon,"..mois  trouve =%d ",i+1);
             Print(Tampon);
             CRLF1();
             mois=Dec2Bcd(i+1);
             break;  
         
}  
       i
++;
    }
    while (i<12);
    
    
*(txt+6)=0; CPrint(", jour = ");Print(txt+4);
    jour=(*(txt+4)-48)*16 + *(txt+5)-48;    // jour=atoi(txt+4);
    *(txt+11)=0; 
    CPrint
(", Annee = ");Print(txt+9); 
    Annee
=(*(txt+9)-48) *16 + *(txt+10)-48;    //Annee=atoi(txt+9); 
    CRLF1();
    * (CRam1+2)=0;* (CRam1+5)=0;* (CRam1+8)=0;
    heure= (*(CRam1)-48 )  *16 + *(CRam1+1)-48;   // en BCD !!
    minute=(*(CRam1+3)-48) *16 + *(CRam1+4)-48;
    second=(*(CRam1+6)-48) *16 + *(CRam1+7)-48;
    sprintf(txt,"JMA= %02x/%02x/%02x , time %02x:%02x:%02x\r\n",jour,mois,Annee,heure,minute,second);
    Print(txt);
    CRLF1();
  
    CPrint
(" Test jour Julien\r\n");
    Jour_Julien=jour2jul(29,8,1996);
    sprintf(txt," date 29/08/1996 -> jour julien # %ld",Jour_Julien);
    Print(txt);PrintChar(TAB);
    // jour de la semaine 
    Print(j_txt(Jour_Julien , &cx));
    CPrint("  jour # ");PrintChar(cx);
    PrintChar(cx+48);
    CRLF1();
  
    i
=Bcd2Dec(jour);
    j=Bcd2Dec(mois);
    k=Bcd2Dec(Annee);
    
    Jour_Julien
=jour2jul(i,j,k+2000);
    sprintf(txt," date aujourd'hui 15/10/2023  -> jour julien # %ld",Jour_Julien);
    Print(txt);PrintChar(TAB);
    // jour de la semaine 
    Print(j_txt(Jour_Julien , &jS));
    CPrint("  jour # ");
    PrintChar(jS+48);  CRLF1();
    CRLF1();
   
    
     CPrint
(" MAJ RTC !\r\n");
     // avec datas en BCD ! 
        tmp[0]=0x00;  //stop Oscillateur
        tmp[1]=second;  ;
        tmp[2]= minute;
        tmp[3]= heure;
        tmp[4]=jS;  //write day of week 
        tmp[5]=jour; 
        tmp
[6]=mois; 
        tmp
[7]=Annee;  
        tmp
[8]=0;
        p1=&tmp[0];
        I2C1_WriteNBytes(DS3231_ADDR,p1,9);
    


oui, je sais ... il y aurait sans doute d'autres possibilités ( Via ESP8266 ou autre GPS ..etc ...)
Modifié en dernier par paulfjujo le ven. 20 oct. 2023 10:07, modifié 1 fois.
Aide toi, le ciel ou FantasPic t'aidera

Digression autour de la RTC et MPLABX
ThomasBarre789
Membre
Membre
Messages : 1
Enregistré en : octobre 2023

#2 Message par ThomasBarre789 » mer. 18 oct. 2023 10:05

Bonjour,

Je trouve que votre idée est originale et astucieuse, mais je comprends aussi les limites que vous avez soulignées. Voici quelques suggestions qui pourraient vous aider à améliorer votre code ou à trouver d'autres solutions :

• Pour réduire le retard du temps de compilation, vous pouvez essayer d'optimiser votre code en supprimant les parties inutiles, en utilisant des macros ou des fonctions inline, ou en choisissant un niveau d'optimisation plus élevé dans les options du compilateur.

• Pour gérer le flag ETE/HIVER, vous pouvez utiliser une variable globale qui stocke l'état actuel du changement d'heure, et la mettre à jour manuellement ou automatiquement selon une règle fixe ou variable. Vous pouvez aussi utiliser une bibliothèque externe qui gère le changement d'heure pour différents pays ou fuseaux horaires.

• Pour synchroniser l'horloge de votre application avec une source plus précise que le système PC, vous pouvez utiliser un module GPS qui fournit l'heure universelle coordonnée (UTC) et la date avec une grande précision. Vous pouvez aussi utiliser un module WiFi qui se connecte à un serveur de temps sur internet (NTP) et qui récupère l'heure et la date actuelles.

J'espère que ces suggestions vous aideront à réaliser votre projet. Si vous avez d'autres questions, n'hésitez pas à me les poser. Bonne journée !

Digression autour de la RTC et MPLABX
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2598
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#3 Message par paulfjujo » mer. 18 oct. 2023 12:34

Bonjour,

et merçi pour la réponse


les options GPS et WIFI ont été écartées des le depart du projet.
In fine je ne vais pas utiliser cette façon ( avec date PC) ...
décision de ne garder que la solution 100% manuelle ( avec menu + Boutons poussoir +LCD ) ou via liaision UART ( ou Bluetooth)

ThomasBarre789 a écrit :.....
• Pour réduire le retard du temps de compilation, vous pouvez essayer d'optimiser votre code en supprimant les parties inutiles, en utilisant des macros ou des fonctions inline, ou en choisissant un niveau d'optimisation plus élevé dans les options du compilateur.


La version MPLAB XC8 Gratuite n'est pas optimisée ....
La meme application se compile 10 à 20 fois plus vite avec MikroC Pro 7.60 ( version payante 250€!)
La duree de compilation depend beaucoup de la taille RAM ... dure 10 à12mn avec 4 Go
j'ai augmenté ma RAM de +8go ( 12gO) ce qui a reduit le temps de compilation < 2minutes.

Les macros dupliquent le code ...
un exemple simple Macro XC8 __delay_ms(xx)
code répliqué autant de fois qu'il est utilise !
d'ou l'usage d'une fonction (sous programme) plutot qu'une macro.
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Bing [Bot] et 7 invités