My STM32F4 I2C function is not working
So I already coded an I2C library for the STM32F1 platform according to the datasheets.
Then I got my hands on a STM32F411CEU6 and tried programming an I2C function for this one.
So I read the documentation and the datasheet and came up with this:
This is the init function:
void I2C_init(void) { RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; GPIOB->MODER &= ~(GPIO_MODER_MODER8 | GPIO_MODER_MODER9); GPIOB->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER8_1; GPIOB->OTYPER |= GPIO_OTYPER_ODR_8 | GPIO_OTYPER_ODR_9; GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9; GPIOB->PUPDR |= GPIO_PUPDR_PUPDR8_0 | GPIO_PUPDR_PUPDR9_0; GPIOB->AFR[1] |= (GPIO_AF4_I2C1<<4) | GPIO_AF4_I2C1; I2C1->CR1 |= I2C_CR1_SWRST; I2C1->CR1 &= ~I2C_CR1_SWRST; // 100MHz / 2 = 50MHz period=0.00000002s=20ns I2C1->CR2 |= 50; //100kHz=100000Hz -> (1/100000)/2 = 5us = 0.000005s -> 5us/20ns=0.000005/0.00000002=250 //5us/(1/50000000) = 250 T_high = CCR * T_PCLK -> t_high = t_r(SCL) + t_w(SCLH) = 1000ns+4us=5us -> can be found in datasheet T_PCLK=APB-Period-time=(1/50MHz) -> 5us/T_PCLK=250 I2C1->CCR |=250; //1000ns/(CR2 period = (1/50MHz)) = 0.000001/0.000000002 = 50 I2C1->TRISE |= 51; //stretch mode activated by default // 7-bit addressing mode enabled by default I2C1->CR1 |= I2C_CR1_PE; } and this is the read function:
void I2C_write(I2C_TypeDef *I2Cx, uint8_t addr, uint8_t reg, uint8_t data){ uint16_t tmp; I2Cx->CR1 |= I2C_CR1_START; while(!(I2Cx->SR1 & I2C_SR1_SB)); I2Cx->DR |= addr<<1; while(!(I2Cx->SR1 & I2C_SR1_ADDR)); tmp = I2Cx->SR2 | I2Cx->SR1; I2Cx->DR |= reg; while(!(I2Cx->SR1 & I2C_SR1_TXE)); I2Cx->DR |= data; while(!(I2Cx->SR1 & I2C_SR1_TXE)); I2Cx->CR1 |= I2C_CR1_STOP; } The problem is that it runs the init function once and then just stops right after the START condition.
Hope someone can help.
[link] [comments]
---

