Vous êtes sur la page 1sur 7

Christophe Berger binôme 1

BUS I2C
A)

Le bus I2C fonctionne avec 2 fils de liaison reliés à tous les circuits utilisant ce même bus I2C
et un fil de masse (permettant la différence de potentiel des signaux). Ces 2 fils de liaison
sont : - SDA (Serial Data) par lequel on transmettra toutes les données.
- SCL (Serial CLock) l’horloge. Tous les changements de bits sont prit en compte lors
d’un état haut de l’horloge.

Les fonctions START, STOP, ACKNOWLEDGE (ACK) et NO ACKNOWLEDGE (NACK)


sont utilisées lors des transmissions de données.
- START : annonce le début d’une transmission avec un front descendant pendant l’état
haut de SCL. Un START sera suivit l’adresse (sur 7 bits) du système avec lequel le
master communiquera puit un bit d’écriture ou de lecture. (une fois le lien établi la
liaison est réservé que pour le master/slave). Donc si l’on communique toujours avec
le même système mais qu’on veut changer de mode (lecture/écriture) il faut relancer
un bit START avant.
- STOP : annonce la fin d’une transmission et donc la libération de la liaison I2C pour
les autres systèmes avec un front montant lors d’un état haut sur SCL.
- ACKNOWLEDGE : une donnée est composé de 8 bits, lorsqu’une donnée est donc
transmise, le receveur doit répondre par un état bas s’y il la bien reçus.
- NO ACKNOWLEDGE : en mode écriture, si la donnée n’a pas bien été reçus le
receveur renvoi un état haut et la donnée lui sera retransmise. En mode lecture si le
maître renvoi un état haut en réponse, cela signifie qu’il a finit la lecture de donnée
(mais il faut toujours un bit PAUSE pour signaler la libération de la liaison).
-

B)
Lorsqu’un microcontrôleur ne dispose pas de périphérique adapter au bus I2C, il faut établir
une routine de gestion. Cette routine de gestion sera découpée en plusieurs parties.
Les temps choisis sont loin d’être vrais, car ils dépendent en partit de la cadence de
communication voulut entre le master et le slave.

START : DONNEE : STOP : ACK : ACK :

SCL = 1 Pour N de 7 à 0 SCL = 1 SCL = 0 SCL = 0


SDA = 1 Faire ( SDA = 0 SDA = 0 SDA = 1
Delay 1ms SDA = bit N Delay 1ms Delay 1ms Delay 1ms
SDA = 0 Delay 1ms SDA = 1 SCL = 1 SCL = 1
Delay 1ms SCL = 1 Delay 1ms SDA = 0 SDA = 1
SCL = 0 Delay 2ms SCL = 0 Delay 2ms Delay 2ms
Delay 1ms SCL = 0 SCL = 0 SCL = 1
Delay 1ms Delay 1ms Delay 1ms
C)

Afin d’afficher l’heure sur un afficheur à cristaux liquides, il faut initialiser le PCF8583
suivant la fonction voulut, lire les données puis convertir de BCD en ASCII et enfin les
afficher.
/**************************************************************************/
ALGORITHME
/**************************************************************************/

DEBUT

VARIABLES :

MSB1, LSB1
MSB2, LSB2
MSB3, LSB3
N

INITIALISATION :

Envoi du bit START //début de la transmission


Envoi de l’octet 0xA0 //Adresse de l’esclave PCF8583 et mode écriture
Lire réponse slave

Envoi de l’octet 0x04 //localisation sur l’emplacement mémoire


//(au niveau des heures)
Lire réponse slave

Envoi de l’octet 0x00 //initialisation des heurs


Lire réponse slave

LECTURE :

Envoi du bit START //re-lancement de la transmission


Envoi de l’octet 0xA1 //Adresse de l’esclave PCF8583 et mode lecture
Lire réponse slave

Envoi de l’octet 0x02 //localisation sur l’emplacement mémoire


//(au niveau des secondes)
Lire réponse slave

Réception de l’octet //lire les secondes


Charge l’octet dans MSB1 et LSB1 //enregistre la donnée avec masquage
Envoi ACK au slave //continuer la transmission (incrémentation sur la mémoire)

Réception de l’octet //lire les minutes


Charge l’octet dans MSB2 et LSB2 //enregistre la donnée avec masquage

Envoi ACK au slave //continuer la transmission (incrémentation sur la mémoire)


Réception de l’octet //lire l’heure
Charge l’octet dans MSB3 et LSB3 //enregistre la donnée avec masquage
Envoi NACK au slave //continuer la transmission (incrémentation sur la mémoire)

Envoi du bit STOP //fin de la transmission

CONVERSION :

Pour N de 1 à 3
Faire : (
Décalage vers la droite de MSBN
MSBN = MSBN + 0x30 //conversion ASCII
LSBN = MSBN + 0x30) //conversion ASCII

AFFICHAGE :

Afficher MSB1 LSB1 : MSB2 LSB2 : MSB3 LSB3

FIN

A noter que lors d’une écriture si, le slave répond par un NACK il faut répéter l’instruction
précédente.

/**************************************************************************/
PROGRAMME EN C
/**************************************************************************/

/***************************DECLARATION des SOUS PORG******************/


void start( );
void delay( );
unsigned char envoi envoi( );
unsigned char envoi recep( );
void ack( );
void nack( );
void stop( );

/*******************************INITIALISATION****************************/
main( )
{
start( ) ;
send(0xA0) ;
send(0x00); /*registre de contrôle*/
send(0x00); /*initialise le registre, fréquence de travail à 32KHz*/
send(0x04); /*registre des heures*/
send(0x00); /*initialise l’heure: en 24H, AM, 00h00*/
stop( ) ; /*libération de la liaison I2C*/
/*********************************VARIABLE*******************************/
while(1)
{

int S, MSBS, LSBS;


int M, MSBM, LSBM;
int H, MSBH, LSBH;

/****************************LECTURE DONNEE****************************/

start( ) ; /*début la liaison privé I2C*/


send(0xA0) ; /*adresse du PCF8583 en monde écriture*/
send(0x02); /*registre des secondes*/
start( ) ; /*re-lancement de la communication*/
send(0xA1); /*adresse du PCF8583 en monde lecture*/
S = recep( ); /*réception des données BCD des secondes*/
ACK( ); /* passage du registre des secondes aux minutes (0x03)*/
M = recep( ); /*réception des données BCD des minutes*/
ACK( ); /* passage du registre des minutes aux heures (0x04)*/
H = recep( ); /*réception des données BCD des heures*/
NACK( ); /*fin de la demande d’acquisition*/
STOP( ) /*liberation de la liaison I2C*/

/*****mise en place des poids forts (DIZAINES) et faibles (UNITES) des temps acquis****/

MSBS = S&F0; /*masquage des bits des 4 bits poids faibles*/


MSBS >>= 4; /*décalage des bits de poids forts aux bits de poids faibles*/
LSBS = S&0F; /*masquage des bits des 4 bits poids forts*/
MSBM = M&F0;
MSBM >>= 4;
MSBM = S&0F;
MSBH = H&F0;
MSBH >>= 4;
LSBH = H&0F;

/*******************CONVERTION ASCII & AFFICHAGE**********************/


affheure(MSBS + 0x30) ; /*(0x30 correspond à 0 en ASCII)*/
affheure(LSBS + 0x30) ; /*les fonction affheure seront réalisé suivant l’afficheur désiré*/
affheure(‘ :’) ;
affheure(MSBM + 0x30) ;
affheure(LSBM + 0x30) ;
affheure(‘ :’) ;
affheure(MSBH + 0x30) ;
affheure(LSBH + 0x30) ;
/*************************ATTENTE AUTRE ACQUISITION*******************/
/*temps d’attente entre 2 acquisition de donnée suivant la cadence de l’afficheur*/

/*****************************SOUS PROGRAMMES************************/

/**********************************DELAY*********************************/
void delay (void)
{
/*initialise pour une cadence d’environ 30µs (32khz) et plus*/
}

/***********************************START*********************************/
void start (void)
{
SCL = 1;
SDA = 1;
delay( );
SDA = 0;
delay( );
SCL = 0;
delay( );
}

/******************************ENVOI DONNEE*****************************/
unsigned char envoi (unsigned char donnee)
{
unsigned char mask = 0x80;
int n,a = 1;

while(a == 1)
{
pdX = 0xFF;
For (n=0 ; n<=7; n++)
{
if ((donnee&mask) == 0) SDA = 0;
else SDA = 1;
delay( );
SCL = 1;
delay( );
delay( );
SCL = 0;
delay( );
mask >>= 1;
}
pdX = 0xFE;
delay( ) ;
SCL = 1;
Delay( );
If (SDA = =0) a = 0;
Else a = 1;
Delay( );
SCL = 0;
Delay( );
}
pdX = 0xFF;
delay( );
}

/****************************RECEPTION DONNEE**************************/
unsigned char recep (void)
{
unsigned char donnee;
int n ;
pdX = 0xFE;
donnee = 0x00;
For (n=0 ; n<8 ; n++)
{
donnee <<= 0x01;
SCL = 1;
delay( );
if (SDA == 1) donnee = donnee + 0x01;
delay( );
SCL = 0;
delay( );
}
pdX = 0xFF;
SDA=0
delay( );
Return (donnee);
}

/************************************ACK**********************************/
void ack (void)
{
SCL = 0;
SDA = 0;
delay( );
SCL = 1;
SDA = 0;
delay( );
delay();
SCL = 0;
delay();
}

/***********************************NACK*********************************/
void nack (void)
{
SCL = 0;
SDA = 1;
delay( );
SCL = 1;
SDA = 1;
delay( );
delay( );
SCL = 1;
delay( );
}

/***********************************STOP**********************************/
void stop (void)
{
SCL = 1;
SDA = 0;
delay( );
SDA = 1;
delay( );
SCL = 0;
}
}