2020-03-11 02:45 PM
void initI2C()
{
SET_BIT(GPIOB->CRL, GPIO_CRL_CNF7_1 | GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_0 |
GPIO_CRL_CNF6_0 |\
GPIO_CRL_MODE7_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 |
GPIO_CRL_MODE6_0);
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);
//RCC peripheral clock enabling
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);
//Delay after an RCC peripheral clock enabling
__IO uint32_t tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);
//Disable acknowledge on Own Address2 match address
CLEAR_BIT(I2C1->OAR2, I2C_OAR2_ENDUAL);
//Disable General Call
CLEAR_BIT(I2C1->CR1, I2C_CR1_ENGC);
//Enable Clock stretching
CLEAR_BIT(I2C1->CR1, I2C_CR1_NOSTRETCH);
//Disable I2C peripheral
CLEAR_BIT(I2C1->CR1, I2C_CR1_PE);
//ClockSpeed
MODIFY_REG(I2C1->CR2, I2C_CR2_FREQ, 36);
//MODIFY_REG(I2C1->TRISE, I2C_TRISE_TRISE, 36 + 1); //100
MODIFY_REG(I2C1->TRISE, I2C_TRISE_TRISE, 11); //400
//MODIFY_REG(I2C1->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), 180); //100
MODIFY_REG(I2C1->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), 0x0000801E); //400
//Set the Own Address1
MODIFY_REG(I2C1->OAR1, I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE, I2C_OWNADDRESS1_7BIT);
//Configure I2C1 peripheral mode with parameter : I2C
MODIFY_REG(I2C1->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP, I2C_MODE_I2C);
//Enable I2C peripheral
SET_BIT(I2C1->CR1, I2C_CR1_PE);
//TypeAcknowledge
MODIFY_REG(I2C1->CR1, I2C_CR1_ACK, I2C_CR1_ACK);
//Set the 7bits Own Address2
MODIFY_REG(I2C1->OAR2, I2C_OAR2_ADD2, 0);
}
and here is read/write functions
void write(uint8_t devAddress, uint16_t regAddress, uint8_t data)
{
__IO uint16_t temp;
SET_BIT(I2C1->CR1, I2C_CR1_PE);
I2C1->CR1 |= I2C_CR1_ACK;
// send START
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
temp = I2C1->SR1;
// by writing DR clear SB flag and send address
I2C1->DR = devAddress;
while(!(I2C1->SR1 & I2C_SR1_ADDR));
temp = I2C1->SR1;
temp = I2C1->SR2;
// send slave register address
I2C1->DR = regAddress;
while(!(I2C1->SR1 & I2C_SR1_TXE));
// send data and clear TXE flag
I2C1->DR = data;
while(!(I2C1->SR1 & I2C_SR1_TXE));
// send stop
I2C1->CR1 |= I2C_CR1_STOP;
//while((I2C1->SR1 & I2C_SR1_STOPF));
}
void read(uint8_t devAddress, uint16_t regAddress, uint8_t *data, const uint8_t &len)
{
__IO uint16_t temp;
SET_BIT(I2C1->CR1, I2C_CR1_PE);
I2C1->CR1 |= I2C_CR1_ACK;
// send START
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
temp = I2C1->SR1;
// send DEV ADDRESS
I2C1->DR = devAddress;
while(!(I2C1->SR1 & I2C_SR1_ADDR));
temp = I2C1->SR1;
temp = I2C1->SR2;
// send register address
I2C1->DR = regAddress;
while(!(I2C1->SR1 & I2C_SR1_TXE));
// send START
I2C1->CR1 |= I2C_CR1_START;
while(!(I2C1->SR1 & I2C_SR1_SB));
temp = I2C1->SR1;
// send DEVADDRESS read mode
I2C1->DR = devAddress | 1;
while(!(I2C1->SR1 & I2C_SR1_ADDR));
temp = I2C1->SR1;
temp = I2C1->SR2;
for(uint8_t i = 0; i<len; i++)
{
if(i < (len - 1))
{
while(!(I2C1->SR1 & I2C_SR1_RXNE));
*(data+i) = I2C1->DR;
}
else
{
I2C1->CR1 &= ~I2C_CR1_ACK;
I2C1->CR1 |= I2C_CR1_STOP;
while(!(I2C1->SR1 & I2C_SR1_RXNE));
*(data+i) = I2C1->DR;
}
}
}
After I setup my MPU9250 and sometimes it stalls in
while(!(I2C1->SR1 & I2C_SR1_ADDR));
sometimes in
while(!(I2C1->SR1 & I2C_SR1_SB));
sometimes
I2C_SR1_AF
is 1, . Please Help, if you need additional information I can send it.