Projet d'architecture
BUS I2C
Chef de Projet
M François Montanet
Projet de 2 semaines du 27 janvier au 4 février
![]()
Etude du protocole
Réalisation des cartes
Programmation d'un driver
Création d'une application fonctionnelle
![]()
SOMMAIRE
I. Le Projet
*A. Utilisation
*1. Soft
*2. Hard
*B. Réalisation
*1. Soft
*2. Driver
*II. Problèmes rencontrés :
*A. Niveau de l'avant-projet :
*1. Le flot d'information
*2. La synthèse
*B. Niveau Hard :
*1. La carte Convertisseur A/N
*2. La carte Enfichable
*3. Le câble de liaison
*C. Niveau du Soft :
*1. Niveau du Driver
*2. Niveau de l'Interface
*3. La liaison entre Driver et Interface
*D. Niveau de l'Information
*1. La recherche d'information
*2. La cohésion d'un groupe de travail
*E. Niveau de la présentation
*III. Listing DRIVER
*
![]()
Possibilité en pratique : Apres le lancement du logiciel l'utilisateur va pouvoir générer des courbes représentant des variations de courant via un bus I2C et un convertisseur A/N . Ces variations pourront être contrôlées grâce à un oscilloscope. Toutes les commandes sont lancées à partir de menu déroulant et de bouton à clicker. Nous avons mise en place une session où l'utilisateur peut étalonner son application afin d'affiner ses réglages ( schéma 0 )

Générateur de tension : Fonctions usuelles
L'utilisateur pourra sélectionner les fonctions sinusoïdales, triangulaires, créneau ( schéma 1 )

Il choisit la période et l'amplitude ( schéma 2 )

L'affichage est assez long de plus il ne représente que 1/10 de la période effective. On calcule les points que l'on transmettra mais l'amplitude est limitée par la tension de référence du convertisseur A/N
Fonction issue d'interpolation
Interpolation par morceau
L'utilisateur place des points sur la zone de traçage puis choisie un type d'interpolation par morceau
Degré 1 : cela correspond a une interpolation linéaire c'est à dire une fonction linéaire par morceau
Degré 2 et plus : cela correspond a une fonction du degré choisie entre deux points
Degré n : l'utilisateur place des points sur la zone de traçage puis choisit interpolation de degré n ( schéma 3 )
Il y a la possibilité de rajouter des points pour affiner la courbe.

Limite :
Calcul: Lorsque l'utilisateur saisit un grand nombre de points les calculs sont excessivement longs
Amplitude : Le convertisseur A/N a une tension maximum de référence limitée entre 2,8 et 4.1 il arrive que la tension de référence soit modifiée lorsque l'on passe trop rapidement d'un état à un autre ou lorsque l'on fait un usage prolongé.
Période : L'écran représente 6,6 s
Plage de fréquence : pour le créneau de 13ms à 6s soit une fréquence de 200mHtz à 75Hz
Pour les fonctions sinusoïdales et triangulaires de 26 ms à 6 s soit une fréquence de 200mHtz à 40Hz
Transmission : Nous avons diminué le temps de transfert des donnés du driver au Hard au maximum donc l'information est transmise à intervalles de temps régulier cependant bien que ce taux soit assez indépendant du processeur il varie beaucoup suivant la plate-forme d'utilisation en effet sous DOS on transmet les données 7,3 fois plus vite que sous windows 3.11
Montage :
Il faut d'abord insérer la carte contenant le 8584 dans un slot ISA libre , qui se trouve sur la carte mère du PC
pour cela il faut enlever le couvercle de l'unité centrale et regarder à l'intérieur . S'il y a un slot ISA libre on insère la carte dedans .Puis il faut vérifier qu'il n'y a aucun conflit au niveau des adresses avec d'autres cartes. Notre carte a par défaut l'adresse 300h. Une fois installée correctement il faut relier la carte I²C (celle contenant le 8584) avec la carte de conversion A/N et N/A grâce au câble fourni avec les deux cartes il faudra s'assurer qu'il n'y aura aucune interférence extérieure ( genre champ magnétique ) ensuite, on relie les entrées d'un oscilloscope avec les broches que l'on veut étudier maintenant, on peut installer le logiciel et l'utiliser.
Algorithmes d'interpolation : Le principe de Lagrange
La façon la plus simple d'approcher une fonction est l'utilisation d'un polynôme d'interpolation.
On choisit n+1 points x0, x1, …, xn.
On calcule y0 = f(x0), …, yn = f(xn).
On cherche un polynôme de degré n tel que Pn(xi) = yi, i = 0, …, n.
On obtient alors le polynôme
![]()
interpolant la fonction f aux points x0, x1, …, xn.
La formule de Lagrange
Soit le polynôme de degré n :

![]()
Donc
![]()
est un polynôme de degré n qui vérifie bien P(xi) = yi.
Ce qu'il faut savoir : pour s'adresser au 8584 ,il faut passer par le registre accessible directement i.e. S1 Grâce à lui on peut envoyer des ordres au 8584 et utiliser tous les autres registres de ce circuit
S0 : ( data ) registre des données
S0' : (own address) il contient l'adresse du circuit
S2 : (clock register) il permet de définir les fréquences d'horloge d'entrée fSCL et la fréquence d'horloge interne fSDA
S3 : ( interupt vector) il permet de définir un vecteur d'interruption par défaut, on accède aux registres du 8584 à l'adresse 300h qui vaut en binaire 11 0000 0000, le dernier bit s'appelant A0 pour pouvoir accéder au registre S1 il faut qu'A0 soit au niveau logique haut i.e. égal à 1 (donc on utilise l'adresse 301h) pour accéder aux autres registres il faut qu'A0 soit au niveau logique bas i.e. égal à 0 ( donc on utilise l'adresse 300h)
La procédure d'initialisation
il faut d'abord faire, un reset qui doit durer au moins 30 cycles d'horloge machine, ensuite, on charge dans le registre S1 (donc A0 = 1 ) la valeur 80h (1000 0000b) ce qui va nous permettre d'avoir accès au registre S0' et d'annuler le mode Serial Interface, maintenant, on va mettre dans S0' l'adresse effective du circuit I²C ( en tant que maître ) qui est 80h. Pour cela on écrit dans S0' la valeur 55h (avec A0=0), on envoie ensuite la valeur A0h dans S1 qui va nous permettre de définir les fréquences d'horloges grâce au registre S2 ( ici A0=1), on met dans S2 la valeur 1Ch (0001 1100b) qui définit fSCL à 90khz et fSDA à 12Mhhz (A0 =0), on écrit dans S1 la valeur C1h ( avec A0=1) qui autorise l'interface serial et qui met les signaux SDA et SCL au niveau logique, haut ( ici 1 ), au prochain accès avec A0=0 on accédera au registre S0
La procédure d'écriture :
Remarque : Dès que l'on accède au registre S1 , A0=1. Dès que l'on accède aux autres registres, A0=0, on lit le contenu du registre S1 et on vérifie que le bus n'est pas occupé . Si c'est le cas, on passe a l'étape suivante , sinon on recommence ce point, pour cela on regarde si le bit de plus bas poids est égal a 1, on met dans S0 l'adresse du circuit esclave qui est ici celui du convertisseur A/N - N/A . cette adresse vaut par défaut 40h (le dernier bit de cette adresse est égal a 0 ce qui indique que l'on va écrire dedans), on envoie la valeur C5h dans S1 ce qui permet au 8584 de générer une condition de départ, le prochain octet que l'on mettra dans S0 sera immédiatement transféré dans le bus I²C, maintenant il faut envoyer un mot de commande au convertisseur pour lui dire d'activer la sortie analogique et d'y mettre ce qu'il reçoit, pour cela on envoie comme première donnée avant le transfert l'octet 44h (0100 0100b) qui active l'`Autoincrement Flag` et l'`Analog Output Flag`
c'est a partir de maintenant que commence vraiment le transfert, on lit le contenu de S1 ,on regarde si le bit de plus haut poids est égal à zéro, si c'est le cas alors, on passe a l'étape suivante . Cela veut dire que la transmission s'est bien faite. Sinon on recommence le point (1), on regarde si le bit 4 de S1 est égal à 0 ( i.e. si le récepteur (l'esclave) a fini de recevoir les données), si oui , on passe a la dernière étape (2), sinon on passe à l'étape suivante, si on a, tout transféré alors on passe à la dernière étape (2) sinon on continue, on écrit dans S0 la donnée à transmettre et on passe à l'étape (1), on met dans S1 la valeur C3h (1100 0011b) ,ce qui génère une condition d'arrêt, et le transfert est fini.
![]()
L'accès à l'information : Il est certes appréciable mais inutile quand on ne sait pas ce que l'on cherche. L'accès à Internet nous a permis d'accéder à un flot d'informations mais bien inutile avant de connaître la mesure du projet I2C.
Bien difficile : La encore comment faire une synthèse lorsque l'on ne parvient pas à définir les aboutissants du projet. Nous avons effectué une approche succincte du projet mais ce n'est qu'après avoir eu le Hard en main pendant quelques jours qu'un réel désir de synthèse a eu lieu . Comment faire marcher ?
La conception du convertisseur:
Nous avons pris soin lors du montage de choisir un code de couleur qui à facilité le debugage du Hard , Masse Noir, Rouge, SCL Jaune, SDA Blanc, INT Vert. Les pins de test 0 et +5 étaient doubles et trop proches un 0 et un +5 ont été supprimés pour éviter d'éventuels cours circuit pendant les tests. La plaquette a été surélevée pour éviter les dysfonctionnements occasionnés par des petits bouts de semi-conducteur abandonnés sur les tables.
Les éléments non utilisés : L'interrupteur DIL (sextuple) pour le réglage des E/S en cas de connections multiples. Le jumper d'alimentation extérieur. Le connecteur de ports d'entrée bidirectionnel E/S du PCF8574 nous avons utilisé pour tester nos E/S sur l'analyseur logique une pince pour micro circuit. Les pins d'entrée du PCF8591. Le connecteur din vers une autre carte I2C
Problèmes rencontrés
La tension de référence du convertisseur A/N théoriquement comprise entre 2.8 et 4.1V semble être instable après plusieurs heures d'utilisation sans raison apparente. En effet malgré la résistance ajustante de 5k branchée directement sur l'entrée du DAC l'étalonnage de la tension de référence ne se fait pour le moment plus et reste à sa limite inférieure soit 2.8V
Explications envisagées: Un contact déficient au niveau de la 14ème connexion du PCF8591. Détérioration de la résistance ajustante . Masse du PCF8591 .
Debugage: Pour cette étape nous avons utilise un analyseur logique de type 1663A de chez Helwett Packard © .
- nous avons vérifié que la comparaison ,avec le comparateur 74HCT688 ,de l'adresse logiciel et de l'adresse matérielle (celle du septuple interrupteur DIL) fonctionnait. Le problème qui est intervenu , fut l'interprétation de l'adresse donnée par le septuple interrupteur DIN.
- d'où l'étude de l'entrée non(CS) du PCD8584 (C.F. schéma x )
- ensuite nous avons vérifié que la clock CLK du 8584 était bien la moitié de la clock entrée en OSC ( pin 30 , face B , cf schéma x), ceci étant du au fonctionnement de la bascule JK (circuit 74HCT107)
- puis on commença l'étude des broches du 8584 non(RD) non(RW) non(RESET)
ensuite ça a été le tour des broches SDA et SCL du 8584 , et les broches de données DBx (0 <= x <= 7). Nous avons pu les tester grâce au driver fournit avec la carte , notre driver n'étant pas encore fini.
La conception de l'Enfichable :
Il y a peu de composants , la carte est donc de petite taille cependant il y a de nombreuses soudures à faire certes facilitées par des supports du puce mais difficiles au niveau du réseau de résistances protégeant le 74HCT688 E/S . De nombreux points de contrôles permettent une vérification des signaux. Il faut faire attention lors de l'enfichage de la carte sur le bus ISA car du moins pour la notre le circuit et un peu plus petit que l'emplacement d'où des connections sur le bus précaire 74HCT688 gestion des E/S
PCF8584 gestion du protocole I2C
Les éléments non utilisés : L'interrupteur sextuple pour adresser la carte ( en 300 ) c'était déjà OK. Le jumper pour la gestion de l'interruption processeur
Il s'agit d'une nappe de 6 câbles d'environ 50 cm avec deux connecteurs din de 6 broches à l'extrémité. Cette liaison est mal adaptée une câble tubulaire à 5 brins et d'environs 1m aurait facilité l'utilisation de plus le protocole I2C est lent et ne nécessite pas des connexions aussi courtes
Le choix du logiciel de développement :
Quick C version DOS Pourquoi ? C'est le seul compilateur C installé sur les PC
Les problèmes survenus : Un temps assez long pour la compréhension des Data Sheets et du fonctionnement de chaque composant des deux cartes. Lors des tests du driver il fut très difficile de trouver ce qui ne marchait pas L'oscilloscope était-il bien relié aux cartes ? Y avait-il des interférences extérieures ? ( bobine sous une des cartes ! ! ! = une heure de perdue ! ! !) Les algorithmes d'initialisation , d'écriture et de lecture du driver étaient-ils corrects ? La syntaxe du driver était-elle correcte ? Il a fallu concilier tous ces points , et les vérifier à chaque instant du débugage. Le plus gros problème fut une mauvaise utilisation des Data Sheets qui entraîna une mauvaise programmation du driver ( Heureusement , en reprenant tout à zéro on s'aperçut de la mauvaise interprétation de nos sources ).
Le logiciel de développement : Nous avons utilisé le logiciel Visual Basic 3 utilisable sur plate-forme windows 3.11 permettant une interface graphique intéressant . Un manque évident de logiciel de développement graphique sur plate-forme windows à l'école a guidé notre choix. En effet sur les machines seules QuickC est installé parfait pour le développement du driver mais mal adapté à une interface graphique ou trop long pour un rendu graphique convenable. Après une journée de travail pour élaborer un environnement graphique sous C nous avons du nous résoudre à abandonner cette idée... Nous avons profité d'une installation sauvage de ce logiciel pour développer notre interface !
Découverte de ce logiciel de développement . Il s'agit d'un logiciel dont les rudiments de programmation s'appuient sur le langage Basic sans pour autant avoir la même syntaxe avec des fonctions graphiques d'utilisation simplifiées. Chaque objet est rattaché à un script de programmation ce qui rend le programme évolutif .
Les limites de Visual Basic 3. Lors de nos élaborations d'interpolations, nous avons constaté. Des temps de calcul élevés en particulier pour les interpolations polynomiales de degrés n. Des saturations de la piles pour les interpolations de Splin Cubique Libre ou Forcé. Y a-t-il une réelle limite du logiciel ou est-ce une mauvaise programmation ? Pour le temps de calcul, il ne fait aucun doute que le logiciel y est pour beaucoup puisque les temps de calcul sont similaires chez d'autres groupes. Pour la programmation du Splin un groupe la mise en place sur un autre type de logiciel de développement
Le contenu: Les fonctionnalités: Les interpolations
L'élaboration d'interpolations sinusoïdale triangulaire et créneau ont été remplacés par les fonctions du même type en effet pourquoi interpoler un triangle alors que c'est une fonction élémentaire ... Compréhension de la formule de Lagrange et Splin grandement facilité par un travail en commun sur un support documentaire établi au cours des années d'études antérieures . Cependant des problèmes calculatoires sont survenus lors de la mise en place de l'algorithme sur Visual. Nous avons établi une ordonnée artificielle dans le calcul des interpolations donc le résultat est celui d'une interpolation effectuée à partir de points tout positifs. Nous avions pensé que cela pourrait simplifier la conversion sur une table positive (0 255) en fait la conversion n'était pas un réel problème
La conversion des données des points n'est pas effectuée parallèlement au tracé, il en résulte une perte de temps calcul mais une meilleure définition pour la conversion. Limite de la conversion lors d'une interpolation polynomiale le résultat est donné sur l'écran et dans un tableau de n point , ce tableau représente une durée Ainsi, il n'est pas possible de modifier la fréquence sur la courbe obtenue par interpolation polynomiale. Nous avons choisi de ne pas faire intervenir la fréquence dans la partie driver qui nous sembler la plus délicate à aborder au début . La fréquence est donc géré par la partie soft ce qui s'est avéré judicieux dans la mesure où le temps d'horloges des ordinateurs diffère de l'un à l'autre.
La réutilisation des données : Nous avons choisi de stocker les informations dans un fichier texte, car, nous ne savions pas comment nous allions réutiliser les données avec le driver bien entendu cela ralentit de beaucoup les performances globales
Les structures:
Type : Les données sont principalement stockées dans des tableaux. Plusieurs choix ont été envisagés avec les autres groupes de travail pour la dimension des tableaux. Un tableau ou chaque point affiché représentent une information. Nous avons choisi un tableau d'information non limité avec un rapport de proportionnalité avec l'affichage écran et l'information transmise c'est à dire plus d'information transmise que d'information affichée. Deux choix différents laissant une bonne place à la course à la performance
Des variables globales: Ces variables permettent la cohésion entre les informations fournies par l'utilisateur et les informations transmises au bus I2C en particulier les périodes et les amplitudes. Nous avons du faire un étalonnement de la période qui varie assez peu suivant les machines puisque les informations sont envoyées à intervalle régulier. Nous avons utilisé une tension de référence de 4,1 v pour définir une amplitude maximum puis un rapport de proportionnalité a été établis .
3. La liaison entre Driver et Interface
Le QC et Visual: Programmer du Hard déjà fait en TP : Programmer une interface graphique déjà fait aussi
Mais faire la liaison des deux, a posé des problèmes, car nous ne savions pas comment intégrer une DLL au sein de Visual basic . Nous avons donc choisi le fichier texte partie commune a toutes les applications de programmation . Perte assez fréquente du fichier texte ou des données qu'il contenait
Auprès des professeurs: Nous avons été un peu perdus au début, il nous a semblé être assez mal soutenu mais en fait cette étape s'est avéré nécessaire pour notre compréhension du problème .
2. La cohésion d'un groupe de travail
Au sein des autres projets: Les informations d'ordres logiciel et utilisation des matériels se sont très bien passés malgré une utilisation intensive par moment du matériel de test
Au sein des projets I2C :Un échange d'information entre groupe a favorisé une sorte de course à la performance et une valorisation pour les premiers projets " achevés ". Il est dommage que certains ne se soient pas prêtés au jeu.
Au sein du binôme :Des tensions et des divergences d'opinions on aboutit à une " séparation " des taches
Opération très bénéfique et nécessaire puisque le temps de compréhension d'un problème a été divisé par deux
En effet lorsqu'un problème est résolut explication et information au binôme. Lorsqu'un problème ne trouvait pas de réponse, nous avons fédéré nos efforts jusqu'à la solution. Divisé pour mieux avancer ! !
Avant la démonstration de notre projet ,nous avons fait quelques dernières modifications sur un PC ayant une fréquence d'horloge différente de l'ordinateur qui a servi à la démonstration.
Plusieurs problèmes sont survenus : Dans les modifications apportées nous avons ,par mégarde ,interverti deux lignes de code . Conséquence une amplitude de sortie différente de ce que nous nous attendions à voir sur l'oscilloscope. De plus les modifications ont été faites en fonction de l'autre PC ,et le programme a été compilé sur cette même machine. Les périodes n'étaient plus ce quelles devaient être. Ce problème venant des paramètres de l'étalonnage ils ne convenaient pas pour la machine test et influençaient la sortie sur l'oscilloscope. Ces deux problèmes aboutissaient à une même erreur en sortie sur l'oscilloscope. Il a donc fallu s'adapter très rapidement à cette situation et trouver ce qui n'allait pas durant la démonstration . ( d'ou l'intérêt de faire ce genre de modifications aussi minimes soient elles sur la machine test ,et de vérifier le programme avant la démonstration ) c'est ce que nous avons réussi à faire en reprenant rapidement le programme et nous avons remarqué que la dernière machine où avait eu lieu les dernières modifications était différente de notre machine test. De plus nous nous sommes aperçu le lendemain qu'il y avait un virus sur le PC où les modifications avait eu lieu. Y aurait-il eu une conséquence sur le déroulement du programme ?
En résume il est vivement déconseillé de faire des modifications de dernières minutes , et sans prendre le temps de vérifier le nouveau programme.
III. Listing DRIVER
#include <stdio.h>
#include <io.h>
#include <conio.h>
#include <math.h>
#define A0LOW 0x300
#define A0HIGH 0x301
#define NOM_FICHIER "a:\\i2c\\test1.txt"
#define ADR_ESCLAVE 0x40
#define GOGO 300
#define NO_ERROR 0
#define I2C_ERROR_FOPEN 1
#define I2C_ERROR_EOF 2
#define MAX 4096
unsigned char tab[MAX];
int I2C_ERROR=0;
FILE *fichier;
int nb_bytes=4096;
void delay(long t)
{
long i;
for(i=0;i<t;i++);
}
void Lecture(void)
{
int i,caractere;
for(i=0;i<MAX;i++)
{
fscanf(fichier," %d \n",&caractere);
tab[i]=(unsigned char)caractere;
}
}
int main(void)
{
unsigned int i=0;
fichier=fopen(NOM_FICHIER,"rt");
if (fichier==NULL)
{
printf("erreur au niveau du fichier");
return(0);
}
Lecture();
delay(GOGO);
outp(A0HIGH,0x80); // ouvre S0
delay(GOGO);
outp(A0LOW,0x55);
delay(GOGO);
outp(A0HIGH,0xA0); // ouvre S2
delay(GOGO);
outp(A0LOW,0x1C); // init clk
delay(GOGO);
outp(A0HIGH,0xC1); // SDA et SCL en 1
delay(GOGO);
printf("..OK\n");
while( ( (inp(A0HIGH)) % 2) == 0) printf("bus non libre\n");
outp(A0LOW,0x90); //envoie adresse esclave
outp(0x91,0x44);
delay(GOGO);
outp(A0HIGH,0xc5); //condition START
outp(A0LOW,0x44);
while(!kbhit())
{
delay(GOGO);
while ( ( ((inp(A0HIGH))>>7) %2 ) == 1 )
{
delay(GOGO);
printf("PIN == 1\n");
}
if ( ( ( inp(A0HIGH)>>4 )%2 ) ==0)
{
outp(A0LOW,tab[((i++)%MAX)]);
if (i==0) i=1;
delay(GOGO);
}
else
{
printf("LBR <> 0\n");
break;
}
}
outp(A0HIGH,0xc3); // condition STOP
printf("sortie");
fclose(fichier);
return(1);
}