Estoy utilizando una placa de desarrollo STM32F401RE para comunicarme a través de I2C a un sensor de placa de ruptura basado en MPU9250. Hasta ahora he establecido la condición de inicio y he enviado la dirección del esclavo / bit de escritura al dispositivo, pero no recibo ningún reconocimiento. He intentado reducir la frecuencia de SCL a 50 KHz y acelerar el tiempo de subida, pero todavía nada. La dirección de esclavo que estoy enviando al dispositivo es 0x68. Soy relativamente nuevo en la programación básica, por lo que cualquier consejo sería muy apreciado.
Código del encabezado I2C:
void I2c_Init(uint8_t slaveAddr) {
I2C1->CR1 &= ~I2C_CR1_PE;
RCC->AHB1ENR |= (1ul << 1); //enable gpio clock
RCC->APB1ENR |= (1ul << 21);// enable i2c clock
GPIOB->MODER &= ~(3ul << 16);
GPIOB->MODER |= (2ul << 16); //set pb8 to af mode
GPIOB->MODER &= ~(3ul << 18);
GPIOB->MODER |= (2ul << 18); //set pb9 to af mode
GPIOB->AFR[1] &= ~(0xF << 0); //pin 8 i2c af
GPIOB->AFR[1] |= (4ul << 0);
GPIOB->AFR[1] &= ~(0xF << 4); //pin 9 i2c af
GPIOB->AFR[1] |= (4ul << 4);
GPIOB->OTYPER |= (1ul << 8); //set pb8 to open drain
GPIOB->OTYPER |= (1ul << 9); //set pb9 to open drain
GPIOB->OSPEEDR &= ~(3ul << 16);
GPIOB->OSPEEDR |= (2ul << 16); //set pb8 to fast mode
GPIOB->OSPEEDR &= ~(3ul << 18);
GPIOB->OSPEEDR |= (2ul << 18); //set pb9 to fast mode
GPIOB->PUPDR &= ~(3ul << 16);
GPIOB->PUPDR &= ~(3ul << 18);
I2C1->CR2 &= ~(0x3F << 0); //reset freqyency bits
I2C1->CR2 = I2C_CR2_FREQ_3; //set register bits to 0x00000008 8MHz
I2C1->CCR &= ~(1ul << 15); //set bit 15 to 0 sm mode
I2C1->CCR &= ~(0xFFF << 0); //clear bits 0-11 for scl
I2C1->CCR |= (0x28 << 0); // setup scl clock as 100Khz by 5000ns / PCLK 125 = 40 (0x28) /////////////50hz 20000ns/125 = 160 = 0xA0
I2C1->TRISE &= ~(0x3F << 0); //clear bits 0 -5;
I2C1->TRISE |= (0x03 << 0); // set rise time to 1000/PCLK = 0x08 + 1 ////////for 300ns////// 300/125 = 0x02 + 1
I2C1->OAR1 = (1ul << 14);
//I2C1->OAR2 &= (1ul << 0);
I2C1->CR1 |= I2C_CR1_PE | I2C_CR1_ACK;// | I2C_CR1_POS;
}
int write_i2c(uint8_t slaveAddr, uint8_t dat) {
I2C1->CR1 |= I2C_CR1_START; //start bit init
while (!(I2C1->SR1 & I2C_SR1_SB)); //wait for start confirm
I2C1->DR = slaveAddr & ~(1ul << 7);// ~I2C_OAR1_ADD0; // send slave address and write bit
while (!(I2C1->SR1 & I2C_SR1_ADDR)) // wait for address confirm
if(I2C1->SR1 & I2C_SR1_AF)
return -1; //if ack fail return
if(!(I2C1->SR1 & I2C_SR1_AF)) return 2;
I2C1->SR1; //sr read
I2C1->SR2; //sr2 read
I2C1->DR &= ~(0xFF << 0); //clear data reg
I2C1->DR |= (dat << 0); // send data
while (!(I2C1->SR1 & (I2C_SR1_BTF | I2C_SR1_AF ))); //wait for data confirm
I2C1->CR1 |= I2C_CR1_STOP; //stop bit
return 0;
}
Salida de alcance:
Configuración: