Ayberk Karaakın
Ayberk Karaakın

Reputation: 31

STM32F4 I2C without library

I have to wire a code for STM32F4 discovery and pcf8574 with I2C.

I can't use any library function. I try something I didn't do it. I did write after init code.

My init code

RCC->APB1ENR|=RCC_APB1ENR_I2C1EN ; // enable APB1 peripheral clock for I2C1
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN; // enable clock for SCL and SDA pins

//SCL on PB6 and SDA on PB7 
GPIOB->MODER|=GPIO_MODER_MODER6; // set pin to alternate function
GPIOB->MODER|=GPIO_MODER_MODER7; // set pin to alternate function

GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR6; //set GPIO speed
GPIOB->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR7; //set GPIO speed

GPIOB-> OTYPER |= GPIO_OTYPER_OT_6; // set output to open drain --> the line has to be only pulled low, not driven high
GPIOB-> OTYPER |= GPIO_OTYPER_OT_7; // set output to open drain --> the line has to be only pulled low, not driven high

GPIOB-> PUPDR  |=GPIO_PUPDR_PUPDR6_0; // enable pull up resistors
GPIOB-> PUPDR  |=GPIO_PUPDR_PUPDR7_0; // enable pull up resistors

GPIOB-> AFR[1] = 0x44000000; // Connect I2C1 pins to AF (af4)

// configure I2C1 

I2C1-> CR2 = 8;  // set peripheral clock to 8mhz
I2C1-> CR2 = 40; // 100khz i2c clock
I2C1-> CR2 |= ~(I2C_CR1_SMBUS); // I2C mode
I2C1-> OAR2 = 0x00; // address not important
I2C1-> CR2 |= 1;    // i2c enable;

Upvotes: 2

Views: 2511

Answers (2)

0___________
0___________

Reputation: 67476

I2C1-> CR2 |= ~(I2C_CR1_SMBUS); // I2C mode

This line does something different that you think. If the idea was to clear that bit it shuold be

I2C1-> CR2 &= ~(I2C_CR1_SMBUS); // I2C mode

Otherwise you set all the bits in the CR2 register except I2C_CR1_SMBUS which is left unchanged.

Another problem is that you try to set CR2 using CR1 bit definitions.

Same is with the enable bit - wrong register.

I2C should be reset before first use on many STM32 micros.

Upvotes: 6

lalnashi
lalnashi

Reputation: 61

Hi I am having the same problem with setting an STM32F4 DISCO board to go

I noticed that you are setting

I2C1-> CR2 = 8;  // set peripheral clock to 8mhz
I2C1-> CR2 = 40; // 100khz i2c clock

you are writing twice to the same register. For the I2C clock you need to set I2C1->CCR to the calculated value

I hope this helps

Upvotes: 1

Related Questions