cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Wrong - STM32F0

Nickname925_O
Associate II
Posted on December 20, 2013 at 08:56

Hello everybody,

I have a problem with the I2C protocol used by the STM32F0.

In fact, after setting up all the necessary stuff if I use this code:

I2C_GenerateSTART(I2C1);

I get the waveform I2C_ONE

http://www.coocox.org/forum/images/ckeditorimages/20131219181541_I2C_ONE.png

The first channel is SDA and the second one is SCL.

Otherwise if I use this code:

I2C1->CR2=0xAA;

I2C_GenerateSTART(I2C1);

I get the waveform I2C_TWO.

http://www.coocox.org/forum/images/ckeditorimages/20131219181602_I2C_TWO.png

In any case, if I use I2C_SendData(....

I am not able to get any data on the I2C bus.

Can you try to use the I2C protocol with the STM32F0 and give me a feedback?

Thanks a lot,

Peppe

stm32f0-i2c-start

23 REPLIES 23
frankmeyer9
Associate II
Posted on January 17, 2014 at 08:49

I connected

 

SDA of IC1 with SDA of IC2

 

SCL of IC1 with SCL of IC2

 

Albeit the likelyhood is small, it could be wired incorrectly, or not soldered correctly. I use to measure a signal at both ends of the line.

I am sure I did set correctly the slave address of IC2 because I set it in init() function...

 

Those addresses are specified as 7 bit (assuming you are using the more common 7 bit mode), meaning bits 1 to 7. I had datasheets that specified an 8 bit address, i.e. actually the write address.

I hope you checked the slave's datasheet, and don't clock too fast.

chen
Associate II
Posted on January 17, 2014 at 10:38

Hi

''I connected

SDA of IC1 with SDA of IC2

SCL of IC1 with SCL of IC2''

That might be your problem!

The STM32 may have 2 I2C peripherals (I2C1 and I2C2) BUT they are NOT joined together in any way.

To get them on the same I2C bus - you MUST join the SDA and SCL lines of both together externally.

Nickname925_O
Associate II
Posted on January 17, 2014 at 17:10

Hi,

I used two fast connector wires to connect externally

SDA IC1 with SDA IC2

and

SCL IC1 with SCL IC2

Do you think it's wrong?

chen
Associate II
Posted on January 17, 2014 at 17:38

Hi

At the beginning of this thread, it sounds like you were trying to I2C communicate STM32 (IC1) with an I2C device (IC2).

Now, you want the 2 I2C peripheral controllers in STM32 (IC1) to wok together.

You have configured and enabled both I2C peripherals in STM32 but one will not respond as a slave device - correct?

Have you connected the I2C pins of STM32 I2C peripheral 1 to

I2C pins of STM32 I2C peripheral 2?

(The 2 are not connected inside the STM32! )

Nickname925_O
Associate II
Posted on January 17, 2014 at 18:13

Hi,

you are right!

I have connected the two I2C modules using external wires and I've enabled both I2C modules.

Do you want to see the code?

chen
Associate II
Posted on January 17, 2014 at 18:35

''Do you want to see the code?''

If you want.

I cannot guarantee that I will find your problem. I have not done enough detailed work with the STM32 I2C peripheral to know it well enough.

Nickname925_O
Associate II
Posted on January 17, 2014 at 19:05

Well,

first of all thanks for your time. I am sure we'll improve our knowledge in any case.

Btw, I think we can start with set up function:

I2C setup means that I set up I2C1 and I2C2:

void set_I2C(void){

GPIO_InitTypeDef GPIO_InitStructure;

I2C_InitTypeDef I2C_InitStructure;

            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

   /* Configure the I2C clock source. The clock is derived from the HSI */

   RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);

   GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1);

   GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1);

   //Configure pins: SCL and SDA ------------------

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

   GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   I2C_DeInit(I2C1);

   I2C_Cmd(I2C1, DISABLE);

   I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;

   I2C_InitStructure.I2C_DigitalFilter = 0x00;

   I2C_InitStructure.I2C_OwnAddress1 = 0x40;

   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

   //I2C_InitStructure.I2C_Timing = 0xA0120227;

   //I2C_InitStructure.I2C_Timing = 0x20310A0D;

   I2C_InitStructure.I2C_Timing =0xB0420F13; //100KHz (see page 529 - table 73 in the manual reference)

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

   I2C_Cmd(I2C1, ENABLE);

   I2C_Init(I2C1, &I2C_InitStructure);

   I2C_ITConfig(I2C1, I2C_FLAG_TXE, ENABLE);

    //Set up of I2C2

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

       GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_1);

       GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_1);

       //Configure pins: SCL and SDA for I2C2 ------------------

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10;

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

       GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

       GPIO_Init(GPIOB, &GPIO_InitStructure);

       I2C_DeInit(I2C2);

       I2C_Cmd(I2C2, DISABLE);

       I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Disable;

       I2C_InitStructure.I2C_DigitalFilter = 0x00;

            I2C_InitStructure.I2C_OwnAddress1 = 0x30; 

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

    I2C_InitStructure.I2C_Timing =0xB0420F13;

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Cmd(I2C2, ENABLE);

                I2C_Init(I2C2, &I2C_InitStructure);

I2C_ITConfig(I2C2, I2C_AcknowledgedAddress_7bit, ENABLE);

}

well, can you give me your point of view about that.

Then from the main function, after setup_I2C calling I have this code:

I2C_AcknowledgeConfig(I2C2, ENABLE);

I2C_SlaveAddressConfig(I2C1,0x30);

I2C_GenerateSTART(I2C1, ENABLE);

    //I2C_ClearITPendingBit(I2C2, I2C_ISR_ADDR);

    while ((I2C1->ISR & I2C_ISR_TXE)==0);    //while TXE ==0, buffer is full

    I2C1->TXDR=0xAA;//example data

Thanks very much in advance.

Nickname925_O
Associate II
Posted on January 17, 2014 at 19:10

Well,

first of all thanks for your time. I am sure we'll improve our knowledge in any case.

Btw, I think we can start with set up function:

I2C setup means that I set up I2C1 and I2C2:

void set_I2C(void){

GPIO_InitTypeDef GPIO_InitStructure;

I2C_InitTypeDef I2C_InitStructure;

            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

   /* Configure the I2C clock source. The clock is derived from the HSI */

   RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);

   GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1);

   GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1);

   //Configure pins: SCL and SDA ------------------

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

   GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   I2C_DeInit(I2C1);

   I2C_Cmd(I2C1, DISABLE);

   I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;

   I2C_InitStructure.I2C_DigitalFilter = 0x00;

   I2C_InitStructure.I2C_OwnAddress1 = 0x40;

   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

   //I2C_InitStructure.I2C_Timing = 0xA0120227;

   //I2C_InitStructure.I2C_Timing = 0x20310A0D;

   I2C_InitStructure.I2C_Timing =0xB0420F13; //100KHz (see page 529 - table 73 in the manual reference)

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

   I2C_Cmd(I2C1, ENABLE);

   I2C_Init(I2C1, &I2C_InitStructure);

   I2C_ITConfig(I2C1, I2C_FLAG_TXE, ENABLE);

    //Set up of I2C2

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

       GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_1);

       GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_1);

       //Configure pins: SCL and SDA for I2C2 ------------------

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10;

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

       GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

       GPIO_Init(GPIOB, &GPIO_InitStructure);

       I2C_DeInit(I2C2);

       I2C_Cmd(I2C2, DISABLE);

       I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Disable;

       I2C_InitStructure.I2C_DigitalFilter = 0x00;

            I2C_InitStructure.I2C_OwnAddress1 = 0x30; 

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

    I2C_InitStructure.I2C_Timing =0xB0420F13;

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Cmd(I2C2, ENABLE);

                I2C_Init(I2C2, &I2C_InitStructure);

I2C_ITConfig(I2C2, I2C_AcknowledgedAddress_7bit, ENABLE);

}

well, can you give me your point of view about that.

Then from the main function, after setup_I2C calling I have this code:

I2C_AcknowledgeConfig(I2C2, ENABLE);

I2C_SlaveAddressConfig(I2C1,0x30);

I2C_GenerateSTART(I2C1, ENABLE);

    //I2C_ClearITPendingBit(I2C2, I2C_ISR_ADDR);

    while ((I2C1->ISR & I2C_ISR_TXE)==0);    //while TXE ==0, buffer is full

    I2C1->TXDR=0xAA;//example data

Thanks very much in advance.

chen
Associate II
Posted on January 17, 2014 at 19:17

Hi

''I2C_SlaveAddressConfig(I2C1,0x30);''

I thought you wanted I2C2 as the slave??

In any case, Im still studying the data sheet and the library code.

Can you test Both I2C to see if they work as master (this will confirm that the config is good)?

Nickname925_O
Associate II
Posted on January 17, 2014 at 19:29

Well the instruction

''I2C_SlaveAddressConfig(I2C1,0x30);''

means that I2C1 will send 0x30 as slave address after the generate_start instruction 🙂

Keep in touch ok?