Bonjour,
Je suis nouveau sur le forum, je suis étudiant à Polytech Marseille j'en suis à BAC+4, j'étudie principalement l'électronique et les télécommunications.
J'essaire depuis plusieurs jours de récupérer via mon pic16f1825 les données mesurées par le magnétomètre de chez freescale : MAG3110. La communication entre les deux composants se fait via le protocole I2C. J'ai paramétré mon pic puis j'essaie de paramétré les registres de mon magnétomètre via la comm. I2c, puis pour vérifier que cela marche, lorsque j'essaie de lire les deux registres de configuration du magnétomètre, IMPOSSIBLE. Je reçois soit 0000000 soit 11111111.... Je ne comprend pas d'où vient le problème !!
J'utilise MPLABX un debogueur ICD3 et le DEV KIT ADC244043 pour simuler le pic 16F1825. Mon magnétomètre est branché sur le LFSTBEB3110 sensor board.
Merci pour votre aide,
Mon code est le suivant :
Code:#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <stdint.h> #include <xc.h> #include "fonctions.h" #include "pic16f1825.h" #define _XTAL_FREQ 8000000 #ifndef CONFIG_BITS_H #define CONFIG_BITS_H // CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT enabled) #pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) #pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled) #pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) #endif /* CONFIG_BITS_H */ #define CTRL_REG1 0x10 #define CTRL_REG2 0x11 #define INIT_REG1 0b01100001 #define INIT_REG2 0b10000000 int8_t x_mesure; int8_t y_mesure; int8_t z_mesure; int main(int argc, char** argv) { //-----------------------------Variable locale---------------------------------- uint8_t x_flag; uint8_t y_flag; uint8_t z_flag; uint8_t reg1=0; uint8_t reg2=0; //********************************************************************* //-------------------------Initialisation-PIC-------------------------- OPTION_REGbits.nWPUEN =0b0 ; //Weak pull-ups are enabled by individual WPUx latch values OPTION_REGbits.TMR0CS =0b0 ; //Internal instruction cycle clock (FOSC/4) OPTION_REGbits.INTEDG =0b0 ; //Interrupt on rising edge of RB0/INT pin PCON = 0b00000000; //Flags à 0 //--------------------------INTERRUPTIONS----------------------------- INTCONbits.TMR0IF =0b0; //TMR0 register did not overflow INTCONbits.TMR0IE =0b0; //Disables the Timer0 interrupt INTCONbits.INTE =0b0; //Enables the INT external interrupt INTCONbits.INTF =0b0; //The INT external interrupt did not occur INTCONbits.IOCIE =0b0; //Enables the interrupt-on-change INTCONbits.IOCIF =0b0; //None of the interrupt-on-change pins have changed state INTCONbits.PEIE =0b0; //Enables all active peripheral interrupts PIE1bits.SSP1IE =0b1; //Enables the MSSP interrupt PIE2bits.BCL1IE =0b1; //Enables the MSSP Bus Collision Interrupt PIR1 = 0b00000000; // Initiate low every interrupts flag PIR2 = 0b00000000; // Initiate low every interrupts flag PIR3 = 0b00000000; // Initiate low every interrupts flag INTCONbits.GIE = 0b1; //Enables all active interrupts //------------------------OSCILLATEUR------------------------------- OSCCONbits.IRCF = 0b1110; //Frequence d'oscylateur à 8Mhz OSCCONbits.SCS = 0b10; // INT. OSC. OSCCONbits.SPLLEN = 0b0; // PLL disabled //-------------------------I/O---------------------------------- ANSELA=0b00000000; // TOUTE LES IO en DIGITAL ANSELC=0b00000000; // TOUTE LES IO en DIGITAL WPUA=0b00000000; // PAS de PULL-UP sur le PORT A WPUC=0b00000011; // PAS de PULL-UP sur le PORT C excepté pour SCA et SCL qui sont sur RC0 et RC1 LATA = 0b00000000; // Initialisation des registres port A à 0 LATC = 0b00000011; // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1 PORTA =0b00000000; // Initialisation des registres port A à 0 PORTC =0b00000011; // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1 TRISCbits.TRISC5 = INPUT; // RX Input TRISCbits.TRISC4 = OUTPUT; // TX Output TRISCbits.TRISC0 = INPUT; // SCL Input (CF datasheet) TRISCbits.TRISC1 = INPUT; // SDA Input (CF datasheet) //------------------------BAUD RATE------------------------------- BAUDCONbits.SCKP=0b1; // Niveau 0 sur CLK au repos (Transmit non-inverted data to the TX/CK pin) BAUDCONbits.BRG16=0b0; // 8 bits baud rate generator BAUDCONbits.WUE=0b0; // Normal mode //------------------------------I2C----------------------------------- SSP1STATbits.SMP =0b0 ; //Slew rate control disabled for standard speed mode (100 kHz and 1 MHz) SSP1STATbits.CKE= 0b1; //Enable input logic so that thresholds are compliant with SMbus specification SSP1CON1bits.SSPEN=0b1; // Enables the serial port and configures the SDAx and SCLx pins as the source of the serial port pins( SSP1CON1bits.SSPM = 0b1000; //I2C Master mode, clock = FOSC / (4 * (SSPxADD+1)) SSP1CON2 =0x80; SSP1CON3bits.SDAHT =0b1; //Minimum of 300 ns hold time on SDAx after the falling edge of SCLx (100ns if = 0) SSP1CON3bits.PCIE =0b1; // Enable interrupt on detection of Start or Restart conditions SSP1CON3bits.SCIE =0b1; // Enable interrupt on detection of Stop conditions SSP1CON3bits.SBCDE =0b1; // Eable interupt on detection of bu collision SSP1BUF = 0b00000000; // I2C buffer initialized TXSTAbits.CSRC =0b1; // Master mode (clock generated internally from BRG) TXSTAbits.TX9 =0b0; // Selects 8-bit transmission RCSTAbits.SPEN =0b0; // Serial port disabled (held in Reset) SSP1ADD = 0b00010011; // set Baud rate clock divider // ************************************************************************************** // The SSPADD register value is used to determine the clock rate for I2C communication. // Equation for I2C clock rate: Fclock = Fosc/[(SSPADD +1)*4] // For this example we want the the standard 100Khz I2C clock rate and our // internal Fosc is 8Mhz so we get: 100000 = 8000000/[(SSPADD+1)*4] // or solving for SSPADD = [(8000000/100000)-4]/4 // and we get SSPADD = 19 //***************************************************************************** //-----------------------------Initialisation-MAG------------------------------ I2C_StartBit(); // send start bit I2C_ControlByte_Sending(); // send control byte with writing option Select_Register (CTRL_REG1); // Select the right register Send_I2C_Data(INIT_REG1); // send data byte I2C_StopBit(); // send stop bit Wait_Idle (); I2C_StartBit(); // send start bit I2C_ControlByte_Sending(); // send control byte with writing option Select_Register (CTRL_REG2); // Select the right register Send_I2C_Data(INIT_REG2); // send data byte I2C_StopBit(); // send stop bit Wait_Idle (); //********************************************************* //-----------------------------PROGRAMME------------------------------ Wait(3); I2C_StartBit(); // send start bit I2C_ControlByte_Sending(); // send control byte with writing option Select_Register (CTRL_REG1); // Select the right register I2C_RestartBit(); // Restart I2C_ControlByte_Reading(); // Send control byte with reading option reg1 = Read_I2C_Data(); // Lecture de reg1 Send_I2C_NAK(); // Send NAK I2C_StopBit(); // Send stop bit Wait_Idle (); I2C_StartBit(); // send start bit I2C_ControlByte_Sending(); // send control byte with writing option Select_Register (CTRL_REG2); // Select the right register I2C_RestartBit(); // Restart I2C_ControlByte_Reading(); // Send control byte with reading option reg2 = Read_I2C_Data(); // Lecture de reg1 Send_I2C_NAK(); // Send NAK I2C_StopBit(); // Send stop bit } void Wait (uint16_t i) { uint8_t j=0; while (i!=0) { for (j=0; j<255; j++){ } i--; } } void I2C_StartBit(void) { PIR1bits.SSP1IF=0; // Set low the I2C Flag SSP1CON2bits.SEN=0b1; // send start bit while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } void I2C_RestartBit (void) { PIR1bits.SSP1IF =0; // Clear the I2C Flag SSP1CON2bits.RSEN=0b1; // send start bit while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } void I2C_StopBit(void) { PIR1bits.SSP1IF =0; // Clear the I2C Flag SSP1CON2bits.PEN=0b1; // send stop bit while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } void I2C_ControlByte_Sending(void) { do{ SSPCON1bits.WCOL =0; // Clear bus collision flag SSP1BUF = 0b00011100; // send the control byte WITH SLAVE ADRESS & R_nW } while (SSPCON1bits.WCOL); // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } void I2C_ControlByte_Reading(void) { do{ SSPCON1bits.WCOL =0; // Clear bus collision flag SSP1BUF = 0b00011101; // send the control byte WITH SLAVE ADRESS & R_nW } while (SSPCON1bits.WCOL); // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } void Select_Register (uint8_t RegisterAdress) { do{ SSPCON1bits.WCOL =0; // Clear bus collision flag SSP1BUF = RegisterAdress; // send the control byte WITH register adress } while (SSPCON1bits.WCOL); // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } void Send_I2C_Data(uint8_t DataByte) { do{ SSPCON1bits.WCOL =0; // Clear bus collision flag SSP1BUF = DataByte; // send the control byte WITH register adress } while (SSPCON1bits.WCOL); // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION while(!PIR1bits.SSP1IF); // Wait for the SSPIF bit to go back high before we load the data buffer PIR1bits.SSP1IF =0; // Clear the I2C Flag } uint8_t Read_I2C_Data(void) { PIR1bits.SSP1IF=0b0; // clear SSP interrupt bit SSP1CON2bits.RCEN=0b1; // set the receive enable bit to initiate a read of 8 bits from the serial eeprom while (!PIR1bits.SSP1IF); while (SSP1STATbits.BF); return (SSP1BUF); // Data from eeprom is now in the SSPBUF so return that value } void Send_I2C_ACK(void) { PIR1bits.SSP1IF=0b0; // clear SSP interrupt bit SSP1CON2bits.ACKDT=0b0; // clear the Acknowledge Data Bit - this means we are sending an Acknowledge or 'ACK' SSP1CON2bits.ACKEN=0b1; // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom while(SSP1CON2bits.ACKEN); // Wait for interrupt flag to go high indicating transmission is complete } void Send_I2C_NAK(void) { PIR1bits.SSP1IF=0b0; // clear SSP interrupt bit SSP1CON2bits.ACKDT=0b1; // set the Acknowledge Data Bit- this means we are sending a No-Ack or 'NAK' SSP1CON2bits.ACKEN=0b1; // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom while(SSP1CON2bits.ACKEN); // Wait for interrupt flag to go high indicating transmission is complete } void Wait_Idle (void) { while ((SSPCON2 & 0x1F) | (SSPSTATbits.R_nW)); // Wait for idle }
-----