AnsweredAssumed Answered

I2C stuck sending address

Question asked by uli stone on Sep 20, 2017
Latest reply on Sep 21, 2017 by uli stone

Hello,

I'm having trouble using I2C (Fast Mode, Master Mode) on a STM32F411RE (Nucleo-F411RE).

My code gets stuck after sending the I2C Address here:

while (!(I2C1->SR1 & I2C_SR1_ADDR));

 

On the bus I get short pulses, but no clock signal or data on SDA.

 

My full code is this:

//I2C configuration
void I2C_Config(void)
{
  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; //enable AHB1 GPIO->B clock
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; //enable Clock for I2C

  GPIOB->AFR[1] |= (1 << 2) | (1 << 6); //AF4

  GPIOB->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1; //set PB8 & PB9 to alternate function
  GPIOB->OTYPER |= GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9;      //Open-Drain configuration for PB8 & PB9, Reset configuration
  ///GPIOB->PUPDR |= GPIO_PUPDR_PUPDR8_0 | GPIO_PUPDR_PUPDR9_0;  //External Pull-up's
  GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR8_0 & GPIO_OSPEEDER_OSPEEDR9_0);

  I2C1->CR1 |= I2C_CR1_SWRST;
  I2C1->CR1 &= ~(I2C_CR1_SWRST);

  I2C1->CR2 &= ~(I2C_CR2_FREQ); //reset Frequency
  I2C1->CR2 |= 30; //30MHz from APB1
  I2C1->CCR &= ~I2C_CCR_CCR;
  I2C1->CCR |= I2C_CCR_FS | I2C_CCR_DUTY | 3;
  I2C1->TRISE |= 1 << 1 | 1 << 3;
  I2C1->CR1 |= I2C_CR1_PE | I2C_CR1_ACK;
}

//Start I2C Communication
void I2C_Start(void)
{
  I2C1->CR1 |= I2C_CR1_START;
  while (!(I2C1->SR1 & I2C_SR1_SB));
}

//Stop I2C Communication
void I2C_Stop(void)
{
  I2C1->CR1 |= I2C_CR1_STOP;
}

//Send I2C Slave Address
void I2C_ADDR(unsigned char ADDR)
{
  char clear_addr_flag;
  I2C1->DR = ADDR; //Write I2C Slave Address
  while (!(I2C1->SR1 & I2C_SR1_ADDR));                            //Wait till Address is sent
  clear_addr_flag = (I2C1->SR2); //Reset ADDR-Flag
}

//Write Data (Byte) to I2C Bus
void I2C_Write(unsigned char write_data)
{
  I2C1->DR = write_data;
  while (!(I2C1->SR1 & I2C_SR1_TXE));
}

//Read Data from I2C Bus, Acknoledge Bit=> I2C_ACKD
unsigned char I2C_Read(void)
{
  while (!(I2C1->SR1 & I2C_SR1_RXNE));
  return (I2C1->DR);
}

 

Can someone tell me why the ADDR Bit is not set?

Thank you

Outcomes