Avant de pouvoir commencer réellement l'écriture de la programmation structurée, il faut d'abord étudier les datasheets des trois circuits spécialisés que nous allons utiliser, afin d'en ressortir les protocoles. C'est grâce à ces protocoles que nous pourrons écrire notre structurée. ******************************************************************************* Révisions: - le 20/04/2005 - Jean-Pol - Ajouté la variable PrecSecondes VAR Byte pour retenir la valeur de la variable Secondes et ainsi pouvoir comparé si l'horloge a avancé d'une seconde. Suite à cela, nous n'avons plus besoin des variables Tempstot VAR Word, Moment VAR Bit et PrecMoment VAR Bit.TempoT VAR Word devient TempoT VAR Byte. Les modifications sont marquées par XXX ******************************************************************************* Etude du MC14489 : Circuit d'affichage à 5 Digits LED 7 segments ---------------------------------------------------------------- La lecture du datasheet nous indique que la commande se fera en mode série, avec l'envoi du bit de poids fort en premier. Suivant nos besoins, nous pouvons envoyer soit un octet (qui programmera le registre de configuration), soit trois octets (qui programmerons l'afficheur proprement dit). Pour ce qui est du protocole "électrique", il est assez traditionnel. 1 - La pin ENABLE est mise à l'état "BAS" pour activer le circuit. 2 - Puis, le premier Bit est présenté sur la pin DATA. 3 - Un "Flanc Montant" sur l'entrée CLOCK permet au registre à décalage de s'incrémenter. 4 - Les points 2 et 3 sont répétés 8 fois ou 24 fois suivant que l'on envoie une "configuration" ou des "données". 5 - Enfin, la pin ENABLE est mise à l'état "HAUT", ce qui a pour effet de "latcher" soit le registre de configuration, soit les sorties. Si l'on envoie un seul octet, il sera donc considéré comme une octet de commande. Cet octet de commande est décomposé de la manière suivante : - Bit 7 : Voir remarque 1 pour afficheurs 4 et 5 - Bit 6 : Voir remarque 1 pour afficheur 1, 2 et 3 - Bit 5 : Voir remarque 2 pour afficheur 5 - Bit 4 : Voir remarque 2 pour afficheur 4 - Bit 3 : Voir remarque 2 pour afficheur 3 - Bit 2 : Voir remarque 2 pour afficheur 2 - Bit 1 : Voir remarque 2 pour afficheur 1 - Bit 0 : 1 = Mode Normal, 0 = Mode Faible Puissance Remarque 1 : 0 = Pas de décodage, ce mode est utilisé lorsque l'on utilise des leds séparées et non pas des afficheurs 7 segments. Dans ce mode, il est possible de commander 20 leds (5X4) avec un circuit MC14489. En matriçant sur les banks 1 à 5 et les segments a, b, c et d. 1 = Décodage suivant les options choisies par les bits 7 à 1. Remarque 2 : 0 = Décodage Hexadécimal (0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F) 1 = Décodage "spécial" ( ,c,H,h,J,L,n,o,P,r,U,u,y,-,=,°) Si l'on envoie trois octets, ces octets seront alors des valeurs envoyées à l'afficheur. Ces trois octets sont en fait divisés en 6 Nibbles. Le premier Nibble envoyé reprend la luminosité de l'afficheur et les points décimaux (segment h) selon la décomposition suivante : - Bit 3 : 0 = Leds "dimmées", 1 = Leds éclairées à fond - Bit 2 : / Selon valeur de 0 à 7 | 0 = pas de points | 1 = Point afficheur 1 - Bit 1 : < 2 = Point afficheur 2 | 3 = Point afficheur 3 | 4 = Point afficheur 4 - Bit 0 : \ 5 = Point afficheur 5 | 6 = Point affi. 1 et 2 | 7 = Point sur tous. Les cinq Nibbles suivants reprennent les valeurs à afficher sur les 5 digits. Selon le cahier des charges, nous voyons que l'afficheur pourra avoir trois formats différents : "HH=MM" , "TTT°", "-TT°", suivant les demandes. "H", "M" et "T" représente des simples digits (de 0 à 9), et nous avons en plus les signes " = ", " - " et " ° " qui sont des caractères "spéciaux". Le datasheet nous indique que les 5 afficheurs sont numérotés 1 à 5 de droite à gauche. Donc, suivant nos besoins, nous aurons trois possibilités : 1 - Affichage de l'heure - Envoi d'un octet de configuration selon le format : 1 - 1 - 0 - 0 - 1 - 0 - 0 - 1 ($C9) (201) (soit décodage normal pour les digits 5, 4, 2 et 1 et décodage "spécial" pour le digit 3) - Envoi des 6 Nibbles de données selon le format : $8 - $H - $H - $E - $M - $M (ou chaque Nibble $H représente un digit de l'Heure, chaque Nibble $M représente un digit des minutes, le premier $8 représente "pas de points décimaux" et allumage des digits à pleine puissance, et $E représente le signe " = ") 2 - Affichage des températures Positives - Envoi d'un octet de configuration selon le format : 1 - 1 - 1 - 0 - 0 - 0 - 1 - 1 ($E3) (227) (soit décodage normal pour les digits 4, 3 et 2 et décodage "spécial" pour le digit 5 et 1) - Envoi des 6 Nibbles de données selon le format : $8 - $0 - $T - $T - $T - $F (ou chaque Nibble $T représente un digit de Température, le premier $8 représente "pas de points décimaux" et allumage des digits à pleine puissance, $0 représente digit éteint et $F représente le signe " ° ") 3 - Affichage des températures Négatives - Envoi d'un octet de configuration selon le format : 1 - 1 - 1 - 1 - 0 - 0 - 1 - 1 ($F3) (243) (soit décodage normal pour les digits 3 et 2 et décodage "spécial" pour le digit 5, 4 et 1) - Envoi des 6 Nibbles de données selon le format : $8 - $0 - $D - $T - $T - $F (ou chaque Nibble $T représente un digit de Température, le premier $8 représente "pas de points décimaux" et allumage des leds à pleine puissance, $0 représente digit éteint, $D représente le signe " - " et $F représente " ° ") Etude du DS1302 : Horloge temps réel Charge et RAM - RTC -------------------------------------------------------- Dans le projet qui nous occupe, nous n'utiliserons ni la ram, ni le circuit de charge. Nous allons donc nous concentrer uniquement sur la partie RTC, "horloge temps réel". Comme pour le circuit précédent, la commande se fait sous forme série, mais ici, c'est le bit de poids faible qui est envoyé en premier. Avant de pouvoir écrire dans les registres, il est nécessaire d'ôter la protection en écriture du registre aussi bien en mode normal qu'en Mode BURST, pour cela, on effectue les actions suivantes: 1 - La pin ENABLE est mise à l'état "HAUT" pour activer le circuit. 2 - Puis, le premier Bit de $8E ( Adresse de Write Protect ) est présenté sur la pin I/O. 3 - Un "Flanc Montant" sur l'entrée CLOCK permet l'écriture du bit présent sur la pin I/O dans le registre. 4 - Les points 2 et 3 sont répétés 8 fois. 5 - Puis, le premier Bit de $00 ( Enlève la protection en écriture ) est présenté sur la pin I/O. 6 - Un "Flanc Montant" sur l'entrée CLOCK permet l'écriture du bit présent sur la pin I/O dans le registre. 7 - Les points 5 et 6 sont répétés 8 fois. 8 - Enfin, la pin ENABLE est remise à l'état "BAS", ce qui a pour effet de confirmer l'écriture et de désactiver le circuit. Le protocole "électrique", fonctionne de manière différente suivant qu'il s'agit d'une lecture ou d'une écriture. Lors d'une écriture nous avons les actions suivantes : 1 - La pin ENABLE est mise à l'état "HAUT" pour activer le circuit. 2 - Puis, le premier Bit est présenté sur la pin I/O. 3 - Un "Flanc Montant" sur l'entrée CLOCK permet l'écriture du bit présent sur la pin I/O dans le registre. 4 - Les points 2 et 3 sont répétés 16 fois. 5 - Enfin, la pin ENABLE est remise à l'état "BAS", ce qui a pour effet de confirmer l'écriture et de désactiver le circuit. Lors d'une Lecture, nous avons une petite différence. Le cycle commencera par une écriture, il faut d'abord écrire l'adresse : 1 - La pin ENABLE est mise à l'état "HAUT" pour activer le circuit. 2 - Puis, le premier Bit est présenté sur la pin I/O. 3 - Un "Flanc Montant" sur l'entrée CLOCK permet l'écriture du bit présent sur la pin I/O dans le registre. 4 - Les points 2 et 3 sont répétés 8 fois. Puis, nous passons à la lecture de l'octet envoyé par le circuit. 5 - Présentation d'un "Flanc Descendant" sur l'entrée CLOCK du circuit 6 - Lecture du Bit envoyé sur la Pin I/O. 7 - Les points 5 et 6 sont répétés 8 fois. 8 - Enfin, la pin ENABLE est remise à l'état "BAS". Deux modes sont disponibles. Le mode BURST qui permet de lire ou d'écrire tous les octets de la RAM ou tous les registres de la RTC d'une seule traite. Le deuxième mode est le mode normal qui permet de lire ou d'écrire un seul octet à la fois. Dans notre application, nous utiliserons le mode normal. Puisque sur les 9 registres de l'horloge, seul 3 registres seront utilisés de manière courante (Les heures, les minutes et les secondes). Le format de lecture ou d'écriture est composé de deux octets. Le premier octet envoyé est l'adresse et constitue toujours une écriture vers le circuit. Le deuxième octet constitue la donnée, et sera envoyé ou reçu, selon qu'il s'agisse d'une écriture ou d'une lecture. L'octet d'adresse possède la structure suivante : - Bit 7 : toujours à 1 - Bit 6 : 0 = RTC, 1 = Ram - Bit 5 : A4 - Bit 4 : A3 - Bit 3 : A2 - Bit 2 : A1 - Bit 1 : A0 - Bit 0 : 0 = Ecriture, 1 = Lecture Où A0-A4 représente l'adresse de registre ou de Ram. Donc, nous pouvons dire que les adresses $80 à $BF (10xxxxxx) concernent la RTC et que les adresse $C0 à $FF (11xxxxxx) concernent la RAM, les adresses paires correspondant à des écritures, et les impaires à des lectures. Pour la partie RTC, nous avons les adresses suivantes : 1 - 00000 : Secondes (de 0 à 59) 2 - 00001 : Minutes (de 0 à 59) 3 - 00010 : Heures (de 1 à 12 ou de 0 à 23) 4 - 00011 : Date (de 1 à 31) 5 - 00100 : Mois (de 1 à 12) 6 - 00101 : Jour (de 1 à 7) 7 - 00110 : Année (de 0 à 99) 8 - 00111 : Protection en écriture de la RAM 9 - 01000 : Programmation du circuit de charge Dans notre application, nous utiliserons les registres des secondes, minutes et heures, soit respectivement les adresses $80(128), $82(130), $84(132) en écriture et les adresses $81(129), $83(131), $85(133) en lecture. Pour les secondes et les minutes, les bits 0 à 3 contiennent les unités, et les bits 4 à 6 les dizaines (0 à 5), le Bit 7 étant toujours à 0. Pour les heures: Si nous travaillons en mode 12 heures. Dans ce mode, les bits 0 à 3 contiennent les unités, le Bit 4 contient les dizaines d'heures (0 ou 1), le Bit 5 contient le moment de la journée 0 = AM et 1 = PM, le Bit 6 est toujours à 0 et le Bit 7 est mis à 1 pour forcer le mode 12 heures et à 0 pour le mode 24 heures. Si nous travaillons en mode 24 heures. Dans ce mode, les bits 0 à 3 contiennent les unités, les Bits 4 et 5 contiennent les dizaines d'heures (0, 1 ou 2), le Bit 6 est toujours à 0 et le Bit 7 est mis à 0 pour forcer le mode 24 heures. ---( PREMIERE APPROCHE: Cette solution n'est pas retenue. | Le mode 12 heures à été sélectionné parce que nous | travaillons avec un STAMP qui travaille en 16 bits. Si nous décidons de | travailler en mode secondes, nous avons 24 X 60 X 60 secondes en une journée, | soit 86400 secondes. Or une variable Word ne peut compter que jusque 65535. | Par contre, en mode 12 heures, nous aurons 43200 secondes par tranche de --- calcul, ce qui ne pose pas de problème dans une variable 16 bits.) XXX DEUXIEME APPROCHE: Cette fois, solution retenue. On utilise le mode 24 heures et on ne travaille plus sur le temps total en secondes. On affiche les heures et les minutes et on lit la valeur des secondes que l'on place dans une variable PrecSecondes, puis lors des bouclages, on compare les valeurs de Secondes et de¨PrecSecondes, si la comparaison est fausse, cela indique que le temps a augmenté d'une seconde et dès lors, on incrémente notre compteur de temporisation. Lorsque la temporisation est atteinte, le basculement de l'affichage entre Horloge et Température s'effectue et vice versa. Donc, en résumé, nous aurons pour ce circuit : 1 - Lecture des secondes : Ecriture de $81, puis lecture de $SS sur 2 Nibbles. 2 - Lecture des Minutes : Ecriture de $83, puis lecture de $MM sur 2 Nibbles. 3 - Lecture des Heures : Ecriture de $85, puis lecture de $HH sur 2 Nibbles. 4 - Mise à zéro des secondes : Ecriture de $80, puis écriture de $00. 5 - Ecriture des Minutes : Ecriture de $82, puis écriture de $MM. 6 - Ecriture des Heures : Ecriture de $84, puis écriture de $HH. NB : Les valeurs $SS, $MM et $HH étant les valeurs converties en hexadécimal des secondes, minutes et heures. Etude du DS1620 : Thermomètre digital et thermostat. ---------------------------------------------------- Le DS1620 possède deux modes de fonctionnement : - Un mode "Stand-Alone" qui lui permet de fonctionner seul. - Un Mode "Trois fils" dans lequel il fonctionne raccordé à un µcontrôleur. Pour notre application, nous utiliserons le mode 3 fils. De plus, nous utiliserons ce circuit dans un mode très simple, puisque les fonctions thermostatiques ne seront pas utilisées, et que le circuit sera mis en mode de conversion permanente. Dans ces conditions, il nous suffira de lire la température à chaque fois que nous en aurons besoin. Comme pour les deux autres circuits, le DS1620 fonctionne en mode série avec l'envoi du bit de poids faible en premier. Le protocole électrique est le même que pour le DS1302. Dans le DS1620, la conversion se fait sur 9 bits. La précision est le 1/2 degré et la variable 9 Bit utilisée est en fait une variable définie en mode signé. Le 9ieme Bit représente le signe ( 0 = Positif, 1 = Négatif ). En mode positif, la conversion se fait naturellement ( $00=0°C, $01=0,5°C, $FA=125°C ). Par contre, en mode négatif, la conversion se fait sur le complémentaire à deux, c'est à dire, l'inverse de la lecture + 1, ce qui nous donne : $FF=-0,5°C, $CC=-26°C et $92=-55°C. La gamme de mesure s'étend de -55°C jusque +125°C par 0.5°C. Lors de l'utilisation du DS1620, nous allons toujours lui envoyer une commande, en mode écriture, suivi soit d'une deuxième écriture, soit d'une lecture suivant la commande envoyée. Pratiquement, dans notre application, nous n'utiliserons que deux commandes : 1 - Tout au début du programme, l'écriture de la configuration dans le registre de commande du DS1620. Soit $0C (WRITE config), suivi de $EA (Mode CPU en conversion continue) 2 - Pendant le programme, lecture de la température, ce qui nous donne l'écriture de la commande $AA (Lecture de la température), suivi de la lecture de la valeur de la température sur 9 Bits !!! Ceci étant fait, nous pouvons commencer à écrire notre programmation structurée ******************************************************************************* Liste des Sous Routines *********************** SUB Initstamp Initialisation des entrées et sorties du Stamp SUB Initvar ' Initialisation des constantes ' Initialisation des variables SUB Initcirc ' Initialisation hardware des circuits. ' En entrée, cette routine a besoin des constantes hardware ' PEnbA, PDatA, PClkA, PEnbH, PDatH, PClkH, PEnbT, PDatT et PClkT. ' Il n'y a pas de variable de sortie. ' Cette routine utilise les routines AFFIHEURE et READHEURE. ' Déprotection en écriture du DS1302 ' Enléver la protection en écriture du registre du DS1302 [$8E,$00] ' Cette routine utilise en plus la routine WRITEHEURE. SUB WRITEAFFI ' Routine d'écriture des valeurs dans l'afficheur. ' En entrée, cette routine à besoin des constantes "Hardware" ' : PEnbA, PDatA et PClkA et des variables "Software" ' : Comser et Digit(n). La variable de travail i est modifiée. ' Il n'y a pas de variable de Sortie. SUB WRITEHEURE ' Routine d'écriture de l'heure dans le DS1302. ' En Entrée, cette routine à besoin des variables Heures et minutes ' ainsi que des constantes "hardware" : PEnbH, PDatH et PClkH. ' Les variables de travail i et j sont modifiées. ' Il n'y a pas de variable de Sortie. SUB READHEURE ' Routine de lecture de l'heure dans le DS1302. ' En Entrée, cette routine à besoin des constantes "Hardware" ' : PEnbH, PDatH et PClkH ' Les variables de travail PrecSecondes, i, j et k sont modifiées. ' En sortie, les variables Heures, Minutes, Secondes sont mises à jour. SUB READTEMP ' Routine de lecture de la température dans le DS1620. ' En Entrée, cette routine à besoin des constantes "Hardware" ' : PEnbT, PDatT et PClkT. La variable de travail i est modifiée. ' En sortie, les variables Température et Signtemp sont mises à jour. SUB LECTURE ' Routine de lecture des touches et du Pot ' En Entrée, cette routine à besoin des constantes "hardware" ' : BoutonUP, BoutonDN et Pot. La variable de travail i est ' modifiée. En sortie, les variables TempoM et Touche ' sont modifiées. SUB AFFIHEURE ' Routine d'affichage des heures. ' En entrée, cette routine à besoin des variables Heures et Minutes. ' Les variables Comser et Digit(4) sont modifiées. ' Il n'y a pas de variable de sortie. ' Cette routine utilise la routine WRITEAFFI SUB AFFITEMP ' Routine d'affichage de la température ' En entrée, cette routine à besoin des variables Température et Signtemp ' Les variables Comser et Digit(4) sont modifiées. ' Il n'y a pas de variable de sortie. ' Cette routine utilise la routine WRITEAFFI SUB CHANGEHEURE ' Routine qui effectue le changement d'heure, et qui met à jour le ' circuit DS1302. En entrée, la routine à besoin de la variable Touche ' et de la constante Timemax. Les variables Timeout, Compteur, Heures, ' Minutes et Anttouche sont modifiées. ' Cette routine utilise les routines WRITEHEURE, AFFIHEURE et LECTURE. Structure du programme ********************** BEGIN DECLARE PEnbA AS Bit ' Constante : n° de pin Enable de l'afficheur DECLARE PDatA AS Bit ' Constante : n° de pin Data de l'afficheur DECLARE PClkA AS Bit ' Constante : n° de pin Clock de l'afficheur DECLARE PEnbH AS Bit ' Constante : n° de pin Enable de l'horloge DECLARE PDatH AS Bit ' Constante : n° de pin Data de l'horloge DECLARE PClkH AS Bit ' Constante : n° de pin Clock de l'horloge DECLARE PEnbT AS Bit ' Constante : n° de pin Enable du Thermomètre DECLARE PDatT AS Bit ' Constante : n° de pin Data du Thermomètre DECLARE PClkT AS Bit ' Constante : n° de pin Clock du Thermomètre DECLARE BoutonUP AS Bit ' Constante : n° de pin du bouton poussoir UP DECLARE BoutonDN AS Bit ' Constante : n° de pin du bouton Poussoir DOWN DECLARE Pot AS Bit ' Constante : n° de pin du potentiomètre DECLARE Timemax AS Byte ' Constante : Butée de Timeout pour la lecture. Cette ' constante est à définir pour obtenir la temporisation ' de timeout voulue dans la routine de lecture. DECLARE Comser AS Byte ' Variable : commande pour les circuits séries DECLARE Digit(4) AS Nibble ' Variable : Contenu des 5 digits à afficher DECLARE TempoT AS Byte ' Variable : Temps de démarrage de la Tempo DECLARE Heures AS Byte ' Variable : Heures (0 à 24) DECLARE Minutes AS Byte ' Variable : Minutes (0 à 59) DECLARE Secondes AS Byte ' Variable : secondes (0 à 59) DECLARE PreSecondes AS Byte ' Variable : Secondes précédentes (Pour la temporisation) DECLARE Température AS Byte ' Variable : Valeur de la température (0 à 125) DECLARE Signtemp AS Bit ' variable : Signe de la température 0=+, 1=- DECLARE TempoM As Byte ' Variable : Mesure de la Tempo en fonction du Pot DECLARE Touche AS Nibble ' Variable : Etat des touches ' (0 : Pas de touche, 1 : Touche DOWN et 2 Touche UP) DECLARE Anttouche ' Variable : Touche antérieure DECLARE Compteur ' Variable : Nombre d'appuis sur un bouton poussoir DECLARE Timeout ' Variable : Compteur pour le timeout dans la lecture DECLARE PrecSecondes ' Variable : Secondes précédentes DECLARE i AS Word ' Variable de travail DECLARE j AS Byte ' Variable de travail DECLARE k AS Byte ' Variable de travail GOSUB Initstamp ' Initialisation du Stamp GOSUB InitVar ' Initialisation des variables GOSUB InitCirc ' Initialisation des périphériques ' Début réel du programme Principal. DO WHILE i=i ' boucle "infinie" ' Partie de programme pour l'affichage de l'heure LET TempoT = 0 ' Initialisation de la tempo pour le ' changement d'affichage DO ' Début de la boucle d'affichage GOSUB LECTURE ' Lecture des touches et du POT IF Touche > 0 THEN ' Si appuis d'une touche, GOSUB CHANGEHEURE ' Aller à la routine changement d'heure ENDIF ' GOSUB READHEURE ' Lecture de l'heure GOSUB AFFIHEURE ' Affichage de l'heure IF PreSecondes <> Secondes THEN ' Si changement de Secondes LET TempoT = TempoT + 1 ' Ajout de 1 seconde à TempoT ENDIF UNTIL Tempstot < TempoM ' Bouclage tant qu'il n'y a pas de ' dépassement de la tempo fixée par le POT ' Partie de programme pour l'affichage de la température LET TempoT = 0 ' Initialisation de la tempo pour le ' changement d'affichage DO ' Début de la boucle d'affichage GOSUB READHEURE ' Lecture de l'heure (pour Tempstot) GOSUB READTEMP ' Lecture de la température GOSUB AFFITEMP ' Affichage de la température IF PreSecondes <> Secondes THEN ' Si changement de Secondes LET TempoT = TempoT + 1 ' Ajout de 1 seconde à TempoT ENDIF UNTIL Tempstot < TempoM ' Bouclage tant qu'il n'y a pas de ' dépassement de la tempo fixée par le POT ENDDO END SUB Initstamp définir P00 en sortie ' Serial data (commun au DS1302 et DS1620) définir P01 en sortie ' Serial Clock (commun au DS1302 et DS1620) définir P02 en sortie ' RST-1302 (Contrôle du DS1302) définir P03 en sortie ' RST-1620 (Contrôle du DS1620) définir P04 en sortie ' ENB-14489 (Contrôle du MC14489) définir P05 en sortie ' CLK-14489 (Serial Clock du MC14489) définir P06 en sortie ' DATA-14489 (Serial Data du MC14489) définir P07 en entrée ' *** Pas Utilisé *** \ Définie P08 en entrée ' Bouton Down | Définie P09 en entrée ' Bouton Up | définir P10 en entrée ' *** Pas Utilisé *** \ Mettre en entrée définir P11 en entrée ' *** Pas Utilisé *** / DIR = 0 (Basic STAMP) définir P12 en entrée ' *** Pas Utilisé *** | définir P13 en entrée ' *** Pas Utilisé *** | définir P14 en entrée ' *** Pas Utilisé *** / Définie P15 en entrée ' Potentiomètre Mettre P02 à l'état Bas ' Met le DS1302 en attente Mettre P03 à l'état Bas ' Met le DS1620 en attente Mettre P04 à l'état haut ' Met le MC14489 en attente ENDSUB SUB Initvar ' Initialisation des constantes LET PEnbA = 4 ' N° de Pin Enable du MC14489 LET PDatA = 6 ' N° de Pin Data du MC14489 LET PClkA = 5 ' N° de Pin Clock du MC14489 LET PEnbH = 2 ' N° de Pin Enable du DS1302 LET PDatH = 0 ' N° de Pin Data du DS1302 LET PClkH = 1 ' N° de Pin Clock du DS1302 LET PEnbT = 3 ' N° de Pin Enable du DS1620 LET PDatT = 0 ' N° de Pin Data du DS1620 LET PClkT = 1 ' N° de Pin Clock du DS1620 LET BoutonUP = 9 ' N° de Pin du Poussoir UP LET BoutonDN = 8 ' N° de Pin du Poussoir DOWN LET Pot = 15 ' N° de Pin du potentiomètre ' Initialisation des variables LET i = 0 ' Initialisation LET j = 0 ' des variables LET k = 0 ' de travail DO WHILE i < = 4 ' début de boucle de mise à zéro des digits LET Digit(4) = 0 ' mise à zéro des digits ENDDO ' fin de boucle LET Comser = 0 ' \ LET Heures = 0 ' | LET Minutes = 0 ' | initialisation LET Secondes = 0 ' \ des LET PrecSecondes = 0 ' | différentes LET Température = 0 ' / variables LET Signtemp = 0 ' | LET Tempstot = 0 ' | LET Touche = 0 ' / ENDSUB SUB Initcirc ' Initialisation hardware des circuits. ' Le DS1620 (Température) doit être initialisé. ' Le DS1302 doit être déprotégé, puis nous effectuerons la lecture et l'affichage ' de l'heure, ce qui nous permettra de tester les circuits DS1302 et MC14489. ' En entrée, cette routine a besoin des constantes hardware PEnbA, PDatA, ' PClkA, PEnbH, PDatH, PClkH, PEnbT, PDatT et PClkT. ' Cette routine utilise les routines WRITEHEURE, AFFIHEURE et READHEURE. Pin PenbT mise à l'état haut ' Activation du DS1620 Envoi de $OC en mode série sur les pins PDatT et PClkT ' Commande "Write Config" Envoi de $EA en mode série sur les pins PDatT et PClkT ' Commande "Mode CPU en conversion continue" Pin PenbT mise à l'état bas ' désactivation du DS1620 Pin PenbH mise à l'état haut ' Activation du DS1302 Envoi de $8E et de $00 en mode série sur les pins PDatH et PClkH ' Commande "WRITE PROTECTION" ' Enlève la protection en écriture Pause 1 MS ' Pause pour "CE inactive Time" Pin PenbH mise à l'état bas ' désactivation du DS1302 GOSUB WRITEHEURE GOSUB READHEURE GOSUB AFFIHEURE ENDSUB SUB WRITEAFFI ' Routine d'écriture des valeurs dans l'afficheur. ' L'envoi des données se fait en deux temps. D'abord, un octet de commande ' (conser) est envoyé. Puis après une courte pose, les 6 nibbles de datas ' ($8 et Digit(4)) sont envoyés. ' En entrée, cette routine à besoin des constantes "Hardware" ' : PEnbA, PDatA et PClkA et des variables "Software" Comser et Digit(n). ' La variable de travail i est modifiée. ' Il n'y a pas de variable de Sortie. Pin PEnbA mise à l'état bas ' Activation de l'afficheur Envoi de la variable comser en mode série sur les pins PDatA et PClkA ' La variable Comser sera mise à $F7, $DD ' ou $CD, suivant le type d'affichage ' (Heure, T° positives ou T° négatives) Pin PEnbA mise à l'état haut ' Latch des valeurs dans l'afficheur PAUSE de 1 ms ' Séparation de la commande et des datas Pin PEnbA mise à l'état bas ' Activation de l'afficheur Envoi de la valeur $8 sur un nibble en mode série sur les pins PDatA et pclkA ' Ecriture de "Pas de points décimaux" LET i = 0 ' Initialisation de boucle DO WHILE i < = 4 ' début de boucle d'envoi des valeurs Envoi de la variable Digit(i) en mode série sur les pins pDatA et PClkA LET i = i + 1 ' Incrémentation du compteur de boucle ENDDO ' fin de boucle Pin PEnbA mise à l'état haut ' Latch des valeurs dans l'afficheur ENDSUB SUB WRITEHEURE ' Routine d'écriture de l'heure dans le DS1302. ' L'envoi des données du circuit se fait en trois temps. ' Le registre des secondes est d'abord remis à zéro, ' puis le registre des minutes est mis à jour et ' enfin le registre des heures est mis à jour. ' En Entrée, cette routine à besoin des variables Moment, Heures ' et minutes ainsi que des constantes "hardware" : PEnbH, PDatH et PClkH. ' Les variables de travail i et j sont modifiées. ' Il n'y a pas de variable de Sortie. i = ENT(Minutes/10)*16 + (Minutes - ENT(Minutes/10)*10) ' Conversion des Minutes en "BCD" j = ENT(Heures/10)*16 + (Heures - ENT(Heures/10)*10) + Moment*32 + 128 ' Conversion des Heures en "BCD" Pin PEnbH mise à l'état haut ' Activation du DS1302 Envoi de $80, puis $00 en mode série sur les pins PDatH et PClkH ' Remise à zéro des secondes Pin PenbH mise à l'état bas ' désactivation du DS1302 PAUSE de 1mS ' Pause pour "CE inactive Time" Pin PEnbH mise à l'état haut ' Activation du DS1302 Envoi de $82, puis i en mode série sur les pins PDatH et PClkH ' Ecriture des Minutes Pin PenbH mise à l'état bas ' désactivation du DS1302 PAUSE de 1mS ' Pause pour "CE inactive Time" Pin PEnbH mise à l'état haut ' Activation du DS1302 Envoi de $84, puis j en mode série sur les pins PDatH et PClkH ' Ecriture des Heures Pin PenbH mise à l'état bas ' désactivation du DS1302 ENDSUB SUB READHEURE ' Routine de lecture de l'heure dans le DS1302. ' La lecture des valeurs se fait en deux temps. Il faut d'abord écrire l'adresse ' du registre, puis lire la valeur de ce registre. Cette opération est répétée ' 3 fois pour lire successivement les heures, minutes et secondes. Ensuite, ' les variables Moment, Heures, Minutes et secondes sont calculées. ' En Entrée, cette routine à besoin des constantes "Hardware" ' : PEnbH, PDatH et PClkH. ' Les variables de travail i, j et k sont modifiées. ' En sortie, les variables Heures, Minutes, Secondes et Tempstot sont ' mises à jour. LET PrecSecondes = Secondes ' Mise en mémoire de Secondes Pin PEnbH mise à l'état haut ' Activation du DS1302 Envoi de $81 en mode série sur les pins PDatH et PClkH ' Commande "Lecture des secondes" Lecture de i en mode série sur les pins pDatH et PClkH ' Lecture des secondes Pin PenbH mise à l'état bas ' désactivation du DS1302 PAUSE de 1 ms ' Pause pour sécuriser la lecture Pin PEnbH mise à l'état haut ' Activation du DS1302 Envoi de $83 en mode série sur les pins PDatH et PClkH ' Commande "Lecture des Minutes" Lecture de j en mode série sur les pins pDatH et PClkH ' Lecture des Minutes Pin PenbH mise à l'état bas ' désactivation du DS1302 PAUSE de 1 ms ' Pause pour sécuriser la lecture Pin PEnbH mise à l'état haut ' Activation du DS1302 Envoi de $85 en mode série sur les pins PDatH et PClkH ' Commande "Lecture des heures" Lecture de k en mode série sur les pins pDatH et PClkH ' Lecture des Heures Pin PenbH mise à l'état bas ' désactivation du DS1302 Secondes = ENT(i/16)*10 + (i - ENT(i/16)*16) ' Calcul du nombre de secondes ' Conversion BCD -> Décimale Minutes = ENT(j/16)*10 + (j - ENT(j/16)*16) ' Calcul du nombre de Minutes ' Conversion BCD -> Décimale Heures = ENT(k/16)*10 + (k - ENT(k/16)*16) ' Calcul du nombre d'Heures ' Conversion BCD -> Décimale ENDSUB SUB READTEMP ' Routine de lecture de la température dans le DS1620. ' Le mode "simple" étant utilisé, il suffit d'envoyer l'octet de commande ' de lecture, puis entrer sur les mêmes lignes série, la valeur de la ' température. Ensuite, les variables Signtemp et Température sont calculées. ' En Entrée, cette routine à besoin des constantes "Hardware" ' : PEnbT, PDatT et PClkT. La variable de travail i est modifiée. ' En sortie, les variables Température et Signtemp sont mises à jour. Pin PenbT mise à l'état haut ' Activation du DS1620 Envoi de $AA en mode série sur les pins PDatT et PClkT ' Commande "lecture de la température" Lecture de i en mode série sur les pins pDatT et PClkT ' Lecture de température sur 9 bits Pin PenbT mise à l'état bas ' désactivation du DS620 Signtemp = ENT(i/256)*256 >> 1 ' Extraction du 9ième bit de i i = i - Signtemp*256 ' Recalcul de i sur 8 bits IF Signtemp = 0 ' Si température positive Température = ENT(i/2) ' Calcul de la température ELSE ' Si température négative Température = ENT((~i+1)/2) ' Complémentaire à 2 ENDIF ENDSUB SUB LECTURE ' Routine de lecture des boutons poussoirs et du potentiomètre. ' Cette routine effectue les lectures sur les entrées Touche et Pot ' et calcule l'état des variables Touche et TempoM ' En Entrée, cette routine à besoin des constantes "hardware" : ' BoutonUP, BoutonDN et Pot. Les variables de travail i, j et k sont modifiées ' En sortie, les variables TempoM et Touche sont modifiées. LET i = 0 LET j = 0 LET k = 0 LET Touche = 0 Lecture de la valeur du Pot dans i ' Lecture de l'entrée "Pot" Lecture de l'entrée BoutonUP dans j ' Lecture de l'entrée (0 ou 1) Lecture de l'entrée BoutonDN dans k ' Lecture de l'entrée (0 ou 1) LET TempoM = ENT(i/"N") + "M" ' Le facteur N devra être définit par ' le "hardware" associé. C'est ce facteur ' qui définira le temps maximal de ' l'alternance de l'affichage, le ' facteur M définira la valeur minimale EXEMPLE: La valeur maximum de lecture du Pot vaut 632, dans ce cas, Le facteur N = 632 divisé par 5 qui est la valeur minimale que nous voulons = 126 et M = 7 , pour obtinir des variations allant de 5 à 12 secondes. soit (i/126) + 7. IF j = 1 THEN ' Test si appuis sur la touche "UP" Touche = 2 ' Mise à jour de la variable Touche ELSE ' (Donc, Touche UP Prioritaire) IF k = 1 THEN ' Test si appuis sur la touche "DOWN" Touche = 1 ' Mise à jour de la variable Touche ENDIF ENDIF ENDSUB SUB AFFIHEURE ' Routine d'affichage des heures et minutes. ' En entrée, cette routine à besoin des variables Heures et Minutes. ' Les variables Comser et Digit(4) sont modifiées. ' Cette routine utilise la routine WRITEAFFI LET Comser = 201 ' Commande pour affichage de l'heure LET Digit(0) = ENT(Heures/10) ' Màj du Digit(0) (Dizaine d'heures) LET Digit(1) = Heures - Digit(0) ' Màj du Digit(1) (Unités d'heures) LET Digit(2) = $E ' Màj du Digit(2) (Signe "=") LET Digit(3) = ENT(Minutes/10) ' Màj du Digit(3) (Dizaines de minutes) LET Digit(4) = Minutes - Digit(3) ' Màj du Digit(4) (Unités de minutes) GOSUB WRITEAFFI ' Rafraîchissement de l'afficheur ENDSUB SUB AFFITEMP ' Routine d'affichage de la température ' En entrée cette routine à besoin des variables Température et Signtemp. ' Les variables Comser et Digit(4) sont modifiées. ' Cette routine utilise la routine WRITEAFFI IF Signtemp = 0 THEN ' Si Température positive LET Comser = 227 ' Commande d'Affi pour T° Positives LET Digit(0) = $0 ' Màj du Digit(0) (Digit éteint) LET Digit(1) = ENT(Température/100) ' Màj du Digit(1) (Centaine de degré) LET Digit(2) = ENT((Température-Digit(1)*100)/10) ' Màj du Digit(2) (Dizaine de degré) LET Digit(3) = Température-Digit(1)*100-Digit(2)*10 ' Màj du Digit(3) (Unité de degré) LET Digit(4) = $F ' Màj du Digit(4) (Signe "°") GOSUB WRITEAFFI ' Rafraîchissement de l'afficheur ELSE ' Si Température négative LET Comser = 243 ' Commande d'Affi pour T° Négatives LET Digit(0) = $0 ' Màj du Digit(0) (Digit éteint) LET Digit(1) = $D ' Màj du Digit(1) (Signe -) LET Digit(2) = ENT((Température/10) ' Màj du Digit(2) (Dizaine de degré) LET Digit(3) = Température-Digit(2)*10 ' Màj du Digit(3) (Unité de degré) LET Digit(4) = $F ' Màj du Digit(4) (Signe "°") GOSUB WRITEAFFI ' Rafraîchissement de l'afficheur ENDIF ENDSUB SUB CHANGEHEURE ' Routine qui effectue le changement d'heure et qui met à jour le circuit DS1302 ' Cette routine incrémente ou décrémente les minutes en fonction des touches ' appuyées. Ensuite, les secondes sont remises à zéro, le circuit DS1302 est ' mis à jour et la nouvelle heure est affichée. Cette routine effectue ' l'accélération de la mise à l'heure (si une touche est appuyée longtemps) ' et applique un timeout pour sortir de la routine. ' En entrée, la routine à besoin de la variable Touche et de la constante Timemax ' Les variables Timeout, Compteur, Heures, Minutes, Secondes et Anttouche sont ' modifiées. Il n'y a pas de variable de sortie. ' Cette routine utilise les routines WRITEHEURE, AFFIHEURE et LECTURE. LET Timeout = 0 ' Remise à zéro des variables LET Compteur = 0 ' Timeout et compteur DO ' Début de la boucle de mise à l'heure IF Touche = 2 THEN ' Si touche "UP" appuyée LET Timeout = 0 ' Remise à zéro du timeout LET Minutes = Minutes + 1 ' Incrémentation des minutes IF Anttouche = 2 THEN ' Si la touche précédente était "UP" LET Compteur = Compteur + 1 ' Incrémentation du compteur d'appuis ELSE ' Si la touche préc. n'était PAS "UP" LET Compteur = 0 ' Remise à zéro du compteur d'appuis ENDIF IF Compteur > 14 ' Lorsque le compteur arrive à 15 LET Compteur = 15 ' remise à 15 du compteur d'appuis ' pour éviter un dépassement de valeur ' lorsque compteur arrive à 255. LET Minutes = Minutes + 9 ' Incrémentation des minutes par (9+1) ENDIF ' 10 minutes IF Minutes > 59 THEN ' Si les minutes dépassent 59 LET Minutes = Minutes - 60 ' Remise à jour des minutes et LET Heures = Heures + 1 ' incrémentation des heures IF Heures = 24 ' Si les heures égalent 24 LET Heures = 0 ' Remise à zéro des heures et ENDIF ' ENDIF ' Ajustement de la valeur de LET Anttouche = 2 ' la touche précédente ELSEIF Touche = 1 THEN ' Si touche "DOWN" appuyée LET Timeout = 0 ' Remise à zéro du timeout LET Minutes = Minutes - 1 ' Décrémentation des minutes IF Anttouche = 1 THEN ' Si la touche précédente était "DOWN" LET Compteur = Compteur + 1 ' Incrémentation du compteur d'appuis ELSE ' Si la touche préc. n'était PAS "DOWN" LET Compteur = 0 ' Remise à zéro du compteur d'appuis ENDIF ' IF Compteur > 14 ' Lorsque le compteur arrive à 15 LET Compteur = 15 ' remise à 15 du compteur d'appuis ' pour éviter un dépassement de valeur ' lorsque compteur arrive à 255. LET Minutes = Minutes - 9 ' Décrémentation des minutes par ENDIF ' (-9 + -1 ) 10 minutes IF Minutes > 59 THEN ' Si les minutes dépassent 59 LET Minutes = Minutes + 60 ' Remise à jour des minutes et LET Heures = Heures - 1 ' décrémentation des heures IF Heures = 255 ' Si les heures passent sous zéro, LET Heures = 23 ' remise des heures à 23. ENDIF ' ENDIF ' Ajustement de la valeur de LET Anttouche = 1 ' la touche précédente ELSE ' Si aucune touche n'est appuyée LET Anttouche = 0 ' Ajustement de la valeur de la touche ' précédente LET Timeout = Timeout + 1 ' Incrémentation du Timeout ENDIF ' GOSUB WRITEHEURE ' Ecriture de l'heure dans le DS1302 GOSUB AFFIHEURE ' Affichage de l'heure GOSUB LECTURE ' Lecture des touches et du POT UNTIL Timeout < Timemax ' Bouclage tant que Timemax n'est pas ' dépassé. ENDSUB