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 ---
- 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 ---
Real Time Clock avec DS1307 (RTC)
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonjour à tous,
Aujourd'hui nous allons parlé du module RTC2_click de Mikroelekronika .
Ce module est un calendrier qui permet de connaitre la date et l'heure en temps réel.
Il utilise le driver DS1307 très répandu.
Nous allons voir comment communiquer avec ce driver et dégrossir ses fonctions principales. ( Data-sheet du DS1307 )
Pour faire ce Tuto je me suis inspiré de l'exemple de MikroE, que vous pouvez retrouver ici
Exemple d'utilisation du moduleRTC2_click
Schéma de connexion du module
Configuration :
- PIC18F45K22
- IDE : MikroC Pro for PIC Version 6.6.2
- Compilateur : Mikro prog suite fo PIC V 2.32
- Plaque Easy PIC V7
- RTC2_click en mode I²C
- LCD 16x2 en mode 4bits
1/ Préliminaire
Le module RTC permet d'avoir l'heure et la date n'importe où sur vos projets ! .
Associer à une pile lithium, il sauvegarde la date et l'heure durant plusieurs mois/année même en cas de coupure de courant. Il est cadencé par un quartz externe calé sur une certaine fréquence(32.768KHz).
Durant ce tutoriel nous allons voir comment écrire et lire sur ce module. Nous allons ainsi pouvoir régler le Groupe-Date-Heure (GDH) en écrivant dans les registres du module, et bien évidemment récupérer le GDH fournit par le RTC pour se servir des informations ( afficher l'heure par exemple).
Le DS1307 offre également une sortie qui peut-être configurée en sortie logique ou en sortie de générateur de signal carré(Square-Wave). Cette sortie est relativement peu utilisée. Nous ne verrons pas cette fonction pour le moment.
2/ Initialisation de l'heure
Sans pile de sauvegarde , les registres sont tous à 0 au démarrage . Il conviendra donc de les initialiser.
Cela se fera par l'appui sur un BP (branché sur RA0).
Cette initialisation va simplement injectée dans les registres les valeurs que nous aurons préalablement configurées.
Une fois initialisé et le fonctionnement autorisé, le DS1307 incrémentera les valeurs automatiquement. elle est pas belle la vie ! :D
3/Récupération des infos
Le DS1307 une fois initialisé va nous fournir la date et l'heure ( l'unité la plus petite est la seconde). Il va donc nous falloir lire ses registres où sont stockés les valeurs du GDH , les enregistrées et enfin les affichées ou faire des calculs de durée par exemple.
Dans notre exemple nous afficherons la date et l'heure sur un écran LCD .
Attention!! La seule petite difficulté que j'ai rencontré c'est sur le fait que le module communique avec des valeurs en hexa ( BCD). Il va donc falloir convertir les données de décimal à hexa dans un sens , et de hexa à décimal dans l'autre .
pour ce faire nous utiliserons la bibliothèque conversions et les fonctions qui vont bien :
Bcd2Dec() et Dec2Bcd()
Donc avant chaque écriture et lecture nous devrons convertir les données.
Comme d'habitude , si vous avez des questions, remarques, propositions etc ..... n’hésitez pas à poster a la suite de ce sujet !
Voici le programme commenté ligne par ligne :
Code : Tout sélectionner
/*----------------------------------------------------------------------------------
- Tutoriel Module RTC 2 click sur plaque easyPic 7
- fait par Jérémy le 01/11/2015 sur www.FantasPic.fr
- Pic 18F45K22 avec MikroC 6.6.2
- Fosc : 8Mhz
----------------------------------------------------------------------------------*/
#define RTC_ADDR 0xD0 // Adresse I²C de l'esclave ( DS1307)
// Lcd module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Constantes
unsigned char txt1[]=" RTC2 click sur ";
unsigned char txt2[]="www.FantasPic.fr";
// Variables
unsigned char heures, minutes, secondes, jour, n_jour, mois, annee, D_secondes, U_secondes;
char oldstate = 0;
// Prototypes
unsigned short Bcd2Dec(unsigned short decnum);
unsigned short Dec2Bcd(unsigned short decnum);
/****************************************************************************
* Fonction: Lire les données sur le RTC
* parametre d'entrée : adresse du registre à lire
* parametre de sortie : valeur lue dans le registre
**********************************************************************************/
unsigned char RTC_Read(unsigned char addr){
unsigned char value; // Déclaration variable temporaire
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(addr); // adresse du registre à lire
I2C1_Start(); // On répète le signal de départ
I2C1_Wr(RTC_ADDR); // Adresse du DS1307
value = I2C1_Rd(0); // lecture et enregistrement de la valeur le 0=pour no ACK
I2C1_Stop(); // Arrêt de l'I²C
return value; // On retourne la valeur lue
}
/**************************************************************************************************
* Fonction: Ecrire les données sur le DS1307
* parametre d'entrée : adresse du registre à ecrire + valeur à y mettre
**************************************************************************************************/
void RTC_Write(unsigned char addr, unsigned char value){
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(addr); // adresse du registre à écrire
I2C1_Wr(value); // On écrit la valeur dans le registre
I2C1_Stop(); // Arrêt de l'I²C
}
/**************************************************************************************************
* Fonction: Ecrire le Groupe Date Heure sur appui du BP
* parametre d'entrée : Les 7 valeurs du GDH à initialiser
**************************************************************************************************/
void Ecrire_GDH (unsigned char heures , unsigned char minutes, unsigned char secondes ,
unsigned char jour,unsigned char n_jour, unsigned char mois,unsigned char annee){
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(0); // Met le pointeur à cette adresse ( N° registre)
secondes = Dec2Bcd(secondes); // Conversion de décimal en BCD pour le RTC
I2C1_Wr(secondes); // On écrit la valeur dans le registre des secondes
minutes = Dec2Bcd(minutes); // Après écriture la valeur du pointeur du registre est incrémenter automatiquement
I2C1_Wr(minutes); // On peut enchainer directement avec la prochaine valeur
heures = Dec2Bcd(heures); // etc ... toutes à la suite.
I2C1_Wr(heures);
jour = Dec2Bcd(jour);
I2C1_Wr(jour);
n_jour = Dec2Bcd(n_jour);
I2C1_Wr(n_jour);
mois = Dec2Bcd(mois);
I2C1_Wr(mois);
annee = Dec2Bcd(annee);
I2C1_Wr(annee);
I2C1_Stop(); // Arrêt de l'I²C
}
/**************************************************************************************************
* Fonction: Lit le Groupe Date Heure sur le RTC pour mettre à jour l'affichage
**************************************************************************************************/
void Lecture_GDH(){
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(0); // lecture à cette adresse ( N° registre)
I2C1_Repeated_Start(); // On répète le signal de départ
I2C1_Wr(RTC_ADDR+1); // Adresse du DS1307 (1=lire / 0=ecrire)
secondes = I2C1_Rd(1); // Lecture et enregistrement de la valeur
secondes = Bcd2Dec(secondes); // Conversion de BCD en décimal pour l'afficheur
minutes = I2C1_Rd(1);
minutes = Bcd2Dec(minutes);
heures = I2C1_Rd(1);
heures = Bcd2Dec(heures);
jour = I2C1_Rd(1);
jour = Bcd2Dec(jour);
n_jour = I2C1_Rd(1);
n_jour = Bcd2Dec(n_jour);
mois = I2C1_Rd(1);
mois = Bcd2Dec(mois);
annee = I2C1_Rd(0);
annee = Bcd2Dec(annee);
I2C1_Stop(); // Arrêt de l'I²C
}
/*##################################################################################
########################## PROGRAMME PRINCIPAL ###############################
##################################################################################*/
void main(){
ANSELA = 0; // Configure le PORTA en digital
ANSELB = 0; // Configure le PORTB en digital
ANSELC = 0; // Configure le PORTC en digital
SLRCON = 0; // ?? Configure all PORTS at the standard Slew
TRISA0_bit = 1; // Met RA0 en entrée pour le BP.
// Utilisé pour initialisé l'horloge avec une valeur enregistrée
I2C1_Init(100000); // Initialise le BUS I2C
Lcd_Init(); // Initialise le Lcd
Lcd_Cmd(_LCD_CLEAR); // Efface écran
Lcd_Cmd(_LCD_CURSOR_OFF); // Curseur off
Lcd_Out(1,1,txt1); // Écrit le texte de présentation 1er ligne
Lcd_Out(2,1,txt2); // Écrit le texte de présentation 2iéme ligne
Delay_ms(3000); // pause 3 sec
Lcd_Cmd(_LCD_CLEAR); // Efface l'écran
LCD_Chr(1,9,'.'); // On écrit la matrice du texte statique
LCD_Chr(1,12,'.');
LCD_Out(2,1,"Heure:");
LCD_Chr(2,11,':');
LCD_Chr(2,14,':');
LCD_Out(1,13,"20"); // le 20 c'est pour l'année 20xx
/*##################################################################################
############################ BOUCLE INFINIE ##################################
##################################################################################*/
while(1){
if (Button(&PORTA, 0, 1, 0))oldstate = 1; // Anti-rebond
if (oldstate && Button(&PORTA, 0, 1, 1)) { // Si le BP est appuyé on envoi le GDH suivant
Ecrire_GDH( 23, 59, 50, 4, 31, 12, 15); //heure: min: sec: N°jour: jour: mois: année
oldstate = 0; // mise à 0 du flag
}
Lecture_GDH(); // On va lire notre DS1307
switch(jour) // On sélectionne le jour suivant la valeur retournée
{
case 1: LCD_Out(1,1, "Lundi"); break; // Affichage du jour en fonction de la valeur
case 2: LCD_Out(1,1, "Mardi"); break;
case 3: LCD_Out(1,1, "Mer. "); break;
case 4: LCD_Out(1,1, "Jeudi"); break;
case 5: LCD_Out(1,1, "Ven. "); break;
case 6: LCD_Out(1,1, "Sam. "); break;
case 7: LCD_Out(1,1, "Dim. "); break;
}
Lcd_Chr(1,7, (n_jour / 10) + 48); // Le numéro du jour dizaine
Lcd_Chr(1,8, (n_jour % 10) + 48); // Le numéro du jour unité
Lcd_Chr(1,10, (mois / 10) + 48);
Lcd_Chr(1,11, (mois % 10) + 48);
Lcd_Chr(1,15, (annee / 10) + 48);
Lcd_Chr(1,16, (annee % 10) + 48);
Lcd_Chr(2,9, (heures / 10) + 48); // Deuxième lignes 9iéme caractère dizaine des heures
Lcd_Chr(2,10, (heures % 10) + 48); // Unité des heures
Lcd_Chr(2,12, (minutes / 10) + 48);
Lcd_Chr(2,13, (minutes % 10) + 48);
Lcd_Chr(2,15, (secondes / 10) + 48);
Lcd_Chr(2,16, (secondes % 10) + 48);
Delay_mS(10); // pause de 10ms
}
}
Sur la vidéo, n'ayant pas de pile, on voit les registres à 0 à l'allumage, puis en appuyant sur le BP en injecte les données . Dans notre exemple nous sommes le Jeudi 31 décembre 2015 et il est 23h59 .
http://www.dailymotion.com/video/x3bxeqz
Real Time Clock avec DS1307 (RTC)
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour,
Je ne sais pas si ma remarque suvante est placée au bon endroit
ce serait plutot dans une rubrique du genre "trucs & astuces ,contournement de deboires".. ?
ATTENTION :
il est preferable d'utilser la zone programme pour stocker les donnees figées
tel que du texte à afficher, car SINON mikroC les stocke en RAM
Ce n'est pas génant TANT qu'on a sufisament de RAM dispo..
sinon on peut tomber dans le cas où un alarme sibiline apparait à la compilation , tel que " irp bit .."
meme avec une compilation réussie .. NO ERROR.
ou error 102 ...
C'est surtout vrai avec les PIC 16F ... de petite taille RAM .
Ou pire on constate des aleas ou effet de bords par écrasement de données en zone memoire (RAM)
et on tourne en rond pour savoir où est le bug !
voir les nombreux post sur MikroE à ce sujet !
Malheureusement, les exemples MikroC NE SONT PAS toujours à suivre !
Ces exemples suffisamment court arrivent à tourner sans probleme
mais des qu'on étoffe un peu le programme .. les problemes arrivent.
// Constantes en Flash
const unsigned char txt1[]=" RTC2 click sur ";
const unsigned char txt2[]="www.FantasPic.fr";
//declaration en RAM
char TEXTE[17]. // largeur LCD 16 cars + 0=terminateur eventuel de string
// transferer le texte de ROM -> RAM via la librairie "String"
strConstRamCpy( TEXTE,txt1); // copie la chaine "Constante " en "Ram"
LCD_Write_Text(TEXTE);
si on a plusieurs messages , on n'utilise que la RAM tampon de 17 bytes...
Ou utiliser une fonction legerement differente suivant qu'on utilise du TEXTE dans le code
ou du TEXTE dans une variable RAM
exemple avec la fonction MikroC originale :
nouvelle fonction modifiée en :
exemple :
on peut faire pareil avec le LCD !
ecrire 2 fonctions distinctes:
la seule difference importante est le type de pointeur ! (sur RAM ou ROM.)
On peut donc aussi, tout simplement rajouter un casting sur le type de pointeur !
(casting = modification et forcage de type de variable ou pointeur)
comme dans l'image ci-jointe
3em solution
Message TEXTES fixes stockees en EEPROM ...
serait peut etre le choix le plus judicieux.
un exemple chiffré qui illustre la difference de stockage en RAM
Je ne sais pas si ma remarque suvante est placée au bon endroit
ce serait plutot dans une rubrique du genre "trucs & astuces ,contournement de deboires".. ?
ATTENTION :
il est preferable d'utilser la zone programme pour stocker les donnees figées
tel que du texte à afficher, car SINON mikroC les stocke en RAM
Ce n'est pas génant TANT qu'on a sufisament de RAM dispo..
sinon on peut tomber dans le cas où un alarme sibiline apparait à la compilation , tel que " irp bit .."
meme avec une compilation réussie .. NO ERROR.
ou error 102 ...
C'est surtout vrai avec les PIC 16F ... de petite taille RAM .
Ou pire on constate des aleas ou effet de bords par écrasement de données en zone memoire (RAM)
et on tourne en rond pour savoir où est le bug !
voir les nombreux post sur MikroE à ce sujet !
Malheureusement, les exemples MikroC NE SONT PAS toujours à suivre !
Ces exemples suffisamment court arrivent à tourner sans probleme
mais des qu'on étoffe un peu le programme .. les problemes arrivent.
// Constantes en Flash
const unsigned char txt1[]=" RTC2 click sur ";
const unsigned char txt2[]="www.FantasPic.fr";
//declaration en RAM
char TEXTE[17]. // largeur LCD 16 cars + 0=terminateur eventuel de string
// transferer le texte de ROM -> RAM via la librairie "String"
strConstRamCpy( TEXTE,txt1); // copie la chaine "Constante " en "Ram"
LCD_Write_Text(TEXTE);
si on a plusieurs messages , on n'utilise que la RAM tampon de 17 bytes...
Ou utiliser une fonction legerement differente suivant qu'on utilise du TEXTE dans le code
ou du TEXTE dans une variable RAM
exemple avec la fonction MikroC originale :
Code : Tout sélectionner
void UART_Write_Text(char * UART_text);
strConstRamCpy( TEXTE,txt1); // copy le string situé en Flash -> RAM
UART_Write_Text(TEXTE) // envoie le texte situé en RAM sur l'UART (ecran);
nouvelle fonction modifiée en :
Code : Tout sélectionner
void UART1_Write_CText(const char *txt1)
{
while (*txt1)
UART1_Write(*(txt1++));
}
exemple :
Code : Tout sélectionner
UART_Write_CText(" TC2 click sur"); // envoi le Texte ecrit dans le code sur l'UART SANS utiliser la RAM
on peut faire pareil avec le LCD !
ecrire 2 fonctions distinctes:
Code : Tout sélectionner
void LCD_Write_Text(unsigned int Ligne,char * t1);
void LCD_Write_CText(unsigned int Ligne,unsigned int col,const char * t1);
la seule difference importante est le type de pointeur ! (sur RAM ou ROM.)
On peut donc aussi, tout simplement rajouter un casting sur le type de pointeur !
(casting = modification et forcage de type de variable ou pointeur)
comme dans l'image ci-jointe
3em solution
Message TEXTES fixes stockees en EEPROM ...
serait peut etre le choix le plus judicieux.
un exemple chiffré qui illustre la difference de stockage en RAM
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Real Time Clock avec DS1307 (RTC)
Bonjour,
Je me permet un petit message. Non pas pour apporté une amélioration au tuto, mais je me pose des questions.
Voilà, je commence sérieusement a m’attaquer aux RTC (DS3231). Et je vois dans le code 2 fonctions mais je ne sais pas a quoi servent t'elle ? Sont t'elle utile pour le bon fonctionnement du reste ?
Il s'agit des fonctions
et
Car ses fonctions ne sont pas rappeler plus tard dans le code. Donc a quoi servent t'elles ?
Désolé, j’essaie de bien comprendre le code pour partir du bon pied dans le fonctionnement des RTC.
Ps: si ma question nécessite un nouveau topic, merci de me le faire savoir.
@++
Je me permet un petit message. Non pas pour apporté une amélioration au tuto, mais je me pose des questions.
Voilà, je commence sérieusement a m’attaquer aux RTC (DS3231). Et je vois dans le code 2 fonctions mais je ne sais pas a quoi servent t'elle ? Sont t'elle utile pour le bon fonctionnement du reste ?
Il s'agit des fonctions
Source du message unsigned char RTC_Read(unsigned char addr)
et
Source du message void RTC_Write(unsigned char addr, unsigned char value)
Car ses fonctions ne sont pas rappeler plus tard dans le code. Donc a quoi servent t'elles ?
Désolé, j’essaie de bien comprendre le code pour partir du bon pied dans le fonctionnement des RTC.
Ps: si ma question nécessite un nouveau topic, merci de me le faire savoir.
@++
Real Time Clock avec DS1307 (RTC)
Real Time Clock avec DS1307 (RTC)
Bonjour,
Avec ceci: https://www.mikroe.com/rtc-2-click tu as ce qu'il te faut (voir User manual).
Module RTC DS1307 bon marché : https://www.ebay.fr/itm/Module-DS1307-2 ... 0005.m1851
Avec ceci: https://www.mikroe.com/rtc-2-click tu as ce qu'il te faut (voir User manual).
Module RTC DS1307 bon marché : https://www.ebay.fr/itm/Module-DS1307-2 ... 0005.m1851
Real Time Clock avec DS1307 (RTC)
Real Time Clock avec DS1307 (RTC)
Real Time Clock avec DS1307 (RTC)
Certes, mais il est vraiment très petit, je n'arriverai jamais à souder ça, heureusement qu'on trouve plein de "breakout" (comment traduire ?), par exemple ici
Real Time Clock avec DS1307 (RTC)
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour,
Petit, mais chero cette version de breakout board!
A noter , que la DS3231 repond tres bien à un programme ecrit pour une DS1307 ...
avec la mesure de temperature ambiante (ou presque) en sus
voir Ds3231 RTC: temperature display
JJE a écrit :Certes, mais il est vraiment très petit, je n'arriverai jamais à souder ça, heureusement qu'on trouve plein de "breakout" (comment traduire ?), par exemple ici
Petit, mais chero cette version de breakout board!
A noter , que la DS3231 repond tres bien à un programme ecrit pour une DS1307 ...
avec la mesure de temperature ambiante (ou presque) en sus
voir Ds3231 RTC: temperature display
Real Time Clock avec DS1307 (RTC)
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
paulfjujo a écrit :bonjour,JJE a écrit :Certes, mais il est vraiment très petit, je n'arriverai jamais à souder ça, heureusement qu'on trouve plein de "breakout" (comment traduire ?), par exemple ici
les chinois traduisent Plaque d'essai BreadBoard par "Planche à pain "
du pain ,il y en a tout le temps sur la planche ..
on pourrait traduire Breakout "plaque pour nous sortir de l'embarras " ( en restant poli !)
Petit, mais chero cette version de breakout board!
A noter , que la DS3231 repond tres bien à un programme ecrit pour une DS1307 ...
avec la mesure de temperature ambiante (ou presque) en sus
voir Ds3231 RTC: temperature display
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 38 invités