Hello @Siva Ram ,
For the I2C communication with sensor , please try to :
1. Enable the I2C and GPIO CLOCKS
2. Configure the Pins for I2C
3. Reset the I2C
4. Set the I2C clock
5. Enable the I2C
I2C START
void I2C_Start (void)
{
/* 1. Send the START condition
2. Wait for the SB ( Bit 0 in SR1) to set. This indicates that the start condition is generated
*/
I2C1->CR1 |= (1<<10); // Enable the ACK
I2C1->CR1 |= (1<<8); // Generate START
while (!(I2C1->SR1 & (1<<0))); // Wait fror SB bit to set
}
Send address
void I2C_Address (uint8_t Address)
{
/* 1. Send the Slave Address to the DR Register
2. Wait for the ADDR (bit 1 in SR1) to set. This indicates the end of address transmission
3. clear the ADDR by reading the SR1 and SR2*/
I2C1->DR = Address; // send the address
while (!(I2C1->SR1 & (1<<1))); // wait for ADDR bit to set
uint8_t temp = I2C1->SR1 | I2C1->SR2; // read SR1 and SR2 to clear the ADDR bit
}
I2C WRITE
void I2C_Write (uint8_t data)
{
/* 1. Wait for the TXE (bit 7 in SR1) to set. This indicates that the DR is empty
2. Send the DATA to the DR Register
3. Wait for the BTF (bit 2 in SR1) to set. This indicates the end of LAST DATA transmission */
while (!(I2C1->SR1 & (1<<7))); // wait for TXE bit to set
I2C1->DR = data;
while (!(I2C1->SR1 & (1<<2))); // wait for BTF bit to set
}
I2C Read
void I2C_Read (uint8_t Address, uint8_t *buffer, uint8_t size)
{
/* 1. If only 1 BYTE needs to be Read
a) Write the slave Address, and wait for the ADDR bit (bit 1 in SR1) to be set
b) the Acknowledge disable is made during EV6 (before ADDR flag is cleared) and the STOP condition generation is made after EV6
c) Wait for the RXNE (Receive Buffer not Empty) bit to set
d) Read the data from the DR
2. If Multiple BYTES needs to be read
a) Write the slave Address, and wait for the ADDR bit (bit 1 in SR1) to be set
b) Clear the ADDR bit by reading the SR1 and SR2 Registers
c) Wait for the RXNE (Receive buffer not empty) bit to set
d) Read the data from the DR
e) Generate the Acknowlegment by settint the ACK (bit 10 in SR1)
f) To generate the nonacknowledge pulse after the last received data byte, the ACK bit must be cleared just after reading the
second last data byte (after second last RxNE event)
g) In order to generate the Stop/Restart condition, software must set the STOP/START bit
after reading the second last data byte (after the second last RxNE event)
*/
int remaining = size;
/**** STEP 1 ****/
if (size == 1)
{
/**** STEP 1-a ****/
I2C1->DR = Address; // send the address
while (!(I2C1->SR1 & (1<<1))); // wait for ADDR bit to set
/**** STEP 1-b ****/
I2C1->CR1 &= ~(1<<10); // clear the ACK bit
uint8_t temp = I2C1->SR1 | I2C1->SR2; // read SR1 and SR2 to clear the ADDR bit.... EV6 condition
I2C1->CR1 |= (1<<9); // Stop I2C
/**** STEP 1-c ****/
while (!(I2C1->SR1 & (1<<6))); // wait for RxNE to set
/**** STEP 1-d ****/
buffer[size-remaining] = I2C1->DR; // Read the data from the DATA REGISTER
}
/**** STEP 2 ****/
else
{
/**** STEP 2-a ****/
I2C1->DR = Address; // send the address
while (!(I2C1->SR1 & (1<<1))); // wait for ADDR bit to set
/**** STEP 2-b ****/
uint8_t temp = I2C1->SR1 | I2C1->SR2; // read SR1 and SR2 to clear the ADDR bit
while (remaining>2)
{
/**** STEP 2-c ****/
while (!(I2C1->SR1 & (1<<6))); // wait for RxNE to set
/**** STEP 2-d ****/
buffer[size-remaining] = I2C1->DR; // copy the data into the buffer
/**** STEP 2-e ****/
I2C1->CR1 |= 1<<10; // Set the ACK bit to Acknowledge the data received
remaining--;
}
// Read the SECOND LAST BYTE
while (!(I2C1->SR1 & (1<<6))); // wait for RxNE to set
buffer[size-remaining] = I2C1->DR;
/**** STEP 2-f ****/
I2C1->CR1 &= ~(1<<10); // clear the ACK bit
/**** STEP 2-g ****/
I2C1->CR1 |= (1<<9); // Stop I2C
remaining--;
// Read the Last BYTE
while (!(I2C1->SR1 & (1<<6))); // wait for RxNE to set
buffer[size-remaining] = I2C1->DR; // copy the data into the buffer
}
}
Hope I helped you!
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.