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;
}