C'est la première fois que je tente de créé une communication I2C. Je me suis inspiré des codes d'exemple que j'ai trouvé sur internet et que j'ai adaptés un peu à mon projet, et forcement ça ne marche pas du premier coup.
J'utilise un PIC18LF2620, et je veux le faire communiquer avec un capteur de type MS5837-02BA21
Voilà tout mon code :
Code : Tout sélectionner
#include <XC.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#pragma config OSC = ECIO6
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config BOREN = OFF
#pragma config MCLRE = OFF
#pragma config PBADEN = OFF
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config STVREN = OFF
#define _XTAL_FREQ 8000000
#define slave_write_address 0b11101100
#define slave_read_address 0b11101101
#define LED PORTCbits.RC5
unsigned short C1=0, C2=0, C3=0, C4=0, C5=0, C6=0 ; // 16 Bits
__uint24 D1=0, D2=0 ; // 24 Bits
signed int dT=0, TEMP=0 ; // 32 Bits , Utiliser var_inter64
signed long long OFF=0, SENS=0, var_inter64=0 ; // 64 Bits
unsigned int P=0 ; // 32 Bits , Utiliser var_inter64
signed int OFFi=0 ;
signed long long Ti=0, SENSi=0, OFF2=0, SENS2=0 ; // 64 Bits
signed short TEMP2=0 ; // 16 Bits , Utiliser var_inter64
__uint24 P2=0 ; // 24 Bits , Utiliser var_inter64
//### FONCTIONS déclarations :
void I2C_Start(char) ;
void I2C_Ready(void) ;
char I2C_Write(unsigned char) ;
void I2C_Stop(void) ;
char I2C_Read(char) ;
void write_MS5837(unsigned char) ;
__uint24 read_MS5837(unsigned char, unsigned char) ;
int main(int argc, char** argv)
{
TRISA = 0b10000000 ;
TRISB = 0b00111100 ;
TRISC = 0b00011000 ;
PORTA = 0b00000000 ;
PORTB = 0b00000000 ;
PORTC = 0b00000000 ;
ADCON1 = 0b00001111 ;
INTCON2bits.RBPU = 0 ;
//////// I2C :
SSPSTATbits.SMP = 1 ; // 1=Slew rate control disabled
SSPSTAT=0b10000000 ; // Slew rate disabled, other bits are cleared
SSPCON1=0b00101000 ; // Enable SSP port for I2C Master mode
SSPCON2 = 0b00000000 ;
SSPADD = 0b00010011 ; // 19 = 100kHz , CLK = FOSC/(4*(SSPADD+1
PIE1bits.SSPIE = 1 ; // Enable SSPIF interrupt
PIR1bits.SSPIF = 0 ;
//### INITIALISATIONS :
LED = 0 ;
write_MS5837(0x1E) ; // RESET
C1 = read_MS5837(0b10100010, 2) ; // C1
C2 = read_MS5837(0b10100100, 2) ; // C2
C3 = read_MS5837(0b10100110, 2) ; // C3
C4 = read_MS5837(0b10101000, 2) ; // C4
C5 = read_MS5837(0b10101010, 2) ; // C5
C6 = read_MS5837(0b10101100, 2) ; // C6
D1 = read_MS5837(0x4A, 3) ; // D1, OSR=8192
D2 = read_MS5837(0x5A, 3) ; // D2, OSR=8192
return (EXIT_SUCCESS);
}
//####################################
void I2C_Start(char wr)
{
SSPCON2bits.SEN = 1 ; // Send start pulse
while(SSPCON2bits.SEN) ; // Wait for completion of start pulse
PIR1bits.SSPIF = 0 ;
if(wr==0) I2C_Write(slave_write_address) ; // Write slave device address with write=0 to communicate
else I2C_Write(slave_read_address) ; // Read slave device address with read=1 to communicate
}
void I2C_Ready(void)
{
while(!PIR1bits.SSPIF) ; // Wait for operation complete
PIR1bits.SSPIF = 0 ; // Clear SSPIF interrupt flag
}
char I2C_Write(unsigned char data)
{
I2C_Ready() ;
SSPBUF = data ; // Write data to SSPBUF
I2C_Ready() ;
if(SSPCON2bits.ACKSTAT) return 1 ; // Check for acknowledge bit
else return 2 ;
}
void I2C_Stop(void)
{
I2C_Ready() ;
SSPCON2bits.PEN = 1 ; // Stop communication
while(SSPCON2bits.PEN) ; // Wait for end of stop pulse
PIR1bits.SSPIF = 0 ;
// if(!SSPSTATbits.P) return 0 ; // Check whether STOP is detected last. If not return 0 to indicate start failed
}
char I2C_Read(char flag)
{
char buffer = 0 ;
SSPCON2bits.RCEN = 1 ; // Enable receive
while(!SSPSTATbits.BF) ; // Wait for buffer full flag which when complete byte received
buffer = SSPBUF ; // Copy SSPBUF to buffer
if(flag==0)
{
SSPCON2bits.ACKDT = 0 ; // Acknowledge data 1:NACK,0:ACK // Send acknowledgment or negative acknowledgment after read to continue or stop reading
SSPCON2bits.ACKEN = 1 ; // Enable ACK to send
while(SSPCON2bits.ACKEN) ;
}
else
{
SSPCON2bits.ACKDT = 1 ; // Acknowledge data 1:NACK,0:ACK
SSPCON2bits.ACKEN = 1 ; // Enable ACK to send
while(SSPCON2bits.ACKEN) ;
}
I2C_Ready() ;
return(buffer) ;
}
//####################################
void write_MS5837(unsigned char dat)
{
I2C_Start(0) ;
I2C_Write(dat) ;
I2C_Stop() ;
}
__uint24 read_MS5837(unsigned char add, unsigned char seize)
{
__uint24 dat=0, dat24 = 0 ;
I2C_Start(0) ;
write_MS5837(add) ;
I2C_Start(1) ;
if(seize==2) // READ C1-6
{
dat = I2C_Read(0) ;
dat24 = dat<<8 ;
dat = I2C_Read(1) ;
dat24 = dat24 | dat ;
}
else if(seize==3) // READ Pression/Température
{
write_MS5837(0x00) ; // ADC READ
__delay_ms(20) ; // Conversion time
dat = I2C_Read(0) ;
dat24 = dat<<16 ;
dat = I2C_Read(0) ;
dat24 = dat24 | (dat<<8) ;
dat = I2C_Read(1) ;
dat24 = dat24 | dat ;
}
I2C_Stop() ;
return dat24 ;
}Pour l'instant tout ce que j'ai testé c'est rajouter un LED = 1 ; à différents endroits du code pour voir si ça bloque quelque part, et effectivement ça bloque dans I2C_Ready au niveau de while(!PIR1bits.SSPIF) ; mais je ne vois pas pourquoi...


