Programmateur Tiny DS1307 pour PIC (ou Autre µ)
CHAPITRE 1
1 Diagramme général du procédé
2 Particularités
2.1 Principes
2.2 Open Collector ou Drain (OC / OD)
2.3 Les accus
2.4 Convertisseur de tension
2.5 ICSP
2.6 Le DCF77
2.7 U4224B et DCF77
2.8 Le programme PIC16F690 avec OD
2.8B Le programme PIC16F690 avec "TRIS"
3 Le Tiny Module DS1307
3B Le Tiny Module DS3231
4 Schéma de l'outillage ancien modèle
4b Schéma avec les "TRIS"
5 Montage avec DS1307 Seul
6 Conclusions
CHAPITRE 2
1 Conventions I2C
2 Conventions DCF77
3 Les routines I2C
4 Lecture date heures DS1307
Si vous arrivez directement sur cette page par un moteur de recherche, vous pouvez avoir accès à la table des matières et à chaque article, en page d'accueil. L'accès se fait par l'un des deux liens en tête de colonne de droite ----->
ATTENTION à compter du 15/09/2019 les commentaires ne seront plus possibles à causes de quelques imbéciles qui font du spam pour le plaisir de nuire ! désolé !
Avant Propos
En terminant la mise au point du tracker photovoltaïque, j'avais évoqué la possibilité de mettre le processeur PIC en mode SLEEP durant la journée, entre 2 commandes moteurs distantes de 4 minutes….
(SLEEP = état inactif, faible consommation d'un processeur)
Et ce n'est pas la première fois que l'on n'a aucune raison de rester "éveillé", mais le grand problème est que si on passe en SLEEP, l'horloge du PIC avec Timer 0 est arrêtée, et on perd donc l'horloge !
La seule solution est d'avoir une horloge temps réel externe et particulièrement économe en énergie. Cependant cette horloge doit aussi être permanente, rapide d'accès, secourue et durer de nombreuses années tout en gardant tous les éléments de calendrier et d'heures sans avoir à les calculer ou les recharger durant un temps très long.
Cette possibilité existe avec des petits modules à base de DS1307 (Tiny module RTC), et qui pourraient seconder très efficacement un PIC "en mal de sommeil". On trouve ces modules chez les Chinois et ceux que j'ai commandés sont de bonne facture… Dommage que l'on ne soit pas en mesure de les acheter chez nous (Le seul magasin de composants de mon secteur a fermé ses portes, quel dommage !)
Ces modules sont en protocole I2C, protocole que je connaissais seulement de nom. Mais ce protocole n'est pas trop facile à priori, tant en hard que soft, et de plus il faut pouvoir prendre (Physiquement) un tel module horloge ayant déjà eu sa programmation du temps en dates et heures et l'implanter dans le montage cible.
Des circuits déjà programmés peuvent parfois exister dans le commerce, moyennant un surcoût bien évidemment, mais sur une fausse manip, tout serait à recommencer et obligation d'en racheter un autre !
Non, je crois qu'il faut réellement maîtriser cette programmation initiale et du côté d'une application, il faut les routines pour LIRE en I2C ces données, particulièrement sur des petits PIC ne possédant PAS les modules spécifiques SSP ou mieux MSSP. Un outillage permet aussi de ne pas multiplier les routines spécifiques pour acquérir les données de date et heures avec la précision du DCF ou toute autre référence de radiodiffusion du temps, sur des montages particuliers à base de micro contrôleurs.
Cette programmation a pour but de rentrer les données de date et heure dans le Tiny module qui sera ensuite exploité, sur tout autre montage spécifique qui l'utilisera comme horloge RTC (Si c'est sa vocation ?) Cette utilisation permet alors l'arrêt en SLEEP d'un processeur avec de bonnes économies d'énergie en pouvant relire très rapidement l'heure sur le module.
Enfin cette façon de voir les choses est également le fruit d'une expérience toujours délicate concernant la réception du DCF77 suivant les conditions de propagation, qui sont assez variables et particulièrement en intérieur. (On peut ajouter que le DCF77 à 77.5KHz n'est pas présent partout dans le monde car il y a d'autres étalons mondiaux de temps, (Tous ne sont pas accessibles : WWVB 60 kHz, JG2AS 40 kHz…et certains arrêtent de fonctionner comme HBG en Suisse, car trop coûteux !)).
Quoi de plus simple que de garder en permanence l'heure et la date sans avoir à tout refaire les calculs de dates, jour de semaine et heures, durant une bonne dizaine d'années sans rien faire d'autre que d'utiliser une petite pile CR2032 et la lecture de 8 octets...(Encore que...à vérifier !... On verra qu'il y a d'autres problèmes...)
Je pense que c'est réellement très utile, avec la petite restriction que dans le cas d'un PIC sans les modules I2C (SSP et MSSP ), il faut 2 I/O standard en OPEN COLLECTOR (OC), pour l'I2C mais parfois en plus une I/O supplémentaire (Pour lire les ACK ou NACK sur la ligne SDA), mais avec la possibilité de connecter d'autres périphériques I2C !)
Il y a donc deux volets à cet article :
- La partie création d'un outillage de programmation des modules I2C DS1307 sur la base d'une mise en œuvre initiale du temps par le DCF77 (On pourrait cette fois choisir un endroit de bonne réception avec un outillage mobile et autonome). On évoquera aussi pour l'occasion, la réparation d'un récepteur DCF77 avec un circuit existant évitant le rebut du récepteur en panne.
- Le deuxième volet consiste en la mise à disposition des séquences de lecture du temps sur le Tiny RTC DS1307 sous forme de routines à inclure, mais avec une conversion BCD binaire de toutes les valeurs, car le DS1307 stocke des valeurs BCD.
Dans ces conditions rien n'empêchera alors de placer un PIC en SLEEP, lors de son réveil par une INT ou par le biais de l'ULPWUE et de le remettre à l'heure en quelques centaines de µs. Les valeurs internes de l'horloge du PIC, et les valeurs BCD seront mises à jour, sans attendre de longues minutes la synchronisation du DCF77 (Quand il veut bien fonctionner en intérieur des habitations !).
Il y a donc lieu de commencer par la création d'un OUTILLAGE de programmation à base d'un PIC 16F690 et d'un récepteur DCF77, pour un premier Tiny module DS1307 et d'obtenir sans erreur et avec précision les valeurs de date et heures. Ces valeurs pourraient alors être maintenues par quartz sur l'outillage, sans avoir à reprendre le DCF77, (Au moins durant une journée).
A l'extrême limite, (Mais ce serait un peu moins précis) il devrait être aussi possible de rentrer dates et heures manuellement à l'aide de l'encodeur en quadrature et de se passer ainsi du DCF77. cette possibilité a été implémentée !
(Cette possibilité se serait révélée très utile lors de la mise au point du "tracker photovoltaïque" pour simuler toutes les dates clefs de l'année et vérifier le bon fonctionnement)
Cet outillage servira donc à programmer en I2C sans les facilités des modules MSSP, ce qui permettra avec peu de travail de mettre en œuvre les routines de lecture des modules utilisés dans des applications avec de petits PIC.
En écriture I2C, le module SSP ne servant pratiquement à rien (Aux dires de quelques commentaires glanés sur le Net), je m'en suis passé ce qui m'a évité de potasser les registres pas toujours trop explicites pour le profane de l'I2C dont je fais partie.
Cet outillage peu utilisé (Pour nous particuliers bricoleurs) sera simplement alimenté par un accu Lithium 18650 avec un petit convertisseur 3.7V vers 5V et devrait cependant confirmer visuellement sur écran LCD, les bonnes valeurs reçues du DCF77, avant de lancer des programmations de modules DS1307.
Cet article traite donc en chapitre I cet outillage chargé de récupérer l'heure par le DCF77, de l'afficher et de programmer en I2C les Tiny modules DS1307.
Il décrira en chapitre 2 les routines programme de lecture du module I2C DS1307 en assembleur sans l'utilisation des facilités des modules PIC MSSP.
Plusieurs programmes assembleur pour des PIC 16F628 existent sur le NET et je m'en suis largement inspiré pour ne pas refaire le monde et j'y ajouterai les routines de conversion. C'est sur un site non retrouvé depuis, que j'ai eu le plus d'éléments assembleur issus de l'auteur Pierre COL. Un Merci particulier à lui ! Malheureusement dans le désordre Internet je n'ai pas pu retrouver le site d'origine des routines publiées ! (Son nom et des adresses inactives figure en tête des routines)
J'ai aussi lu avec intérêt l'introduction au bus I2C de Camille DIOU. Merci également à lui et à d'autres sites comme http://projet.eu.org/pedago/sin/term/8-bus_I2C.pdf qui démystifient le sujet.
Cet outillage assure la programmation des modules enfichés sur l'outillage, la vérification par lecture de ces mêmes modules. Il devra y avoir aussi des possibilités de rentrer des valeurs ou des commandes, ainsi que d'afficher différents éléments. Pour cela un encodeur en quadrature permettra de prendre le contrôle de l'outillage et de lancer les différentes commandes.
Tant que l'on y est, on réservera une sortie RS232 peut-être simplement pour la mise au point et si besoin en était de récupérer l'I/O ...?
Le tout sera agrémenté peut-être d'une simple LED pour attirer l'attention en cas de problème. Cela conduira à établir le diagramme général du paragraphe suivant…
Enfin tout ceci implique que le Tiny module soit enfichable… sur le codeur mais aussi sur le montage destinataire !
NOTA : Lorsqu'il sera fait référence à un Open Collector cela vaudra tout autant pour un OPEN DRAIN dans le cas des CMOS.
1 Diagramme général du procédé
2 Particularités
2.1 Principes
Je rappelle que le but de cet outillage est de programmer date et heure sur un Tiny module équipé d'un circuit intégré DS1307 avec sa petite pile CR2032.
Voir le datasheet de ce circuit : https://datasheetspdf.com/pdf-file/925278/Maxim/DS1307/1 pour les différentes adresses internes du circuit. (Une seule adresse (Zéro) suffira cependant pour recevoir en séquence les 8 octets nécessaires).
Le module sera ensuite retiré de l'outillage codeur et rejoindra un appareil cible quel qu'il soit et permettra à ce nouveau circuit cible de disposer des dates et heures en un temps très court de quelques centaines de µ secondes sans avoir à les rentrer ou attendre la synchronisation (Aléatoire*) DCF77 de quelques minutes. La seule obligation est de lire en protocole I2C, 8 octets sur le module "Tiny RTC" pour obtenir date et heure en format BCD.
On considèrera que le Tiny module équipé aussi d'un quartz horloger est suffisamment stable et précis pour tenir les valeurs de temps sur de longues périodes...(On verra par la suite, qu'il y a beaucoup de divergences...)
C'est un PIC 16F690 qui va être le chef d'orchestre de cet outillage. Le module à programmer, sera obligatoirement amovible par un petit connecteur au pas de 2.54 qui équipe aussi l'outillage lui-même et le montage cible. (L'outillage sera toujours maître et le Tiny l'esclave tant sur l'outillage que sur la cible).
Il aurait peut-être été possible d'utiliser le module SSP du PIC 16F690 pour traiter, mais devant le manque d'habitude et de clarté des opérations j'ai préféré déclarer forfait. Les I/O ont malgré tout été prévues en ce sens et pourraient devenir les bonnes I/O en SSP.
Je n'ai pas utilisé ce module SSP du PIC car cela me paraissait trop "indigeste", et cela permettait aussi de préparer les sous programmes pour les petits PIC sans SSP ou MSSP, et un excellent exercice au novice que je suis pour appréhender le sujet I2C au niveau le plus bas.
(Je vais cependant reprendre un peu ce sujet maintenant que l'outillage est terminé, car le fait d'être en SSP crée de fait des Open Drain et cela facilite largement le Hardware)
L'outillage équipé (ou non) d'un premier module à programmer devra être mis à l'heure une fois par jour à partir du DCF77 ! Plusieurs modules pourraient ainsi être programmés en séquence, et à priori sur une seule opération journalière DCF77. La continuité de précision du temps étant alors assurée par le quartz du PIC et la gestion précise des Interrupts horloge PIC. (La précision de programmation ne pourra être assurée que par une synchronisation toutes les secondes avec le léger retard de quelques dizaines de µs dû à la réponse aux interrupts)
La RS232 servira seulement à la mise au point de l'outillage et éventuellement pour diffuser date et heure sous ce protocole Asynchrone.
L'afficheur sera le contrôle visuel des bons éléments programmés mais servira aussi au dialogue pour assurer les différentes fonctions liées au codage/programmation.
Bien entendu, les différentes opérations se dérouleront de façon séquentielle, et seule les INT du Timer0 seront toujours acceptées en plus des différentes autres correspondant à une opération spécifique. En d'autres termes tous les périphériques ne fonctionneront qu'un seul à la fois.
* J'ai remarqué que le DCF77 est assez sensible aux conditions météorologiques, et à cette fréquence, la propagation des ondes radio est presque toujours en ligne directe sans rebond sur les couches atmosphériques.
2.2 Open Collector ou Drain (OC / OD)
L'I2C utilise des open collector qui peuvent devenir rapidement des entrées et des sorties à la fois, avec la particularité de pouvoir être potentiellement forcés à la masse, mais ne pouvant jamais être "tirés" vers le +.
C'est ce forçage à 0 sur une sortie que l'on devra pouvoir lire rapidement sur la ligne SDA ! c'est le ACK ou NACK suivant le cas...
On remarquera que l'horloge SCL n'est en principe jamais forcée à zéro, et qu'une sortie standard en mode maître (Sous réserve de créer à la suite un simple open collector -sans possibilités de lecture-) est tout à fait possible, (c'est ce qui est réalisé pour l'outillage).
En effet si on recrée un open collector en externe à un PIC, au niveau de la commande en OUT, il faut pouvoir recevoir en même temps les ACK, et cela n'est possible qu'avec une entrée en // sur l'open collector, d'où ces 3 I/O nécessaires.
On verra par la suite que j'ai abandonné ce principe des Open Drain et refait le hardware et le programme en conséquence, voir §4B
Certains PIC 16873 16F877 16F628 et 16F84 (et tous ceux que je ne connais pas…), ont UNE sortie OC et peuvent donc avec un simple buffer OC pour SCL, traiter le problème de lecture écriture sur la ligne SDA, par un simple retournement du TRIS correspondant. L'OC manquant pour SCL devra être traité par un buffer non inverseur OC. (Dans cette situation 2 I/O suffisent mais avec un buffer OC non inverseur en plus pour SCL). En réalité il n'y a même pas besoin d'un OC pour SCL, car on procédera comme pour SDA avec les "TRIS"
Il reste à vérifier que dans le cas d'un PIC avec au moins le module SSP, le simple fait de passer en I2C permet de valider les deux I/O I2C en open collector et de permettre ainsi de se passer d'une I/O supplémentaire ainsi que de l'utilisation d'un circuit complémentaire non inverseur en OC. Ceci est indiqué dans le data sheet du 16F690....
J'ai développé l'ensemble du premier logiciel avec 2 MOSFET_P en OC dont l'un est doublé en sortie d'une entrée pour SDA pour les raisons qui suivent :
Si toutes fois on pouvait se passer de ces 2 MOSFET_P ce serait très bien car il subsiste vers le niveau zéro, 0.7 à 0.8 V de déchet, ce qui me gêne dans le principe, mais cela n'affecte pas le fonctionnement heureusement. Je crois que je vais faire cet essai en faisant très attention de ne pas me prendre les pieds dans le tapis et en créant une version séparée…. A suivre !...
C'est fait ! Après quelques essais, il semble qu'il faille également composer avec les obligations afférentes à L'I2C, car je n'ai pas pu en "pseudo statique" vérifier que l'on était en open collector en utilisant le SSP.
Avant de commencer les essais je me suis posé la question de savoir comment reconnaître réellement si une sortie est bien positionnée en open collector ? Cela ne me semblait pas trop évident à moins que…
Les résistances Open sont dans notre cas situées sur le Tiny module, aussi si l'on considère une sortie Open Collector sans rappel au Vcc, le fait de lui adjoindre une résistance "pull down" à la masse et de commander la sortie à 1 logique ne devrait rien donner en tension de sortie. On ne travaille donc que sur l'outillage sans Tiny
Le principe des MOSFET_P en tête des pull up (côté Vcc), pour éviter de doubler un étage afin de retrouver la bonne polarité n'est pas parfait, mais j'ai commandé des 74LVC07A qui peuvent permettre avec des petits PIC de fonctionner sans SSP, car pour éviter cette tension de déchet, je n'ai pas d'autre solution que d'utiliser de véritables buffers MOSFET non inverseurs Drain ouvert. Ce circuit ultra faible consommation convient parfaitement à cette opération.
Dans cette idée d'utiliser une partie du SSP uniquement pour la mise des I/O en collecteur ouvert, après quelques essais succins, j'ai donc constaté que les sorties ne fonctionnent pas correctement si on essaye de les faire "bagoter" en statique.
Alors mauvaise manip ou réalité ? Je ne sais pas vraiment, aussi j'ai persisté à tort d'utiliser le mode programmé avec 3 I/O, ce qui m'évite de m'engluer dans des registres particuliers avec des restrictions et obligations assez compliquées et inconnues.
On connaît le principe de l'I2C, alors autant le réaliser en mode programmé, d'autant que ce n'est que pour 8 octets, et de façon très occasionnelle, tant en écriture du module que pour sa lecture.
Le fonctionnement avec MOSFET_P ou transistor PNP est opérationnel, mais n'est pas électriquement satisfaisant. Aussi je préconise d'utiliser un 74LVC07A en lieu et place de ceux-ci, mlais plus encore il s'avère nécessaire de simplifier en utilisant les "TRIS".
2.3 Les accus
J'ai prévu que cet outillage fonctionne sur un seul accu Li-ION de 3.7V et qu'il soit mobile (Pour recevoir le DCF77dans de bonnes conditions). Il utilise un petit convertisseur 3.7 vers 5V. Cette tension de l'accu sera contrôlée à l'allumage de l'outillage.
(On peut voir sur la photo ci-contre le gros élément 18650 qui alimente l'outillage et la pile du petit module Tiny en place. On peut voir aussi le quartz 8MHz, un condensateur de découplage de 10nF sur le PIC, ainsi que les 2 gros chimiques de l'alim et l'interrupteur général)
Un autre accu cette fois beaucoup plus délicat était prévu sur chaque module Tiny DS1307. J'ai bien dit ACCU et NON PILE. Pour l'utilisation d'une simple pile, j'ai pu trouver une parade sur Internet avec une modification (partielle) mais insuffisante dans la mesure où le test de la pile devrait être réalisé tant sur l'outillage, qu'éventuellement sur l'appareil destiné à recevoir le module Tiny DS1307. (Voir § précédents)
La raison principale est qu'à l'origine ce module est prévu pour un ACCUMULATEUR LI-ION (LIR2032) et NON pour une pile CR2032.
Dans le cas d'une pile, ce qui est le plus courant, celle-ci conviendrait largement pour une bonne dizaine d'années.
Dans le cas d'une pile il faut donc modifier ce circuit Tiny suivant le plan trouvé sur …. ces sites ou suivant le schéma repris pour être plus explicite.
https://www.electronique-mixte.fr/wp-content/uploads/2018/07/Formation-Interface-communication-50.pdf
https://www.pleguen.fr/index.php/arduino/modules/horloge-temps-reel-ds1307
https://www.vs-elec.fr/fr/minuterie-horloges/2109-module-horloge-temps-reel-ds1307-3665662013811.html
Mais ATTENTION cela ne suffit pas dans le cas où l'outillage ou l'appareil destinataire du module est hors tension. Dans ce cas précis c'est la pile qui réalimente partiellement l'outillage ou l'appareil si vous aviez pris le loisir de contrôler la tension de la pile avec une entrée ANA. ( Cette entrée ANA n'est plus réellement une entrée ANA lors d'une mise hors tension ! C'est simplement quelques composants sans fonction réelle avec des fuites à tous les niveaux)
Je m'en suis rendu compte accidentellement en ayant des difficultés pour une remise sous tension avec un re-départ incorrect du PIC réalimenté faiblement par la pile du Tiny module (par l'entrée ANA)
Si on veut mesurer par une entrée ANA la valeur de la pile, il est donc nécessaire de limiter ce courant de fuite par une résistance suffisante (510K) qui permette cependant la mesure de tension mais ne pouvant réalimenter tout montage (par une entrée !)
La mesure de la tension ANA ne peut se faire qu'en prenant un "TAQ" très important et de placer un condensateur réservoir aux bornes de l'entrée BAT (côté outillage et/ou montage cible).
Je pense que le contrôle de cette tension de pile est un peu superflu et n'a pas lieu d'être réalisé sur le montage cible recevant le module DS1307.
Tous les 10 ou 15 ans on change la pile et ça devrait suffire.
(Les changements de pile du Tiny peuvent (Et doivent) se réaliser avec les montages sous tension si l'on ne veut pas perdre date et heures).
Il est seulement important et suffisant de contrôler cette pile lors du "codage" du module, pour garantir sa longévité de 10 à 15 ans.
La stabilisation de la tension après les 510K sur le Tiny module est maintenue par un petit condensateur de 10nF sur l'outillage qui permettra au PIC de charger son propre condensateur de mesure ANA sans faire chuter la tension à mesurer.
Pour plus de précisions sur cette correction pour pile CR2032 voir au § 3
Un petit complément cette fois l'autre composant RTC : le DS3231 qui lui aussi est alimenté par un accu de secours LIR2032, mais si vous utilisez une pile CR2032, il faut enlever la diode de charge minimelf.
2.4 Convertisseur de tension
L'outillage est alimenté par un seul accu LI-ION type 18650 de 3.7 à 4.2V mais doit être alimenté en 5V, aussi un convertisseur est nécessaire. Cet accu est situé sous le CI et est visible sur les photos (couleur rose sur la photo précédente)
La tension de 5V est nécessaire tant pour la norme I2C que pour le display qui est en 5V.
Ce petit convertisseur d'origine Chinoise de quelques Euros a cependant un inconvénient sérieux, car il lui faut un excellent filtrage, tant les spikes de tension sont importants. Il faut également doubler l'accu LI-ION par un condensateur, car bien que la résistance interne d'un tel accu soit excellente elle reste insuffisante pour des pics de courant très étroits.
L'angle d'ouverture de conduction est très étroit et l'intensité (Non mesurée) certainement très importante également.
Il y a donc 470µF en // sur l'accu et 1000µF sur le 5V (+ 0.1µf pour la HF). C'est du sérieux pour quelques mA seulement !
La règle empirique de 1µF par mA est totalement bafouée, mais ce n'est pas grave en soi, dans la mesure où le convertisseur accepte les pics de courant sans "broncher", ce qui semble le cas.
En effet, au pire si ce circuit venait à griller, le risque est seulement de retrouver une tension moindre, c'est-à-dire environ 3.7V à 4.2V ! Donc pas de quoi s'affoler !
2.5 ICSP
L'ICSP est prévu par un connecteur mais ne m'a pas servi. En effet j'ai utilisé un PIC 16F690 DIP20 et ça été plus facile de coder directement le PIC sur un support ZIF, car en ICSP il faudrait retirer impérativement les modules encodeur et DCF77 car ils utilisent les lignes de l'ICSP (Vpp, ICSPDAT et ICSPCLK).
Cela reste possible si on a mis l'encodeur et le DCF sur connecteur. C'est toujours le cas pour le DCF mais il fallait penser à l'encodeur et ne pas le souder !!! !...
2.6 Le DCF77
C'est l'organe d'entrée de la date et de l'heure qui garanti l'exactitude des valeurs et la précision. (Photo du modèle revisité photo ci-contre et voir aussi le § suivant)
J'avais développé ce module programme DCF77 depuis très longtemps et il avait nécessité pas mal de travail. Je l'ai repris dans ce contexte avec simplification en page 0 et surtout pour ajouter une sortie complémentaire impérative en mode BCD dans un buffer pour pouvoir être introduit dans le Tiny module DS1307 qui demande ce format de données.
En outre par rapport au DCF, il faut entrer les secondes qui ne figurent pas en clair en DCF77, mais elles seront mises à zéro lors de la 2ème impulsion manquante avec la minute+1 (au front suivant).
De plus, les jours de la semaine et les jours du mois sont inversés dans les deux systèmes, DCF et Tiny DS1307. Il faut donc les remettre en ordre pour le Tiny module.
Enfin, les valeurs du DCF77 restent converties en binaire à partir du label "minutes" pour le programme du PIC.
L'horloge PIC reste bloquée lors de l'exécution de la routine DCF, mais est validée à la fin de la trame synchronisée pour maintenir l'heure sur le PIC.
Les valeurs binaires et BCD seront maintenues (Seulement durant une seule journée) par l'outillage PIC pour permettre le codage de plusieurs Tiny modules sans avoir à reprendre une synchronisation DCF. (Ceci est nécessité par la non gestion de la date)
L'étiquette du Buffer BCD est "BUF77" avec l'ordre des données du circuit DS1307 remis dans le bon ordre juste au moment de l'impulsion manquante de fin DCF77.
Le byte de contrôle d'adresse 0x07 du Tiny module, est prévu en écriture pour que le module fournisse en plus un signal à 1 Hz sur la sortie SQW/OUT en pin 7 du DS1307 ou sur la borne "SQ" du Tiny module.
2.7 U4224B et DCF77
Ce paragraphe mériterait un petit article, mais on fera au plus simple et en complément logique de cet article ...
J'avais malencontreusement fait un mauvais branchement sur un module DCF77 complet avec antenne ferrite, et il n'a pas résisté !
Vu le prix élevé de ces modules DCF77, j'ai voulu réparer mon erreur et je me suis tourné vers un circuit intégré existant qui est capable de s'adapter à tous les émetteurs de 77.5 KHz à 40 KHz.
Ce circuit est le U4224B de TEMIC ! Le principe est quasiment le même que feu le module acheté, aussi cela me permet de garder l'antenne ferrite et le quartz à 77.5 KHz, éléments que l'on ne trouve pas facilement ou à des prix prohibitifs. (Y compris le condensateur d'accord de l'antenne ferrite qui est apparié avec celle-ci).
J'ai donc réalisé un tout petit circuit imprimé avec le U4224B avec les principaux éléments n'ayant pas souffert du défunt DCF77 : antenne ferrite accordée et quartz pour les principaux ! Tout marche bien !
Ce circuit consomme très peu (21µA mesurés) et demande seulement 2 secondes de temps de démarrage. Il a de plus une pin POWER_ON (PON) qui permet de réduire encore la consommation à 100nA !
J'ai seulement appliqué avec succès le montage indiqué sur la documentation spécifique au DCF77, car ce circuit est compatible avec plusieurs émetteurs mondiaux en très basse fréquence.
J'ai ajouté un MOSFET_N pour avoir la sortie inversée. Ce montage donne donc au choix une sortie normale ou inversée.
(A noter que la sortie "normale" doit être bufferisée par un MOSFET car le courant pouvant être fourni est très faible (Il écroule le signal sur un simple transistor avec une résistance de base de 100K !))
Le circuit correspond exactement à la notice du U4224B, je n'ai donc pas fait de nouveau schéma, et j'ai juste ajouté le MOSFET_N (U2) avec 1.5K en gate et 10K à 33K en drain, comme c'est d'ailleurs indiqué dans le datasheet. Voici le lien pour ce datasheet :
https://datasheetspdf.com/datasheet/U4224B.html
Voici le schéma du circuit et le typon (1000 dpi en miroir) pour ceux qui veulent le reprendre tel quel.
Ainsi que je l'ai indiqué dans l'article sur le tracker, je recommande un MOSFET en lieu et place d'un transistor NPN, car cela écroule trop le signal ! Il faut une entrée MOS dans le cas où on veut utiliser le signal direct.
Ce circuit donne sur le connecteur la sortie normale et la sortie inversée ainsi que la commande POWER_ON* (Active à 0)
(Si vous n'utilisez pas cette commande POWER, mettre cette pin à la masse par un petit strap sur le run juste au dessus)
(Le Quartz est prévu dans 2 positions, soit comme représenté couché sur le U4224 ou perpendiculairement couché sur le transistor MOSFET. Ceci à cause des longueurs de fils pas toujours faciles à reprendre des anciens montages).
2.8 Le programme PIC16F690 avec OD
Il est maintenant terminé et j'ai mis 6 commandes en 2 groupes, choisies par l'encodeur en quadrature. Les routines I2C sont figées et ont fonctionné du premier coup, ce qui est assez rare dans une première réalisation... Mais il faut l'abandonner pour la partie I2C !
J'ai en effet abandonné le hardware avec OD pour utiliser les "TRIS". C'est dommage mais c'est ainsi, car j'ai eu beaucoup de difficultés avec les nouvelles routines I2C....
Actuellement il était donc composé d'un premier menu à 4 possibilités à savoir lire l'heure au DCF77 écrire en I2C le Tiny module, le lire en I2C et "AUTRES" qui renvoie vers le deuxième menu.
Ce deuxième menu comporte seulement 2 entrées : Affichage du buffer BUFF77 et Entrée manuelle de date et heure y compris le byte de contrôle du Tiny/DS1307.
Le programme débute par une initialisation et la mesure de la tension de l'accu de l'outillage. La valeur est affichée au display. Une deuxième mesure est faite en séquence avec la mesure de la tension de la pile du Tiny module. La tension du Tiny module n'est pas rédhibitoire. Cette valeur sera également affichée au display mais dans le cas où elle se situe en dessous de 2.0 volts, un message "Pile low" est affiché. (Valeur limite indiquée par le datasheet)
Le programme a été modifié pour aller directement sur le menu, car cela permettra d'interroger un Tiny module sans avoir à se synchroniser sur le DCF77.
Il est maintenant possible de rentrer manuellement date et heure avec l'encodeur, pour pouvoir vérifier certains programmes avec des dates précises, ce qui me semble très utile, notamment dans la partie des calculs solaires ou astronomiques.
Les 3 entrées principales du menu génèrent un affichage clair de l'heure. Le DCF77 affiche en cours 2 digits par 2 digits des informations reçues, avec dans l'ordre un S pour indiquer la synchronisation suivi des minutes, heures, jour du mois, jour de la semaine, mois et année. La fin est clôturée par un "Z". L'ordre est donc spécifique du DCF77, mais le buffer BUF77 est chargé avec les bonnes valeurs (BCD) et dans le bon ordre pour le Tiny et son circuit DS1307
J'ai pu contrôler la précision de l'heure maintenue par le PIC de l'outillage grâce au quartz. J'ai constaté 2 à 3 secondes de décalage en 12 heures de fonctionnement. Cet écart de temps semble incontournable et est donné par la seule précision du quartz. Ce fait me conforte dans l'aspect évoqué de se resynchroniser au moins une fois par jour sur le DCF77. Je pense que ce sujet de la précision des quartz fera l'objet d'un petit complément, car avec 4.7 pf en // sur les quartz, j'ai déjà fortement amélioré cet écart (C'est en cours d'essais actuellement)
Le Quartz du Tiny module est dans le même sujet et j'espère aboutir à une solution acceptable.
Le menu d'affichage ainsi que le menu d'écriture se font juste après le changement de seconde sur le temps du PIC pour la meilleure précision possible relativement à l'origine DCF77. Le timer zéro est remis à zéro ainsi que le comptage de base en 25ms. Toute éventuelle interruption pendante est également fermée.
Toute écriture I2C commence par le contrôle de la pile CR2032 et après synchronisation à la seconde, l'écriture réelle I2C. Il n'est donc plus nécessaire de contrôler la pile en début de programme, mais seulement à cet endroit. Cela permet de débuter le programme sans la présence d'un Tiny module. Ce contrôle initial a cependant été maintenu, mais une tension faible n'est plus bloquante et est seulement indiquée (Absence Tiny module).
Le menu d'affichage est devenu "Autres" avec 2 sous menus dont l'affichage et l'entrée manuelle des données de date et heures avec l'encodeur en quadrature.
2.8B Le programme PIC16F690 avec "TRIS"
Ce programme structurellement est très peu différent de celui d'origine au niveau des commandes, mais il a nécessité beaucoup de temps pour sa mise au point à cause d'une particularité qui est la suivante :
Il est évident que les retournements d'entrée et de sortie de bits de ports sont récurents et que l'on est tenté de créer des macros. C'est ce que j'ai fait, mais mal à propos. En effetlorsque vous utilisez une macro, votre programme indique une seule ligne pour peut-être plusieurs lignes et instructions.
Si vous ne faites pas attention à cela, vous allez aller droit dans le mur, ce que j'ai fait en toute confiance, car après avoir modifié le hardware en supprimant les open-drain et confiant dans ce programme qui fonctionnait bien, j'ai longtemps cherché ...
Le sujet est simple, derrière un test on ne peut pas pas mettre une macro, car suivant le résultat du test on ne fait pas dfu tout ce qui est prévu ! mais n'importe quoi en sautant ou non la première instruction du groupe d'instruction macro.
J'ai également préparé la programmation pour obtenir les signaux SQW ou SQWE et 32K pour les modules DS1307 et DS3231. Ce programme est donc tgalement compatible pour ces deux modules.
Inutile de dire que la version Open Drain est obsolète !
3 Le Tiny Module DS1307
Il vient de Chine et outre le circuit DS1307 d'horloge, il comporte également une EEPROM 24C32 accessible suivant le même principe I2C à l'adresse 0x50 (7 bits) (ou 0xA0 8 bits en écriture)
Le DS1307 est accessible à l'adresse I2C 0x68 (7 bits) (ou 0xD0 8 bits en écriture)
La modification pour traiter la sauvegarde avec pile CR2032 a été indiqué précédemment.
Il faut supprimer les résistances R4 et R5, remplacer R6 par une résistance 0 ohms, et insérer sur la sortie BAT la résistance de 510K.La diode doit également être supprimée. Quoi de mieux qu'un schéma plus précis que ceux que j'ai pu voir...
Vous pouvez aussi utiliser le circuit en natif si vous utilisiez un accu LIR2032 qui est la version rechargeable du CR2032, mais dans ce cas le Tiny module devrait être mis plus souvent sous tension pour recharger ce mini accu, car au final, c'est la consommation du pont diviseur 510K 1.5M qui obèrera la longévité du maintien de la date et de l'heure. Cette consommation n'est pas négligeable.
L'esprit de ce montage (pour "bricoleurs") fait qu'il sera utilisé une ou 2 fois par année ??? Peut-être ? Et qu'une pile est quasiment rendue obligatoire (Dans ce contexte !)
La modification suivant le schéma relevé est tout à fait correcte SI le circuit "BAT" reste en l'air, car autrement il risque de RÉalimenter l'outillage ou un autre circuit d'utilisation, par le biais de l'entrée ANA (d'un appareil hors tension). (Ce fait a été mis en évidence par un mauvais départ du PIC sur l'outillage !!!)
Si toutes fois vous ne vouliez pas mesurer la tension de la pile, alors le montage avec la modification de base suffit.
Pour insérer la nouvelle résistance de 510K sur la sortie BAT, il faut le faire à raz de la pin de sortie, car autrement le DS1307 serait alimenté au travers de 510K ! (Voir photo ci contre cercle rouge)
On notera que le circuit comporte une sortie "DS" prévue pour un capteur de température DS18B20 (Non présent sur ce module).
Les résistances sur SDA et SCL sont déjà présentes sur le Tiny Module et n'ont donc pas à être installées sur l'outillage.
Le Tiny module dispose d'un double connecteur dont l'un n'a que 5 broches et est plus destiné au capteur de température.
Un lien utile également pour tout ce qui peut se connecter en I2C :
https://www.aurel32.net/elec/i2c.php
3B Le Tiny Module DS3231
Pourquoi un autre module ? Je pense que vous avez pu saisir un élément important qui est la précision du temps. Or ce module DS1307 n'est pas très précis tant en valeur absolue, qu'en dérive en fonction de la température. Le module DS3231 est un oscillateur à base de TCXO, c'est à dire compensé en température. La fréquence d'un quartz diminuerait en fonction de l'élévation de la température, mais ce module à base du DS3231 corrige automatiquement la fréquence en fonction de la tempértature.
Il va de soi que le prix de ce module n'est pas comparable à celui du DS1307.
Mais !...
A ce stade des expérimentations sur le temps, je ne suis plus tout à fait enchanté par le module TCXO, pour de multiples raison. Sa fréquence de base n'est pas suffisamment précise, et je suis arrivé à des valeurs bien meilleures en ajustant le DS1307. Ce DS3231 a le grand désavantage de comporter un élément oscillant interne au circuit intégré, certes compensé en température, mais inaccessible pour ajustement par des condensateurs en // comme pour le DS1307.
Au niveau amateur, la dérive en température a moins d'importance que la précision intrinsèque du temps pour le long terme. Aussi je reste très "mitigé" sur le DS3231.
j'ajoute que le 2 ppm n'est l'objet que de certains modules et que sans faire attention aux indices des composants, on se retrouve vite avec 5 ou 10 ppm, ce qui devient problématique pour des durées de nombreux mois ou années.
4 Schéma de l'outillage ancien modèle
Ce schéma reste simple. On peut y voir les résistances d'Open Collector mises en dehors du circuit puisqu'elles sont sur le Tiny module, on remarque également les 2 MOSFET_P sur les sorties PIC et la lecture sur la sortie SDA avec la 3ème I/O.
En ce qui concerne l'encodeur en quadrature, j'en avais réalisé un sur la base de petits PIC, mais j'ai retenu celui de la revue Elektor d'octobre 2016, et je vous y renvoie pour ne pas plagier ce montage qui a le mérite d'être simple et de bien cadrer avec le principe des petits encodeurs à switch du commerce.
4B Montage avec les "TRIS"
Ce schéma est peu différent de l'autre et comporte principalement les modifications pour SDA et SCL
5 Montage avec DS1307 Seul
Si vous aviez déjà installé le seul circuit DS1307 sur votre montage, alors vous pouvez éviter de traiter la mise à l'heure dans votre programme en utilisant simplement quelques fils depuis le bus I2C de votre montage vers le bus de l'outillage. C'est en quelque sorte un "pseudo ICSP" pour la mise à l'heure.
Si vous aviez déjà un DS1307, c'est que vous pratiquez l'I2C peut être pour d'autres périphériques. Il est fort probable que vous ayez déjà les résistances des Open Collector. Si ce n'était pas le cas, alors il faudra les mettre, peut être au niveau des fils de raccordement.
Il va de soi que vous devrez mettre un connecteur sur votre montage qui donnera accès aux deux lignes SDA et SCL référencées à la masse et il serait bon également, outre la masse, de prévoir un fil pour le Vcc pour raccorder les 2 résistances au cas où… !
Cette possibilité reste très marginale, car en principe vous avez du prévoir la mise à l'heure, mais on ne sait jamais, car ce programmateur peut éviter quelques lignes de programme et cela peut être intéressant pour disposer d'une mise à l'heure précise issue du DCF.
Il est évident que dans ce cas, il sera nécessaire que le montage de l'utilisateur ait prévu le maintien de l'énergie pour garder les éléments de date/heure. Cette énergie pourra dans ce cas être soit une pile CR2032 soit un accu LIR2032 et la méthode d'alimentation de l'entrée BAT du DS1307 devra avoir été prévue.
6 Conclusions
D'une façon générale, je crois que les électroniciens n'aiment pas trop voir la "partie énergie" se trouver sur les circuits imprimés, du moins (c'est mon cas !). Alors utiliser un module externe sur le circuit imprimé d'une application est une solution acceptable. C'est la raison pour laquelle je trouve cette solution du Tiny module intéressante pour plusieurs raisons.
J'ai parlé d'années voire de dizaines d'années avant de changer de pile, et c'est peut-être vrai pour cette partie énergie, mais au bout de ces années qu'en sera-t-il de la date et de l'heure ? Combien de minutes, heures, voire de jours de décalage se seront produits ? C'est là le principal écueil auquel je n'avais pas véritablement songé, mais qui m'est revenu avec acuité lors d'une vérification faite seulement 12 heures après une mise à l'heure sur l'outillage !
Certes, ce n'est pas encore le drame absolu, mais c'est un vrai problème que j'avais souvent supposé sans jamais avoir mis véritablement le doigt dessus. En effet sur les panneaux solaires, j'avais toujours prévu de faire la mise à l'heure journellement, car je pensais que l'horloge PIC (Horloge interne de type RC) n'était pas suffisamment précise et stable pour calculer les équations solaires. (Vrai ou faux ? je n'en sais rien à ce stade)
Cette fois, pour la mise à l'heure pour de nombreuses années, j'avais mis les moyens avec quartz sur le PIC et je m'aperçois de déviations du temps par rapport au DCF sur une période de seulement 12 Heures, et cela m'a inquiété (3 secondes). J'ai toujours cru le quartz comme remède absolu à la précision, mais il n'en est rien et j'avais simplement oublié les particularités des quartz !!! Avec une double résonance série et //.
Qu'en est-il réellement de la précision ? J'ai voulu m'en rendre compte au réel en laissant tourner durant 12 heures environ le montage sous tension et en regardant le basculement de la minute avec une autre horloge DCF. J'ai constaté une avance d'environ 3 secondes de décalage pour l'horloge du PIC avec un quartz de 8 MHz et une précision rigoureuse au niveau du TIMER1.
J'ai également constaté 8 secondes de décalage sur le Tiny toujours avec cette même horloge DCF et le même temps d'observation mais le Tiny étant alimenté par l'outillage durant ces 12 heures.
Il reste à vérifier le décalage Tiny hors tension cette fois, et seulement alimenté par la pile... Lors d'une deuxième mesure je n'ai trouvé que 2 secondes !...? Je pense que pour le Tiny module, le problème est encore plus compliqué, du fait qu'il est alimenté parfois par une alim externe, et parfois par la pile CR2032.
Que penser de ces écarts de temps imprévus ? Rien de bon ! Cet outillage serait-il un coup d'épée dans l'eau ? Peut-être pas. au niveau des écarts, cela reviendrait pour 3 secondes à un rapport de 1/14400, ce qui reste non négligeable mais interdirait toute exploitation réelle au delà de 8 à 10 jours.
En résumé 3 secondes pour 12h cela reviendrait à 1 minute de décalage en 10 jours, ou 6 minutes en 2 mois ce qui devient inacceptable.
Alors que penser ? Il y a (presque) toujours une solution à un problème !
Il me semble que la vérité se situe à mi chemin et que sans aucune modification, le système permettrait de faire des pauses dans la journée, mais nécessiterait cependant une remise à l'heure périodique comprise entre 24 h et 2 mois suivant la précision que l'on demande.
Il est évident que durant une dizaine d'années, et dans ces conditions, il n'est pas possible de maintenir l'heure à un niveau de précision satisfaisant.
Concernant l'horloge du PIC, actuellement fonctionnant sur la base d'un quartz de qualité à 8 MHz, la précision n'est pas satisfaisante, bien que la fréquence soit "exacte" (au scope !), je ne savais plus comment expliquer cette différence, car la remise à zéro du registre du Timer 0 est faite au bon instant et le décomptage ajusté rigoureusement à la bonne valeur, à l'instruction près. Il semble évident que le PIC n'est pas en cause et que c'est le quartz qui est la cause, car il oscille sur la mauvaise fréquence de résonance et qu'il doit être compensé par un condensateur en // pour abaisser légèrement la fréquence.
Au sujet des quartz, il reste à investiguer la modification de la fréquence des quartz avec des condensateurs et de voir si c'est véritablement envisageable. C'est une opération que je n'ai jamais eu l'occasion de réaliser.
Je viens de faire plusieurs essais avec 10 pf en // mais c'est trop car on bascule de l'autre côté, et l'oscillateur est alors trop lent.
Il faut donc ajuster au plus fin avec quelques Pf en // sur le quartz, et pour cela une simple torsade de 2 petits fils isolés téflon peut faire l'affaire.
A savoir qu'un mètre de cette torsade représente 110 pf mesurés. Il faudra donc quelques centimètres à couper en vérifiant la dérive après un certain nombre d'heures (ou de jours).
Cette corection s'applique également et SURTOUT au Tiny module et après avoir placé un condensateur de 6.6 pf, l'écart sur 12 heures semble assez petit, sans pour l'instant savoir de quel côté je me situerai après un nombre d'heures plus conséquent.
Cette précision de l'heure est réellement un point important et je pense qu'il faudra réellement ajuster la fréquence des quartz aussi bien sur l'outillage mais surtout sur les Tiny modules si l'on veut éviter de corriger trop souvent l'heure sur le montage destiné à recevoir le Tiny module.
Le problème de ce condensateur d'ajustage est principalement sur le Tiny module, car il n'est pas question de mettre un petit trimmer vu que le circuit est déjà réalisé, aussi ce système de la torsade est le plus simple (après avoir déjà installé un condensateur qui fera le plus gros du travail.
Sur l'outillage ça poura être un trimmer si vous refaites le circuit, c'est un peu plus "pro" !
(Sur la photo, les flèches rouges pour la torsade faisant office de condensateur de faible valeur. Celle-ci est branchée directement en // du quartz situé en dessous du CI.
En jaune, le condensateur de 5.9 pf, base du réglage. L'affinage sera réalisé par la coupure de la torsade et son immobilisation finale par de la colle (à faire)).
L'autre possibilité sur laquelle j'ai quelques doutes, serait d'utiliser l'oscillateur RC interne du PIC qui reste tout de même assez stable et qui a le mérite de pouvoir être ajusté grâce à OSCTUNE. Cela pourrait règler le problème côté PIC mais pas côté Tiny où seule la modification de la fréquence du quartz reste envisageable.
Au niveau des quartz, je maîtrise assez mal le sujet et les possibilités réelles et j'ai seulement quelques bribes concernant les fréquences séries et //. Je dois faire encore quelques recherches à ce sujet.
La dernière remarque est que si l'horloge du PIC n'est pas parfaitement précise, ce n'est pas très grave dans l'emploi, car il peut être très facilement re-mis à l'heure (du DCF). Il n'en serait pas de même sur un montage en pleine nature à des kilomètres ou dans des conditions difficiles et équipé du Tiny module.
Il faut donc rectifier et ajuster en premier lieu la fréquence du Tiny module, ce que je n'avais jamais envisagé une seule seconde !
Le montage permet cette gymnastique même avec son oscillateur non rigoureusement calé avec précision. En effet la première opération consistera à lire le DCF, puis juste après à écrire un Tiny module. Enfin après un certain temps de mesurer des écarts de temps d'au moins une seconde, de relire le Tiny module, d'afficher le Buffer puis de comparer avec un DCF externe (pendule par ex) si il y a des différences conséquentes.
Cette approche par tâtonnements nécessitera de longs moments de réglages, mais cela n'a plus rien à voir avec mon outillage qui m'a seulement permis de débusquer ce lièvre.
Au final je vous invite à compulser ce lien vers Wikipédia https://fr.wikipedia.org/wiki/Quartz_(%C3%A9lectronique) où vous pourrez comprendre comme moi que rien n'est acquis au niveau de la fréquence et que c'est finalement à nous de faire le nécessaire pour que le quartz du Tiny oscille à la bonne fréquence. Il apparait aussi à la lumière de cet article qu'il est facile de diminuer la fréquence de résonance, et que heureusement ces quartz semblent avoir été prévus en ce sens.
Cependant on comprendra aussi que la fréquence de résonance dépendra aussi de l'électronique pure du Tiny et des capacités parasites qu'il présente sur l'entrée oscillateur.
Donc ajustez au mieux les quartz et n'oubliez pas que la température joue aussi un rôle non négligeable. Regardez également sur un moteur de recherche "réglage précision d'une montre à quartz", et vous aurez compris que ce qui vient d'être dit est une réalité. Un quartz est précis mais il faut l'ajuster et le maintenir en température constante.
Une montre à quartz est beaucoup moins sensible à la température, du fait qu'elle est à la température du poignet, (pour les bracelets)
J'ai lu sur Wikipédia que les Quartz sont taillés pour une capacité // d'entrée du montage oscillateur de 6 Pf. La capacité à ajouter est donc très faible et je pense que c'est mécaniquement réalisable avec une simple vis de réglage ou une torsade comme c'était déjà réalisé dans les très anciennes télé avec rotacteur, ou mieux un trimmer si ça a été prévu !
Voyez également sur ce site (https://www.forum-mdp.com/t6343-ajuster-un-calibre-quartz) quelques commentaires propres au réglages des montres à quartz mais qui s'appliquent rigoureusement à ce Tiny module qui ne fait pas exception aux quartz en général.
En conclusion ultime, je dois dire que ce montage avec les TRIS a été nécessité par le fait que je ne pouvais plus programmer les sorties 1 herz sur DS1307 et 32 KHz sur DS3231 suite à des erreurs. J'ai donc pris la décision de revenir à plus simple, même si au niveau concept Open Drain et TRIS cela semble un peu différent. Cette reprise du programme a été laborieuse ainsi que déjà évoqué.
Ces sorties 1 HERTZ me sont nécessaires pour un montage en cours qui devrait s'appeler "montage pour l'étalonnage du temps", qui s'appuiera sur un pseudo étalon de temps élaboré sur de nombreux jours et permettant d'étalonner de nombreux modules DS1307. Les modules DS3231 ne sont pas concernés car non mùodifiables. Ce montage permettra de cerner RAPIDEMENT les variations en quelques minutes ou heures contrairement à plusieurs jours.
_______________________________________________________________________________________________________________
CHAPITRE 2
Dans ce chapitre, je vais donner mes NOUVELLES routines assembleur pour la lecture, qui seront transposables sur les différents PIC16F ou 12F et peut-être ceux que je ne connais pas. Ces routines sont exploitables sur les PIC n'ayant ni SSP ou MSSP (16F628, 12F629 par exemple etc…) et sont partiellement issues de Pierre COL, mais ses sites http://www.altern.org/col2000/ ou http://www.multimania.com/offset ne fonctionnent pas ! (Je me demande d'ailleurs comment j'ai pu trouver les lignes de code ?)
Vous noterez que je n'utilise pas l'EEPROM présente sur le Tiny module, mais que cela ne crée pas de consommation faramineuse supplémentaire. Les puristes pourront la dessouder, bien qu'un petit complément de neurones ne soit pas toujours inutile...
(Il existe aussi des modules ayant seulement le DS1307 mais un peu plus cher !!!)
Ces routines sont en Page 0, à vous de transposer si nécessaire!
1 Conventions I2C
Cette partie rassemble toutes les #define et macros qui permettent une transposition plus facile d'un PIC à l'autre. Vous retrouverez ces définitions dans les séquences I2C ci après. A savoir que vous pourrez ainsi choisir n'importe quelle I/O (Sauf celle du MCLR/Vpp qui est en général une input seule, mais qui peut cependant être l'I/O de lecture du SDA (si nécessaire)).
#define SDA_R PORTB,Bit4 ; BANK0
#define SCL_W PORTB,Bit6
#define SDA_W PORTB,Bit4 ;
#define SDA4 Bit4 ; pour le transfert en BANK0 par NX
#define SDA_PORT PORTB
#define SDA_W_0 bcf TRISB,Bit4 ; Sortie PORTB4 à 0
#define SDA_W_1 bsf TRISB,Bit4 ; Sortie PORTB4 à 1 (en l'air sur PULLup)
#define SCL_W_0 bcf TRISB,Bit6 ; clock PORTB6 à 0
#define SCL_W_1 bsf TRISB,Bit6 ; Clock PORTB6 à 1 (en l'air sur pullup)
AD1307W EQU 0xD0 ; adresse en écriture DS1307 bit écriture=0
; variables BANK1
CBLOCK 0xA0 ; BANK1
CTRL1_1 :1 ; mot de contrôle BANK1
CNT1_1 :1
Byte_Data_1 :1 ; donnée SDA
MAN1_1 :1 ; petit délai 5 µs tj en BANK1
Spare :5 ; pour rangement adresses modules I2C + adresses simple ou double pour EEPROM BUF77-x
BUF_Disp :20 ; Buffer Display limitée à 1 ligne
;
ENDC
A noter que dans les routines qui doivent recevoir ou émettre des ACK et/ou NAK, certaines variables sont en BANK1 pour la raison que les tests par BTFSS n'ont que 2 sorties et qu'il est parfois nécessaire de passer par une variable intermédiaire commune à toutes les BANK (NX).
Il est important aussi comme cela a été mentionné de faire attention aux macros qui peuvent cacher la première sortie d'un BTFSS, et c'est ce que j'ai expérimenté avec malheur durant de nombreux jours...
2 Conventions DCF77
; macro DCF77 pour version signal négatif
TST77SC macro
btfss PORTA,Bit3 ;
endm
TST77SS macro
btfsc PORTA,Bit3 ;
endm
NOTA : Pour un DCF77 en sortie positive, il suffit de remplacer le btfsc par btfss et réciproquement. Il est aussi possible de croiser les noms de macro
3 Les routines I2C
ATTENTION : Ces routines correspondent uniquement au schéma avec les "TRIS"
Ces routines sont établies pour la vitesse standard de 100KHz de l'I2C. Ces routines comportent seulement un CALL delay 5µs permettant de fonctionner à 100 KHz, vitesse de base de l'I2C, ici avec un PIC à 8MHz.
;*****************************************************************
; I2C INIT pour SSP et OPEN collector
; force la mise à 1 des open collector SCL et SDA (en tant que sorties)
; Aucun paramètre
;
I2C_INIT
BANK1
SCL_W_1 ;
SDA_W_1 ;
RETURN ; End I2C_INIT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; séquence 'START' "I2C_STRT"
; dans l'application ICI prévue avec DS1307, les bus seront toujours libres (à 1)
; on ne les testera pas. Ce sera le cas certainement dans les petites applications
; mais pas pour les applications où l'I2C est déjà utilisée
; ce module réalise la préparation DATA et CLOCK pour l'envoi de l'adresse I2C
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I2C_STRT
BK0_1
SDA_W_1
SCL_W_1
call Tempo5us ; tempo 5µs
SDA_W_0 ; mise à 0 SDA
call Tempo5us ; tempo 5µs
SCL_W_0
call Tempo5us ; tempo 5µs
; SDA_W_1 ;: remise à 1 pour recevoir les datas
BK1_0
RETURN ; End I2C_STRT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Envoi W au peripherique I2C "W_toI2C"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; W : data à envoyer placé ensuite
; dans Byte_Data qui est en BANK 1 on va roter 8 fois
; cet octet vers la gauche, en recopiant a chaque fois au
; prealable le bit B7 sur la broche SDA (avant d'appliquer une impulsion
; d'horloge sur SCL). La variable Cnt1 est le compteur
;
; rappel ci-dessous pour information
;
; variables Byte_Data, Cnt1
; Appels Tempo5us
W_toI2C
BK0_1
movwf Byte_Data_1 ; Octet a envoyer
movlw 8 ; 8 (nb de decalages) dans VAR2.
movwf Cnt1_1 ;
LoopW_toI2C
SCL_W_0 ; SCL mis a '0'.
btfss Byte_Data_1,Bit7 ; test si Bit B7 de Byte_Data a 1
SDA_W_0 ; attention 3 ou 4 instructions !!!! si BANK0 d'origine
btfsc Byte_Data_1,Bit7 ; test si Bit B7 de Byte_Data a 1
SDA_W_1
; non mise SDA a 1
CALL Tempo5us ; tempo 5µs
SCL_W_1 ; SCL mis a 1 Front montant sur SCL
CALL Tempo5us ; attente 5 us, SCL repasse a '0'
SCL_W_0 ; SCL remis a '0'.
rlf Byte_Data_1,f ; 6--7 etc...
decfsz Cnt1_1,f ; -1 / compteur
goto LoopW_toI2C ; loop
SDA_W_1 ; mise à 1 TRIS SDA et passage en lecture ACK
BK1_0
RETURN ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Verifie si le peripherique I2C renvoie un 'Acknowledge' ; si celui-ci
; est present, le bit I2C_ACK_R est mis a 0, sinon I2C_ACK_R est mis a 1.
; Ce sera un ACK Read envoyé par le périph
; Aucune variable utilisée
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I2C_ACK_R
BK0_1
SDA_W_1 ; confirm SDA à 1 inutile à priori déjà fait en WI2C
SCL_W_0 ; confirm SCL à 0
call Tempo5us ; tempo
SCL_W_1 ;SCL a '1', attente de 5 us.
call Tempo5us ; tempo
BK1_0
movfw SDA_PORT ; PORTB
movwf NX
BK0_1
SCL_W_0
btfss Nx,SDA4 ; replique du portB
goto No_ER
; erreur
BK1_0
movlw Disp_Clear ; clear display
call ENB_DispC
call DLY_100msT1 ;
movlw 'E' ; Petit message "Wait"
call ENB_DispD
movlw 'r'
call ENB_DispD
call DLY_1000msT1 ; temps d'affichage juste pour info
RETLW 1 ; retour en erreur 1
No_ER
BK1_0
clrw ; retour sans erreur W=0
RETURN ; end I2CACK_R
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Envoi une sequence STOP au peripherique I2C
; Aucune variable utilisée
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I2C_STP
BK0_1
SCL_W_0 ; retour à 0 clock
SDA_W_0 ; retour à 0 DATA
call Tempo5us ; On attend 5 us,
SCL_W_1 ; Set Clock à 1
CALL Tempo5us ; on attend 5 us...
SDA_W_1 ; mise à 1 SDA
call Tempo5us ; on attend 5 us...
BK1_0
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Lecture 8 BITS sur DS1307
; Résultats en W et Byte_DATA
; Cette séquence permettra de récupérer la totalité date et heure du DS1307 avec une boucle l'incluant
; variables utilisées : Cnt1, Byte_Data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
I2C_toW
BK0_1
movlw 8 ; 8 Bits
movwf Cnt1_1 ; 8 decalages.
clrf Byte_Data_1 ; RAZ
I2CtoW2
SCL_W_0 ; mise à 0 clock SCL
SDA_W_1 ; mise à 1 SDA pour libérer le bus Open Collector
CALL Tempo5us ; tempo 5 us.
SCL_W_1
CALL Tempo5us ; tempo 5 us.
rlf Byte_Data_1,F ; shft vers la gauche.
bcf Byte_Data_1,Bit0 ; preset 0
; btfsc SDA_R ; lecture BIT PORTB,Bit4
BK1_0
movfw SDA_PORT
movwf NX
BK0_1
btfsc NX,SDA4
bsf Byte_Data_1,Bit0 ; si non (SDA='1'), on met B0 a '1'.
decfsz Cnt1_1,f
goto I2CtoW2 ; non loop
SCL_W_0 ; mise à 0 de SCL
movfw Byte_Data_1 ; l'octet lu est copie dans W.
BK1_0
RETURN ; end I2C_toW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC envoie ACK Acknowledge au peripherique I2C.
; Aucune variable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I2C_ACK_W
BK0_1
SCL_W_0 ; au debut, SCL est déjà à '0'.
SDA_W_0 ; SDA est mis a '0' (on applique ACK).
call Tempo5us ; tempo 5 us.
SCL_W_1
call Tempo5us ; tempo 5 us.
SCL_W_0
SDA_W_1
BK1_0
RETURN ; Fin de la routine, retour au programme principal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC envoie NAK au peripherique I2C pour dernier K lu depuis DS1307
; Aucune variable.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I2C_NACK_W
BK0_1
SCL_W_0 ; au debut, SCL est déjà à '0'.
SDA_W_1 ; SDA est mis a 1 (on applique NACK).
call Tempo5us ; tempo 5 us.
SCL_W_1
call Tempo5us ; tempo 5 us.
SCL_W_0
SDA_W_1
BK1_0
RETURN ; End I2C_NACK_W