Le PIC16F84 Exemples ◘ Routines de gestion du port I2C ----------------------------------------------------------------------------------------------------------------NOTE sur BUS I2C Le BUS I2C est un système matériel et logiciel de transmission de données entre plusieurs équipements. Inventé par PHILIPS il fait partie de la de famille des BUS locaux (LAN) . La transmission se fait sur 2 fils plus masse L’un des fils SDA transporte les données en série ,les niveaux logiques étant 0 et 5V ,l’autre SCL porte un signal d’horloge qui synchronise les échanges. Les qualités du BUS I2C reposent entièrement sur la structure matérielle adoptée. Tous les équipements sont accrochés en parallèle sur les deux fils du BUS . Chacun d’entre eux est constitué d’un MOS destiné à forcer le niveau logique à zéro et un ampli permettant au circuit d’observer le niveau présent sur le fil considéré. Cette possibilité de s’auto espionner permet de gérer les conflits entre les divers équipements présents. Ainsi , si un seul +5V équipement force un fil du BUS au niveau bas , tous les autres le verront au 0 ,c’est une structure ET CABLE . Rp 4k7 Une résistance de PULL UP commune à tous les SDA ou SCL circuits remonte à 1 le niveau des fils si tous les circuits sortent un niveau haut . Une valeur typique de cette Rs 100 résistance est 4700Ω .Une résistance série de 100Ω facultative peut être placée en série avec chaque entrée; elle est surtout utile si les fils sont longs (plusieurs mètres) Circuit . Lorsque aucun composant n’est actif les deux fils CLC et SDA sont au niveau haut le bus est libre. ( F ) SDA L’état du fil de données SDA ne peut être modifié que lorsque SCL est bas SCL Un bit de donnée (état de SDA ) est émis pendant l’état haut de SCL Chaque envoi de bit est donc associé à une Envoi d'une donnée impulsion sur SCL La règle de non variation de SDA lorsque SCL SCL=1 est haut est violée dans deux circonstances importantes : - La condition de Start : (S ) SDA SDA passe de 1 à 0 pendant que SCL est au 1 - La condition de Stop (P ) Condition Condition SDA passe de 0 à 1 pendant que SCL est haute de START de STOP Pour les circuits les plus courants (Première génération) la fréquence d’horloge maximale (et conseillée ) est de 100kHz . Sur le BUS sont présents : Un circuit maître qui pilote le transfert ,c’est lui qui génère les signaux d’horloge sur SCL il peut envoyer des données vers les circuits esclave (émetteur ) ou en recevoir (Récepteur ) Des circuits esclave qui peuvent être des récepteurs recevant des octets venant du maître ou des émetteurs qui envoient des octets vers le maître . Chaque circuit esclave possède une adresse sur 7 bits . Les adresses ne sont pas distribuées au hasard mais attribuées par l’organisme responsable du BUS I2C, chaque type de composant possède son adresse propre ,nous reviendrons sur ce point plus loin. FORMAT DU TRANSFERT : Le transfert commence toujours par une condition de Start générée par le maître . Sont envoyés ensuite successivement ,et accompagnés à chaque fois d’une impulsion d’horloge ; 8 bits dont les 7 premiers constituent l’adresse de l’esclave que l’on veut contacter suivis 1 Le PIC16F84 Exemples ◘ d’un dernier bit qui indique le sens du transfert 1 pour une lecture esclave vers maître, 0 pour une écriture maître vers esclave. Le transfert se termine par un ACQUITTEMENT . Cet acquittement est une procédure essentielle ;le maître relâche le fil SDA et génère un top d’horloge au cours duquel le circuit esclave doit forcer à 0 le fil SDA pour indiquer qu’il a bien reçu le message. 0 1 0 0 1 2 3 4 1 1 1 W 6 7 8 Bus relaché SDA 5 9 SDA piloté par l'esclave ACK Demande d'écriture vers l'esclave d'adresse 0100111 Un récepteur esclave peut dans certains cas ne pas accepter la donnée ,par exemple s’il est occupé à une tâche, dans ce cas il ne valide pas acquittement et le maître peut ,soit générer une condition de stop, soit s’adresser à un autre esclave plus disponible . L’adresse étant envoyée le transfert se poursuit par la réception (dans ce cas l’esclave pilote SDA au rythme de SCL envoyée par le maître ) ou l’émission d’un octet suivi d’un acquittement par le récepteur . Exemple : 1 2 3 4 1 0 1 1 5 6 7 0 0 8 9 1 2 3 4 5 6 7 8 9 SCL SDA 0 R Lecture S P Par l'esclave A 1 0 0 0 1 0 1 1 Envoyé par l'esclave 8BH Dans la suite nous simplifierons ce dessin en : S Adrs Escl R/W A Data A P Note: Il est possible de recevoir plusieurs octets à la suite les uns des autres, le maître doit acquiter entre chacun sauf pour le dernier juste avant le STOP. JAMAIS d'ACQUITEMENT DEVANT LE STOP FINAL L'Horloge peut être irrégulière , seule la position relative des fronts compte. 1 Adresse 7bits 1 A DU MAÏTRE A Data1 Data2 DE L’ESCLAVE 2 A Data3 1 Le PIC16F84 Exemples ◘ Les PIC ne possèdent qu’un nombre très réduit de fils d’accès. Il est par exemple difficile de connecter à un PIC un clavier , un afficheur et quelques leds de signalisation. Il est bien sûr possible de mettre en œuvre des latches et des buffers 3 états connectés sur PB et sélectionnés à partir du port A, mais cela alourdi considérablement le circuit imprimé et manque de souplesse. Les circuits I2C n’utilisant que 2 fils seulement fournissent une solution élégante , mais il faut gérer le bus I2C ce qui , à la différence du 80552 par exemple , n’est pas prévu à l’origine. Voir note sur le port I2C Le logiciel présenté ci dessous résout ce problème. ,on notera que les signaux d’acquittement ne sont pas gérés c’est à dire que le processeur ne s’aperçoit pas si l’un des circuits n’acquitte pas . Il n’est pas difficile d’introduire quelques lignes dans le programme pour remédier à ce manque .En pratique si les boîtiers I2C sont câblés sur la même carte ou à faible distance les erreurs de transmission sont rares. Et le logiciel présenté est suffisant. Le port B du PIC est libre , il permet par exemple de gérer les diodes électroluminescentes de contrôle et quelques poussoirs. Seuls les fils RA0° et RA1 sont utilisés par les boîtiers I2C reliés. Le fil RA1 qui pilote l’horloge est programmé en sortie , la résistance de pull up de 4,7k n’est donc pas nécessaire .Elle l’est par contre pour le fil de données RA0=SDA qui peut être entrée ou sortie. Connexion des circuits I2C +5V 4,7k SCL SDA GND +5V Circuit I2C Ce programme utilise 3 cases PORT B mémoire que nous avons prises en haut de la mémoire , mais il est facile de les changer de place. Votre programme de gestion des boîtiers I2C (Port PCF8574, horloge temps réel, EEPROM etc…) devra être écrit à l’endroit indiqué. A titre d’exemple un compteur sur le port I2C mettant en œuvre un PCF8574 est présenté Title’ Gestion du bus I2C’ List p=16F628 #include<p16F628.inc> _CONFIG 0x3F21 SDA SCL KTEUR BUFF ADRS OCTET DELAI1 DELAI2 EQU EQU EQU EQU EQU EQU EQU EQU 0 1 0x20 0x21 0x22 0x23 0x24 0x25 ;configuration des fusibles internes dans le cas d’un ;PIC16F628 ;pour SDA=RA0 ;pour SCL=RA1 ;utilisées par la routine de retard org 0 Goto DEBUT ;-----------------------------------------------------------; Les MACROS ;-----------------------------------------------------------3 Le PIC16F84 Exemples ◘ SDAOUT MACRO ;met le fil SDA en sortie BSF STATUS,RP0 BCF TRISA,SDA BCF STATUS,RP0 endm SDAIN MACRO ;met le fil SDA en entrée BSF STATUS,RP0 BSF TRISA,SDA BCF STATUS,RP0 endm POSE MACRO ;sera intercalé pour respecter la vitesse possible du BUS NOP NOP NOP NOP NOP NOP endm SCLOUT MACRO BSF STATUS,RP0 BCF TRISA,SCL BCF STATUS,RP0 endm ;-----------------------------------------------------------ATTENTE ;attente longue pour routine de test CLRF DELAI1 CLRF DELAI2 BCLDL DECFSZ DELAI2,1 GOTO BCLDL DECFSZ DELAI1,1 GOTO BCLDL RETURN ;============================================================ ;Routines I2C ;============================================================= START ;é met une condition de start SDAOUT ;SDA en sortie (haut) BSF PORTA,SDA ;SDA prépositionné haut BSF PORTA,SCL ;SCL haut POSE BCF PORTA,SDA ;abaisse SDA alors que SCL est haute = START POSE BCF PORTA,SCL ;descente d'horloge pour sortie SCL basse RETURN ;sortie avec SDA OUT ;--------------------------------------------------------LITBIT ;place la valeur de SDA sur C BTFSS PORTA,SDA ;saut si SDA=1 GOTO ZEROL BSF STATUS,C ;C=1 si SDA=1 GOTO FINL ZEROL BCF STATUS,C ;C=0 FINL RETURN ;-------------------------------------------------------PLACEBIT ;place le contenu de C sur SDA BTFSS STATUS,C ;saut si C=1 GOTO ZEROP ;executé si C=0 BSF PORTA,SDA ;SDA=1 si C=1 GOTO FINP ZEROP BCF PORTA,SDA ;SDA=0 si C=0 4 Le PIC16F84 Exemples ◘ FINP RETURN ;-------------------------------------------------------CLOCK ;génération d'une phase d'horloge par le maître BSF PORTA,SCL ;montée d'horloge POSE CALL LITBIT ;L'état de SDA est transféré sur C BCF PORTA,SCL ;descente d'horloge RETURN ;sortie avec horloge basse ;--------------------------------------------------------ACK ;Le maître émet un acquitement BCF PORTA,SDA ;SDA=0 s'il ne l'était pas CALL CLOCK RETURN ;-----------------------------------------------------------NACK ;non acquitement ;ou attente acquitement esclave SDAIN ;SDA doit être en entrée CALL CLOCK ;L'esclave acquite SDA à la montée de SCL ;SDA est lu pendant le CLOCK ;sa valeur permet de vérifier que l'esclave ;a bien acquité .Nous ne l'avons pas fait ;cette amélioration est facile à ajouter SDAOUT ;retour à SDA en sortie RETURN ;------------------------------------------------------------STOP ;émet une condition de stop BCF PORTA,SDA ;SDA à zéro s'il ne l'était pas BSF PORTA,SCL ;horloge haute POSE BSF PORTA,SDA ;montée SDA alors que SCL est haute=STOP RETURN ;sortie avec SDA HAUT et SCL HAUT ;-------------------------------------------------------------INBYT ;Lit un octet envoyé par l'esclave ;l'octet reçu est chargé dans BUFF SDAIN ;SDA doit être en entrée CLRF BUFF ;BUFFER vidé, non indispensable MOVLW 8 MOVWF KTEUR ;chargement du compteur avec 8 LOOP1 CALL CLOCK ; l'esclave charge SDA à la montée d'horloge ; et l’état de SDA est transféré dans C RLF BUFF,1 ;introduction de C dans le LSB de BUFF DECFSZ KTEUR,1 ;décrément compteur, saut si 0 GOTO LOOP1 SDAOUT ;retour à SDA en sortie RETURN ;--------------------------------------------------------OUTBYT ;l'octet à envoyer doit être dans BUFF SDAOUT MOVLW 8 MOVWF KTEUR LOOP2 RLF BUFF,1 ;le bit le plus à gauche est placé dans C CALL PLACEBIT ;place C dans SDA en sortie CALL CLOCK ;top horloge envoi du bit DECFSZ KTEUR,1 GOTO LOOP2 RETURN ;============================================================ ;L'Adresse du port en écriture ou lecture est placée dans ADRS ;L'octet à envoyer est placé dans OCTET ;en position lecture l'octet lu est chargé dans OCTET 5 Le PIC16F84 Exemples ◘ ; EMETBYTE ;envoie OCTET vers le port d'adresse ADRS MOVF ADRS,0 ;adresse dans W MOVWF BUFF ;adresse dans BUFF CALL START CALL OUTBYT CALL NACK ;c'est l'esclave qui acquitte MOVF OCTET,0 ;octet à transmettre dans W MOVWF BUFF ;octet dans BUFF CALL OUTBYT CALL NACK CALL STOP RETURN ;-----------------------------------------------------------RECOIYBYTE ;recoit un octet envoyé sur le port I2C ;d'adresse ADRS MOVF ADRS,0 MOVWF BUFF ;adresse dans BUFF CALL START CALL OUTBYT CALL NACK ;c'est l'esclave qui acquitte CALL INBYT CALL NACK ;pour un seul octet reçu , pour plusieurs ;il faudrait acquitter CALL STOP MOVF BUFF,0 ;BUFF dans W MOVWF OCTET ;BUFF dans OCTET RETURN ;=============================================================== DEBUT movlw 0x07 movwf CMCON ;Ces deux lignes sont indispensables si l’on utilise un ;PIC16F628 car les fils RA0 et RA1 sont utilisés par ;deux comparateurs analogiques qu’il faut ici déconnecter. SCLOUT ; pour la gestion du BUS le fil h’horloge est en sortie BSF CLRF BCF STATUS,RP0 TRISB STATUS,RP0 MOVLW 0x42 MOVWF ADRS MOVLW 0 MOVWF OCTET CLRF PORTB ;Port B en sortie ;l’adresse du port du PCF8574 sur notre carte ;départ avec 0 UNENVOI CALL INCF INCF CALL GOTO EMETBYTE PORTB,1 OCTET,1 ATTENTE UNENVOI ;l'Octet est reçu sur le PORT 8574 ;le PORT B compte ;incrémentation d'OCTET pour le suivant END Si au lieu d’envoyer des octets sur le port du circuit PCF574 on voulait au contraire lire l’état de ce port il faudrait modifier les dernières lignes du programme écrites en bleu ci dessus . .par exemple : ;---------------------------------------------------------------------------------------------------------------------------MOVLW 0x43 ;adresse du PCF8574 en lecture 6 Le PIC16F84 Exemples ◘ MOVWF ADRS CLRF PORTB ;port B effacé LECTURE CALL RECOITBYTE ;l'état du port lu dans OCTET MOVF OCTET,0 ;OCTET dans W MOVWF PORTB ;transfert dans PORTB POSE GOTO LECTURE -------------------------------------------------------------------------------------------------------------------------- 7