Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

18F46K22 MSSP I2C Issue

Status
Not open for further replies.

Jon Wilder

Active Member
Hi all.

When using the MSSP module as I2C master, I always send the start, restart, ack/nack, and stop bits by setting the appropriate control bit in SSPCON2, then polling the control bit to wait for the completion of the start,restart,ack/nack, and stop bits. Each time the cycle completes, my code then clears the SSPIF flag in PIR1.

However, when sending data, I write data to SSPBUF, then poll the SSPIF flag in register PIR1.

Sending the start,restart,ack/nack, and stop works perfectly fine so I know the hardware is working and initialized properly. However, when writing data to SSPBUF, the SSPIF flag never sets, hence my code hangs forever since the flag never gets set. I am not using interrupts.

The I2C slave component is a 24LC64 EEPROM chip, which I've worked with many times in the past without issue (even using the SSPIF polling routine when sending data) with 470R pull up resistors on the SCL/SDA bus. The chip is interfaced with MSSP1 on pins RC3 and RC4.

What could be causing this issue?

Code:
void sendI2C(uint8_t data){
    while(SSPCON2 & 0b01011111);   // wait for idle state
    SSPBUF = data;                 // send data
    while(!PIR1bits.SSPIF);        // wait for send to complete
    PIR1bits.SSPIF = 0;            // clear SSPIF
}

void initI2C(void){
    SSPSTATbits.SMP = 1;          // disable slew rate control
    SSPADD = 0x9F;                // 100kHz bit rate (Fosc = 64MHz)
    ANSELC &= 0b11100111;         // RC3-RC4 digital I/O mode
    TRISC |= 0b00011000;          // RC3-RC4 open drain for SCL/SDA
    SSPCON1 = 0b00101000;         // enable MSSP1, I2C master mode
    while(SSPCON2 & 0b01011111);  // wait for idle state
}

/*
* The following code works with no issues - example of how control bits are handled
*/
void sendStartBit(void){
    while(SSPCON2 & 0b01011111);   // wait for idle state
    SSPCON2bits.SEN = 1;           // send start bit
    while(SSPCON2bits.SEN);        // wait for send to complete (SEN cleared by hardware)
    PIR1bits.SSPIF = 0;            // clear SSPIF
}
 
Last edited:
470R pull up resistors
I would not go that low R 2k2 +- would be better.not done I2C with PIC18 , These are my PIC24 EE functions

Code:
char EE_read(unsigned int location)
{
    char ee_loc_byte_low = (location & 0x00FF);
    char ee_loc_byte_hi = location >> 8 ;
   
    char EEdata = 0;
        I2C_start_W(EE_addr);
        I2C_sendB(ee_loc_byte_hi );
        I2C_sendB(ee_loc_byte_low );
        I2C_restart_R(EE_addr);
        I2C1CONbits.RCEN = 1;
        while (!I2C1STATbits.RBF);
        EEdata = I2C1RCV;
        I2CNak();
        I2C_endtx();
        I2C1CONbits.RCEN = 0;
        return EEdata ;  
}
void EE_write(unsigned int ee_location, char ee_data)
{
    char ee_loc_byte_low = (ee_location & 0x00FF);
    char ee_loc_byte_hi = ee_location >> 8 ;

         I2C_start_W(EE_addr);
         I2C_sendB(ee_loc_byte_hi);
         I2C_sendB(ee_loc_byte_low);
         I2C_sendB(ee_data);
         I2C_endtx();
         DLYm(5);  /// write cycle time
}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top