Je suis en train d'essayer de faire marcher l'I2C sur un pic18F452, le problème c'est que mon programme semble être bloqué dans ma fonction Init_boussole.
J'ai aussi regardé à l'oscilloscope et apparemment je n'ai pas de signal sortant de la pin SCL, il ne doit pas en avoir une par hasard
Voici mon programme:
main:
Code : Tout sélectionner
#include <p18f452.h>
#include "fonctions.h"
#include "PWM_fonc.h"
#pragma config OSC = HS, OSCS = OFF
#pragma config PWRT = OFF, BOR = OFF
#pragma config WDT = OFF
#pragma config CCP2MUX = ON
#pragma config STVR = ON
#pragma config LVP = OFF
#pragma config DEBUG = ON
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTRB = OFF
void main(void)
{
unsigned char vision;
char vitesse_droit;
char vitesse_gauche;
float position;
LATB = 0x0f; // allumer 4 bits faibles sur PORTB
TRISB = 0xF0; // 4 bits faibles PORTB en sortie
Init_ADC();
Init_PWM();
Init_I2C();
Init_boussole();
vitesse_droit = 0xFF;
vitesse_gauche = 0xFF;
MOT_G_Avant();
MOT_D_Avant();
while(1)
{
position = Gest_Bouss();
if (position > 50)
{
vitesse_gauche=0x10;
vitesse_droit=0x10;
}
/*ADCON0=0b01000001; //MILIEU
vision = conversion();
if (vision >= 20)
{
vitesse_gauche=0x00;
vitesse_droit=0x00;
}
else
{
vitesse_gauche=0x80;
vitesse_droit=0x80;
}
ADCON0=0b01001001; //COTE DROIT
vision = conversion();
if (vision >= 20)
{
vitesse_gauche=0x00;
}
else
{
vitesse_gauche=0x80;
vitesse_droit=0x80;
}
ADCON0=0b01010001; //COTE GAUCHE
vision = conversion();
if (vision >= 20)
{
vitesse_droit=0x00;
}
else
{
vitesse_gauche=0x80;
vitesse_droit=0x80;
}
*/
VITESSE_MOT_G=vitesse_gauche;
VITESSE_MOT_D=vitesse_droit;
}
return;
}
I2C:
Code : Tout sélectionner
#include <p18f452.h>
#include <math.h>
#include <delays.h>
#include "fonctions.h"
#include "PWM_fonc.h"
void Init_I2C(void)
{
TRISCbits.TRISC4 = 1; // data direction SDA
TRISCbits.TRISC3 = 1; // data direction SCL
SSPCON1=0x28; // no collision,0, SSPEN Enable I2C, 0, I2C master, I2C master clock=Fosc/(4*SSPADD+1)
SSPSTATbits.SMP=1; // pas de slew rate control (standard speed mode)
SSPADD=0x05; // 166Khz
return;
}
void Init_boussole(void) //mesure en continue
{
SSPCON2bits.SEN = 1; //start
while (SSPCON2bits.SEN==1); // attente raz en fin du start
SSPBUF=0x3C; // envoie adresse du chip HMC5883 en write
while (SSPCON2 & 0x1F) ; // attente bus IDLE (5 bits faibles à 0)
while (SSPSTATbits.R_W ==1) ; // attente fin d'envoi
while (SSPCON2bits.ACKSTAT == 1); // attente ACK recu
SSPBUF=0x02; // envoie octet 02 en write pour acces au registre de mode
while (SSPCON2 & 0x1F) ; // attente bus IDLE (5 bits faibles à 0)
while (SSPSTATbits.R_W ==1) ; // attente fin d'envoi
while (SSPCON2bits.ACKSTAT == 1); // attente ACK recu
SSPBUF=0x00; // envoie octet 00 en write dans registre de mode pour mesure en continu
while (SSPCON2 & 0x1F) ; // attente bus IDLE (5 bits faibles à 0)
while (SSPSTATbits.R_W ==1) ; // attente fin d'envoi
while (SSPCON2bits.ACKSTAT == 1); // attente ACK recu
SSPCON2bits.PEN=1; // envoi du stop
while (SSPCON2bits.PEN == 1); // attente fin du stop
Delay1KTCYx(50); // delay = 5mS
return;
}
float Gest_Bouss(void)
{
// gestion boussole HMC5883
// écriture octet de commande et lecture de la réponse :(voir DATA SHEET "READ BYTE FORMAT")
int X,Y,Z,x,y,z = 0; // raz variables recues
char x1=X ; // On place les 8 MSBs de x
char y1=Y ; // On place les 8 MSBs de x
float teta;
SSPCON2bits.SEN=1; // start
while (SSPCON2bits.SEN==1); // attente raz en fin du start
SSPBUF=0x3C; // envoie adresse du chip HMC5883 en write
while (SSPCON2 & 0x1F) ; // attente bus IDLE (5 bits faibles à 0)
while (SSPSTATbits.R_W ==1) ; // attente fin d'envoi
while (SSPCON2bits.ACKSTAT == 1); // attente ACK recu
SSPBUF=0x03; // envoie octet 03 en write pour acces au registre X
while (SSPCON2 & 0x1F) ; // attente bus IDLE (5 bits faibles à 0)
while (SSPSTATbits.R_W ==1) ; // attente fin d'envoi
while (SSPCON2bits.ACKSTAT == 1); // attente ACK recu
SSPCON2bits.PEN=1; // envoi du stop
while (SSPCON2bits.PEN == 1); // attente fin du stop
SSPCON2bits.SEN=1; // start
while (SSPCON2bits.SEN==1); // attente raz en fin du start
SSPBUF=0x3D; // envoie adresse du chip HMC5883 en read
while (SSPCON2 & 0x1F) ; // attente bus IDLE (5 bits faibles à 0)
while (SSPSTATbits.R_W ==1) ; // attente fin d'envoi
while (SSPCON2bits.ACKSTAT == 1); // attente ACK recu
SSPCON2bits.RCEN=1; // passe en mode réception
while (SSPCON2bits.RCEN == 1); // attente octet de réception
X=SSPBUF; // récup caractère reçu
SSPCON2bits.ACKDT=0; // positionne ACK
SSPCON2bits.ACKEN=1; // envoi
while (SSPCON2bits.ACKEN == 1); // attente fin du ACK
SSPCON2bits.RCEN=1; // passe en mode réception
while (SSPCON2bits.RCEN == 1); // attente octet de réception
x=SSPBUF; // récup caractère reçu
SSPCON2bits.ACKDT=0; // positionne ACK
SSPCON2bits.ACKEN=1; // envoi
while (SSPCON2bits.ACKEN == 1); // attente fin du ACK
SSPCON2bits.RCEN=1; // passe en mode réception
while (SSPCON2bits.RCEN == 1); // attente octet de réception
Z=SSPBUF; // récup caractère reçu
SSPCON2bits.ACKDT=0; // positionne ACK
SSPCON2bits.ACKEN=1; // envoi
while (SSPCON2bits.ACKEN == 1); // attente fin du ACK
SSPCON2bits.RCEN=1; // passe en mode réception
while (SSPCON2bits.RCEN == 1); // attente octet de réception
z=SSPBUF; // récup caractère reçu
SSPCON2bits.ACKDT=0; // positionne ACK
SSPCON2bits.ACKEN=1; // envoi
while (SSPCON2bits.ACKEN == 1); // attente fin du ACK
SSPCON2bits.RCEN=1; // passe en mode réception
while (SSPCON2bits.RCEN == 1); // attente octet de réception
Y=SSPBUF; // récup caractère reçu
SSPCON2bits.ACKDT=0; // positionne ACK
SSPCON2bits.ACKEN=1; // envoi
while (SSPCON2bits.ACKEN == 1); // attente fin du ACK
SSPCON2bits.RCEN=1; // passe en mode réception
while (SSPCON2bits.RCEN == 1); // attente octet de réception
y=SSPBUF; // récup caractère reçu
SSPCON2bits.ACKDT=1; // positionne NACK Non ACK pour le dernier octet lu !!!!
SSPCON2bits.ACKEN=1; // envoi
while (SSPCON2bits.ACKEN == 1); // attente fin du NACK
SSPCON2bits.PEN=1; // envoi du stop
while (SSPCON2bits.PEN == 1); // attente fin du stop
// concaténation
x1=x1 << 8;
x1=x1 | x;//On place les 8 LSBs de x
y1=y1<<8;
y1=y1 | y;//On place les 8 LSBs de x
// calcul angle
teta = ((-atan2(y1,x1)*180)/3.14159265359)+180; //angle par rapport au nord
Delay10KTCYx(30); // delay = 30 * 10 000 cycles temps de visu des caracteres
return teta;
}
Merci d'avance pour votre aide :)


