firoz3321
Newbie level 5
- Joined
- Oct 3, 2008
- Messages
- 9
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,350
Hi ,
I am very new to PIC controllers.
I am using PIC18LF43k22 controller, and i have configured the I2C as SMBus.
I having issue reading 16 Bit data from the slave.
Kindly help me.
ISSUE:
I am able to write BYTE and write WORD (2 bytes) to the Slave, But i am not able to READ from the slave. I am sure i am doing it wrong, but i cant understand which part am i missing.
I am either getting both LOWer Byte and Higher Byte same
example :
Expected 16 bit data is : 0X0002
I am recieving :
Data_Low : 0x02
Data_High : 0x02
Data : 0x0202
I followed this protocol :
I am pasting my Read routines Below:
--------------------------------------------------------------------------
2. One more query i have is :
Which of the following 2 codes are right ?
or
Second one ( while (PIR1bits.SSPIF != 1); ) is working for me, but all the example codes i have see seem to be using the first part.
I am very new to PIC controllers.
I am using PIC18LF43k22 controller, and i have configured the I2C as SMBus.
I having issue reading 16 Bit data from the slave.
Kindly help me.
ISSUE:
I am able to write BYTE and write WORD (2 bytes) to the Slave, But i am not able to READ from the slave. I am sure i am doing it wrong, but i cant understand which part am i missing.
I am either getting both LOWer Byte and Higher Byte same
example :
Expected 16 bit data is : 0X0002
I am recieving :
Data_Low : 0x02
Data_High : 0x02
Data : 0x0202
I followed this protocol :
I am pasting my Read routines Below:
Code:
void I2C1_init(void) // init I2C1 as master
{
TRISCbits.TRISC3 = 1; // LT4100 SCK, Smart battery SCK
TRISCbits.TRISC4 = 1; // LT4100 SDA, Smart battery SDA
PIE1bits.SSP1IE = 1;
SSPCON1 = 0x28; //enable serial port and configure SDA and SCL
SSP1STATbits.SMP = 0; //slew rate disable and configered to input level to I2C (< 100k)
SSP1STATbits.CKE = 1; // Enable input logic thresholds to SMBus compatable
SSPADD = 39; // baud rate fixed to 50kHz with 8 MHz crystal frequency
SSPCON2 = 0x00;
//SSPCON2bits.ACKEN = 1;
}
void I2C1Ack(void)
{
SSPCON2bits.ACKDT = 0; /* Acknowledge data bit, 0 = ACK */
SSPCON2bits.ACKEN = 1; /* Ack data enabled */
while(SSPCON2bits.ACKEN); /* wait for ack data to send on bus */
}
void I2C1Nak(void)
{
SSPCON2bits.ACKDT = 1; /* Acknowledge data bit, 1 = NAK */
SSPCON2bits.ACKEN = 1; /* Ack data enabled */
while(SSPCON2bits.ACKEN); /* wait for ack data to send on bus */
}
void I2C1RecieveEnable(void)
{
SSPCON2bits.RCEN = 1; //enable receive enable bit
while (PIR1bits.SSPIF != 1);
PIR1bits.SSPIF = 0;
}
void I2C1SSPIFWait(void)
{
while (PIR1bits.SSPIF != 1);
PIR1bits.SSPIF = 0;
}
void I2C1_Idle(void)
{
//while (SSP1STATbits.BF); // Wait for bus Idle (BF - is high while transmission in progress)
while ((SSP1CON2 & 0x1F) | (SSP1STATbits.R_W));
}
void I2C1_start(void)
{
I2C1_Idle(); // Wait for Bus Idle
SSPCON2bits.SEN = 1;
while (PIR1bits.SSPIF != 1); //START CONDITION and wait for SSPIF flag
PIR1bits.SSPIF = 0;
}
void I2C1_repeated_start(void)
{
SSPCON2bits.RSEN = 1;
while (PIR1bits.SSPIF != 1); //REPEATED START CONDITION
PIR1bits.SSPIF = 0;
}
void I2C1_stop(void)
{
SSPCON2bits.PEN = 1; // STOP condition
while (PIR1bits.SSPIF != 1); //REPEATED START CONDITION
PIR1bits.SSPIF = 0;
}
unsigned char I2C1_byte_read(unsigned char dev_add, unsigned char loc_add)
{
unsigned char read_dat = 0;
unsigned char temp_add = (dev_add | 0x01);
I2C1_start(); // SMBus START
SSPBUF = dev_add; // Slave Address with Write Bit
I2C1SSPIFWait();
//pointing to specific location
SSPBUF = loc_add; //Command Code / add location
I2C1SSPIFWait();
//I2C1_repeated_start();
SSPBUF = temp_add; //Slave Address + Read Bit
I2C1SSPIFWait();
read_dat = SSPBUF; //saving data into some register
// SSPCON2bits.ACKDT = 0; // Send an ack bit
// SSPCON2bits.ACKEN = 1;
// while (SSPCON2bits.ACKEN); // Wait for ack to finish
I2C1_stop(); // SMBus STOP
return (read_dat);
}
unsigned int I2C1_Word_read(unsigned char dev_add, unsigned char loc_add)
{
unsigned int read_dat_msb = 0, read_dat_lsb = 0, read_dat = 0;
unsigned char temp_add = (dev_add | 0x01); //((dev_add << 1) | 0x01); //Fz_Mod
I2C1_start(); // SMBus START
SSPBUF = dev_add; // Slave Address with Write Bit
I2C1SSPIFWait();
//I2C1Ack(); // ACK
//pointing to specific location
SSPBUF = loc_add; //Command Code / add location
I2C1SSPIFWait();
//I2C1Ack(); // ACK
I2C1_repeated_start();
SSPBUF = temp_add; //Slave Address + Read Bit
I2C1SSPIFWait();
//I2C1RecieveEnable();
//I2C1Ack(); // ACK
read_dat_lsb = SSPBUF; //saving data into some register
I2C1Ack(); // ACK
read_dat_msb = SSPBUF; //saving data into some register
I2C1Nak(); // NACK
I2C1_stop(); // SMBus STOP
read_dat_msb = read_dat_msb << 8;
read_dat = read_dat_msb | read_dat_lsb;
return (read_dat);
}
--------------------------------------------------------------------------
2. One more query i have is :
Which of the following 2 codes are right ?
Code:
void I2C1_start(void)
{
I2C1_Idle(); // Wait for Bus Idle
SSPCON2bits.SEN = 1;
while (SSPCON2bits.SEN);
}
or
Code:
void I2C1_start(void)
{
I2C1_Idle(); // Wait for Bus Idle
SSPCON2bits.SEN = 1;
while (PIR1bits.SSPIF != 1); //START CONDITION and wait for SSPIF flag
PIR1bits.SSPIF = 0;
}
Second one ( while (PIR1bits.SSPIF != 1); ) is working for me, but all the example codes i have see seem to be using the first part.