Communication I2C avec avr-gcc :
#include <avr/io.h>
#define         ERROR   0
#define         SUCCESS 1
#define         IIC_START       0x08
#define         IIC_RESTART     0x10
#define         IIC_WADDR_ACK   0x18
#define         IIC_WDATA_ACK   0x28
#define         IIC_RADDR_ACK   0x40
#define         IIC_RDATA_ACK   0x50
#define         IIC_RDATA_NACK  0x58
#define         SCL_CLOCK       400000L // En Hertz
void i2c_init(void){
TWSR=0;                          // Pas de multiplicateur d'horloge
TWBR=((F_CPU/SCL_CLOCK)-16)/2;   // Fréquence de l'horloge i2c
TWCR=(1<<TWEN);                  // Activation de l'i2c matériel
}
static void i2c_start(void){     // Envoi d'un start
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR & (1<<TWINT))==0);   // Attente de fin d'envoi
}
static void i2c_stop(void){      // Envoi d'un stop
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
static uint8_t i2c_statut(void){ // Etat de la dernière transmission
return (TWSR & 0xF8);
}
void i2c_ecrire(uint8_t octet){  // Envoi d'un octet sur le bus i2c
TWDR=octet;                      // Ecriture de l'octet à envoyer
TWCR=(1<<TWINT)|(1<<TWEN);
while((TWCR & (1<<TWINT))==0);   // Attente de fin d'envoi
}
uint8_t i2c_lire_ack(void){      // Lecture d'un octet sur i2c avec accusé positif
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while((TWCR & (1<<TWINT))==0);
return TWDR;
}
uint8_t i2c_lire_nack(void){     // Lecture d'un octet sur i2c avec accusé négatif
TWCR=(1<<TWINT)|(1<<TWEN);
while((TWCR & (1<<TWINT))==0);
return TWDR;
}
uint8_t i2c_ecrire_registre(uint8_t adr_i2c,uint8_t reg_val,unsigned char stop){
                                 // Modification de la valeur d'un registre
int statut;
i2c_start();
statut=i2c_statut(); if(status!=IIC_START && status!=IIC_RESTART) return ERROR;
i2c_ecrire(adr_i2c<<1);
statut=i2c_statut(); if(status!=IIC_WADDR_ACK) return ERROR;
i2c_ecrire(reg_val);
statut=i2c_statut(); if(status!=IIC_WDATA_ACK) return ERROR;
if(stop) i2c_stop();
return SUCCESS;
}
uint8_t i2c_ecrire_donnee(uint8_t adr_i2c,uint8_t adresse,uint8_t donnee){
                                 // Ecriture dans la mémoire de l'esclave
int statut;
i2c_start();
statut=i2c_statut(); if(status!=IIC_START && status!=IIC_RESTART) return ERROR;
i2c_ecrire(adr_i2c<<1);
statut=i2c_statut(); if(status!=IIC_WADDR_ACK) return ERROR;
i2c_ecrire(reg_val);
statut=i2c_statut(); if(status!=IIC_WDATA_ACK) return ERROR;
i2c_ecrire(donnee);
statut=i2c_statut(); if(status!=IIC_WDATA_ACK) return ERROR;
TWI_stop();
return SUCCESS;
}
#define MATRICE_REG_LUMINE      0xE0
#define MATRICE_SYSTEME         0x20
#define MATRICE_AFFICHAGE       0x80
#define MATRICE_ADR_I2C         0x70
int matrice_afficher(uint8_t image[8]){
int dim=0x01;                   // Ecriture de quelques registres de la matrice
i2c_ecrire_registre(MATRICE_ADR_I2C,MATRICE_SYSTEME|1,1);
i2c_ecrire_registre(MATRICE_ADR_I2C,MATRICE_REG_LUMINE|dim,1);
i2c_ecrire_registre(MATRICE_ADR_I2C,MATRICE_AFFICHAGE|1,1);
int i;                          // Envoi de chaque ligne
for(i=0;i<8;i++) i2c_ecrire_donnee(MATRICE_ADR_I2C,2*i,image[i]);
return 0;
}