Overblog Suivre ce blog
Editer la page Administration Créer mon blog

Horloge temps réel DS1307 + Picaxe 08M2 + LCD série

Retrouvez cette page
et toutes les mises à jour
sur

http://electromag1.wifeo.com/ 

 

 
Il est parfois utile dans une application de disposer d'une horloge temps réel.
Un DS1307 donne cette possibilité pour un prix raisonnable.  
  Cahier des charges:
Afficher sur un LCD la date et l'heure en temps réel.
Option 1: Sélection des paramètres d'initialisation par potentiomètre.
Option 2: Sélection des données par poussoir.
Remarque: La date donnée par le DS1307 est juste, à condition que l'initialisation soit cohérente. Un 30 février ou un 31 avril est accepté. De même, le jour de la semaine n'est pas calculé. Toute erreur conduit à une date incohérent.
La version poussoir interdit l'introduction de date farfelue (au prix d'un code plus touffu). Mais c'est pour le fun, on est pas non plus obligé de faire n'importe quoi. 
 
 
Voilà déjà le schéma, potentiomètre ou poussoir, au choix.
 
        RTC1307 08m2 LCD  
 
 
Le DS1307  Notice
 
C'est un circuit horloge, fabriqué par Maxim avec liaison par bus I2C .
Adresse %11010000
Cadensé par quartz et sauvegardé par batterie lithium (10 ans).
Le calendrier couvre la période 2000 à 2100
 
Les données sont enregistrées dans 7 registres au format BCD, dans l'ordre
secondes,minutes,heures, j de sem,jour,mois, année (ss,mm,hh,JS,JJ,MM,YY)
Ex: pour initialiser le DS1307, à la date du 25 décembre 2012 à 23h 15,
(c'est un mardi, jour 3 de la semaine) nous utiliserons la commande suivante:
 
hi2cout 0, ($00,$15,$23,$03,$25,$12,$12,%00010000)
 
Et pourquoi les $ ?   Explication:  
 
Chaque registre est composé d'un octet et reçoit 2 chiffres.
Chaque chiffre est codé sur 4 bits, le premier chiffre va dans les 4 premiers bits, le second chiffre dans les 4 derniers bits. C'est le codage BCD (décimal codé binaire) 
Ex pour 29: 
2 = %0010
9 = %1001
en BCD, 29 = % 0010 1001  ce qui est bien 29 en hexadécimal et donc noté $29
En décimal, $29 = 41 
Donc, envoyer dans un registre %00101001 ou $29 ou 41, c'est pareil, ce n'est qu'une  notation différente du même octet.
 
Le premier registre des secondes est toujours à 0 et initialise l'oscillateur.
Le dernier octet est un registre de contrôle et règle en particulier le format de l'heure sur 12 ou 24h.
Il faut introduire "manuellement" le bon jour de la semaine correspondant à la date. Pour limiter les erreurs, il sera calculé avec l'algorithme de Mike Keith (il a déclaré lui même que c'était le plus court et le meilleur), à partir du jour, du mois et de l'année.
 
 
Le choix minimaliste du picaxe 08M2 est juste suffisant pour remplir toutes les fonctions: lecture du DS1307, réglage initial des registres et affichage sur LCD série (voir cette page).
Le réglage des données utilise un potentiomètre sur une entrée ADC ou un poussoir et occupe le dernier port.
  
 
Dans cette vidéo de démo de la version poussoir, on voit que l'on peut cliquer n'importe comment mais ça ne donne pas n'importe quoi. (en regardant la vidéo, j'ai vu les heures monter à 24 !...C'est corrigé, maintenant c'est 23 max).
  
Pour limiter les possibilités aux seules dates cohérentes, il faut introduire la date dans l'ordre:  année, mois, jour.
De plus, le choix des chiffres est limité au stricte nécessaire:
L'année pour calculer les années bissextiles.
Le mois pour calculer le nombres de jours max (28,29,30,31).
Calculer le chiffre mini et maxi des dizaines et des unités (pas de 00 pour le mois et le jour).
L'année, le mois et le jour pour calculer le jour de la semaine. 
 
 
 
       
 
On trouve facilement sur eBay des modules complets, avec quartz et batterie (là, il faut bien lire si elle est fournie ou non) pour moins de 2 euros (oui, 2 euros !, port gratuit !).
 
  
Tiny-RTC-DS1307.JPG  Tiny-RTC-DS1307_2.JPG
 Le module commandé sur ebay
1,86 € port gratuit reçu en 15 jours
 Pile comprise, avec une EEPROM
A si, le connecteur a été ajouté..
 
 
Le schéma correspondant (trouvé sur internet):
 
Schema Tiny RTC DS1307
        Remarques:
  • Les modules reçus sont conformes au schéma (oui "les modules", j'ai vu une offre avec un module marqué "designed by Newman" pour voir. J'ai vu, vendu plus de 4 euros, non marqué, c'est exactement le même !).
  • Les résistances de pull up de la liaison I2C sont cablées sur le module.
  • La batterie LIR 2032 (3,6v) est rechargeable et rechargée par  D1, R5 donc, il faut en tenir compte si vous recevez un modèle sans batterie (ce qui serait dommage).
  • L'emplacement pour un capteur thermique DS18B20 est là, avec la broche DS, mais pas le capteur (Ah, les radins!).
  •  l'EEPROM AT24C32 a les pattes A0,A1,A2 reliées au 0v. L'adresse est donc figée à %1010000X, X étant le bit R/W.

Doc de l'EEPROM:

http://www.datasheetcatalog.org/datasheet/atmel/doc0336.pdf

 

Un petit essai avec ce module:
 
 
 
 
Le code du programme "poussoir" :
 
L'original .bas, (à ouvrir avec l'éditeur Picaxe) est plus présentable.
En téléchargement ICI   
 
 
  '########################################
'# Pour PICAXE-08M2 et MAXIM DS1307 RTC #
'# MM 29/12/2012                        #
'########################################
' Plage de dates entre 2000 et 2099
' Affichage des données sur LCD série port C.0   
 
Debut:
 #picaxe 08m2
 SetFreq m8
 symbol baud=N4800_8 'liaison série à 4800 bauds 8 Mhz
'***** Nomination des ports *********
 symbol increm  = pinC.4 'poussoir incrémentation
 symbol valid  = pinC.3 'poussoir validation 
'***** Nomination des variables type byte ***********
 symbol ch  =b1 'chiffre
 symbol dch  =b2 'chiffre diz
 symbol col  =b3 'n° colonne
 symbol minch =b4 'chiffre mini
 symbol maxch =b5 'chiffre maxi
 symbol varb  =b6 'temporaire byte
 symbol jour  =b7
 symbol mois  =b8
 symbol heure =b9
 symbol minut =b10
 symbol second =b11
'***** Nomination des variables type word ********** 
 symbol joursem =w11
 symbol varw  =w12 'temporaire word
 symbol an   =w13 
'****************************************** 
 pause 2000 'temps initialisation LCD
 
 ' Initialisation DS1307
 '%11010000 est l'adresse i2c 
   
 i2cslave %11010000, i2cslow, i2cbyte
  
 Do   'boucle principale
 if valid=1 then gosub init
 
  hi2cin 3,(varb)  ' jour de semaine lu dans le registre 3      
 bcdtoascii varb,dch,ch  ' DS1307 les données sont au format BCD
 serout C.0,baud,(254,128)
 
 if  ch="1" then serout C.0,baud,(" Dim ") 'affichage du jour de la semaine
 elseif ch="2" then serout C.0,baud,(" Lun ")
 elseif ch="3" then serout C.0,baud,(" Mar ")
 elseif ch="4" then serout C.0,baud,(" Mer ")
 elseif ch="5" then serout C.0,baud,(" Jeu ")
 elseif ch="6" then serout C.0,baud,(" Ven ")
 elseif ch="7" then serout C.0,baud,(" Sam ")
 endif 
 
 hi2cin 4,(jour)    ' jour lu dans le registre 4
 bcdtoascii jour,dch,ch 
 serout C.0,baud,(dch,ch,"/")
 
 hi2cin 5,(mois)    ' mois lu dans le registre 5
 bcdtoascii mois,dch,ch
 serout C.0,baud,(dch,ch,"/")
 
 hi2cin 6,(an)    ' année lu dans le registre 6. 
 bcdtoascii an,dch,ch
 serout C.0,baud,("20",dch,ch," ")
 
 serout C.0,baud,(254,192) 
 hi2cin 2,(heure)    ' heure lu dans le registre 2
 bcdtoascii heure,dch,ch
 serout C.0,baud,(254,192,"    ",dch,ch)
 
 hi2cin 1,(minut)    ' Minute lu dans le registre  1
 bcdtoascii minut,dch,ch
 serout C.0,baud,(":",dch,ch)
 
 hi2cin 0,(second)    ' Seconde lu dans le registre  0
 bcdtoascii second,dch,ch
 serout C.0,baud,(":",dch,ch,"    ")   
 loop   ' fin boucle principale
 
'******* Initialisation du DS1307 ************************ 
init: 
 Do: loop while valid=1 'attente relachement poussoir 
 serout C.0,baud,(254,1) 'Effacement écran
 serout C.0,baud,(254,128,"20aa/MM/jj hh:mm ") 'Modèle du format
  
'********* an ***************
 Do: loop while valid=1 'Attente relachement poussoir
 col=194    'Position colonne 1er chiffre
 minch=0:maxch=9  'plage possible chiffre dizaire
 gosub chiffre   'routine affichage
 dch=ch    'mémoire dizaine
 col=195    'position 2ème chiffre 
 gosub chiffre 
 an=dch*10+ch   'nombre année
  
'******* mois ********
 col=197
 minch=0
 maxch=1
 gosub chiffre
 dch=ch 
 col=198
 if dch=0 then
  minch=1:maxch=9
   else
  minch=0:maxch=2   
 endif
 gosub chiffre 
 mois=dch*10+ch
 
'****** jour ********
 col=200  'chiffre des dizaines
 minch=0
 if mois=2 then  
    maxch=2
   else maxch=3
 endif 
 gosub chiffre
 dch=ch
 
 col=201  'chiffre des unités
 if dch=0 then   'si chiffre des dizaines = 0
    minch=1 'pas de 00
   else minch=0
 endif
 if mois =2 then 'traitement février
   varb=an//4 
   if varb=0 then   'année bisextile
      maxch=9 'max 29
     else maxch=8 'sinon 28
   endif
 endif
 if mois<>2 then 'traitement non février
   maxch=9
   if dch=3  then
    if mois=4 or mois=6 or mois=9 or mois=11 then
       maxch=0 'mois de 30j
     else maxch=1 'sinon 31j
    endif
   endif
 endif
 gosub chiffre 
 jour=dch*10+ch
 
'******** heure **************
 col=203
 minch=0
 maxch=2
 gosub chiffre
 dch= ch
 col=204
 minch=0
 maxch=9
 if dch=2 then
  maxch=3 
 endif
 gosub chiffre
 heure=dch*10+ch
 
'******** minutes **********
 col=206
 minch=0
 maxch=5
 gosub chiffre
 dch= ch
 col=207
 minch=0
 maxch=9
 gosub chiffre
 minut=dch*10+ch 
 
'***** calcul joursem ****************
 'L'algorithme de Mike Keith numérote de 0 à 6
 'Dim=0, Lun=1,...,Sam=6
 
 an= 2000+an 
 if mois < 3 then
    varw=an-1
   else varw=an
 end if 
 joursem= 23*mois/9 +jour+4+an
 w10=varw/4
 joursem=joursem+w10
 w10=varw/100
 joursem=joursem-w10
 w10=varw/400
 joursem=joursem+w10
 if mois>= 3 then
   joursem=joursem-2
 endif
 joursem=joursem//7+1 '+1 pour numérotation de 1 à 7 idem DS1307
 varb=joursem  'mémorisation dans une variable type byte
'***********************************************
 dch=minut//10  'Les données sont
 minut=minut/10*16  'mises au format BCD
 minut=minut+dch  'pour enregistrement
 dch=heure//10
 heure=heure/10*16
 heure=heure+dch
 
 dch=jour//10
 jour=jour/10*16
 jour=jour+dch 
 
 dch=mois//10
 mois=mois/10*16
 mois=mois+dch
 
 an=an-2000
 dch=an//10
 an=an/10*16
 an=an+dch  
 
 hi2cout 0, ($00,minut,heure,varb,jour,mois,an,%00010000) 
 return
 
'******* Sous programme affichage et incrémentation *************** 
chiffre:
 
 ch=minch  
 Do
  serout C.0,baud,(254,col,#ch)
  if increm=1 then   
   do:loop while increm=1   
   inc ch
   if ch>maxch then
    ch=minch
   endif  
  endif    
  if valid=1 then exit
 loop  
 Do: loop while valid=1  
 return
 
A suivre... 
 
 
 
 
 

Partager cette page

Repost 0
Pour être informé des derniers articles, inscrivez vous :