0
\$\begingroup\$

I'm trying to implement read and write routines using Polling method for a PIC18LF24K40, write seems to work, but not read. I cannot figure out what i am doing wrong.

EDIT: Reading a byte stored in a register on a slave chip:

   void read_LDC_reg(U8 *dest_addr)
   {
      U8 temp=0;   

      if( ( check_for_bus_free_iic() == 1) )   
      send_start();

      PIR3bits.SSP1IF=0;
      I2C_wait();  

      send_address(U8_LDC_I2C_ADDRESS,READ_BIT);

      send_start();
      SSP1CON2bits.RCEN1=1;

      while(SSP1STATbits.BF==0);
      temp=read_from_slave();

      PIR3bits.SSPIF = 0;

      dest_addr =  &temp;

      send_stop();

}

send_start() looks like this:

void send_start()
{
    while(SSP1STATbits.RW);          // wait for write to complete
    SSP1CON2bits.SEN=1;              //set start enable bit

    if(PIR3bits.BCLIF==1)
        PIR3bits.BCLIF =0;  //Clear collision bit in PIR register

    while(SSP1CON2bits.SEN);         //waits to get cleared by hardware 
}  

I2C_wait looks like this:

void I2C_wait(void)
{
    while( (SSP1STAT & 0x04) | (SSP1CON2 & 0x1F) );

    PIR3bits.BCL1IF=0;

}

send_address() looks like this:

void send_address(unsigned char addr,unsigned char ReadWrite_bit)
{
    unsigned char temp=0;
    temp = ( (addr <<1u ) | (ReadWrite_bit & (unsigned char)0x01) ); 
    write_to_bus(temp);


}

write_to_bus() looks like this:

void write_to_bus(unsigned char data)
{

    send_start();
    I2C_wait();

    send_byte(data);
    I2C_wait(); 

    send_stop();        
}

read_from_slave() looks like this:

unsigned char read_from_slave(void)
{  
    unsigned char rcvd_byte=0;   

    rcvd_byte = SSP1BUF;     
    return rcvd_byte;    
}

I am getting unexpected values from the slave register, i do not know why i believe i have initialised correctly, i can see the SCL and SDA waveforms on Oscilloscope.

EDIT: Hardware is fine, I2C works perfectly when i use the I2C Driver code generated from MCC(MPLAB Code Generator), i want to reduce the overhead caused by MCC in my project, thats the reason im going for I2C using Polling option.

\$\endgroup\$
0
\$\begingroup\$

Load test values in a dummy MCU and try simulating with the Proteus design suite, but i agree with Buhra with checking the flag for successful reception from the slave, and if possible check necessary flags that indicate a free buffer and transmission-ready state.

\$\endgroup\$
-1
\$\begingroup\$
unsigned char read_from_slave(void)
{  
    unsigned char rcvd_byte=0;   
   <----------- Check Flag ------------>
    rcvd_byte = SSP1BUF;     
    return rcvd_byte;    
}

In this function you are not check any flag for successfull reception from slave,Check datasheet again

\$\endgroup\$
  • \$\begingroup\$ I have not enabled ACKEN bit so I'm not sure if i need to check if ACKDT bit is set on Receive. Probably i have to set ACKEN \$\endgroup\$ – Abel Tom Oct 24 '17 at 6:03
  • \$\begingroup\$ what do you mean by I have not enabled ACKEN bit . Check previous reception is complete or not using flag,there is no matter of ACK. \$\endgroup\$ – Bhura Oct 24 '17 at 6:41
  • \$\begingroup\$ I modified the read from register routine, i check if the buffer is now full, but i receive 0xFF for some reason, always. \$\endgroup\$ – Abel Tom Oct 24 '17 at 6:50
  • \$\begingroup\$ ReCheck your connections, I2C Master SDA -> Slave SDA and SCK -> SCK with pull ups 1K'oms -> 4.7k'oms and what freq you are using for I2C communication can you provied whole code. \$\endgroup\$ – Bhura Oct 24 '17 at 7:08
  • \$\begingroup\$ Pullups are around 2.2K, Clock frequency is set to 100KHz. Hardware is fine, I2C works perfectly when i use the I2C Driver code generated from MCC(MPLAB Code Generator), i want to reduce the overhead in my project, thats the reason im going for I2C using Polling option. \$\endgroup\$ – Abel Tom Oct 24 '17 at 7:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.