I2C on STM32L152 does not work

606 Views Asked by At

I want to connect 2 devices with I2C. But I don't get the I2c working. I tried a lot and looked on a lot of website but still without any success. I connect my circuit to a oscilloscope and then I saw that there was noting send.

I connected everything good and added a pull up resistor.

Here is my code:

#include <stddef.h>
#include "stm32l1xx.h"
#include "stm32l1xx_rcc.h"
#include "stm32l1xx_i2c.h"
#include "stm32l1xx_gpio.h"
#include "core_cmFunc.h"


#define Timed(x) Timeout = 0xFFFF; while (x) { if (Timeout-- == 0) goto errReturn;}

void I2C_LowLevel_Init() {
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    GPIO_StructInit(&GPIO_InitStructure); // configure I#C clock and GPIO

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    //Configure pins: SCL and SDA ------------------
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

//    I2C1 reset
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);

    I2C_StructInit(&I2C_InitStructure);
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 1;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = GPIO_Speed_400KHz;

    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
}


int I2C_Write(const uint8_t *buf, uint32_t nbyte, uint8_t SlaveAddress) {
    uint32_t Timeout = 0;
    if (nbyte) {
        Timed(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
//      Intiate Start Sequence
        I2C_GenerateSTART(I2C1, ENABLE);
        Timed(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
//      Send Address EV5
        I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter);
        Timed(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//      EV6 Write first byte EV8_1
        I2C_SendData(I2C1, *buf++);
        while (--nbyte) {
//      wait on BTF
            Timed(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));
            I2C_SendData(I2C1, *buf++);
        }
        Timed(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));
        I2C_GenerateSTOP(I2C1, ENABLE);
        Timed(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
    }
    return 1;

    errReturn:
    return -1;
}

int main(void) {
    uint8_t buf[] = {0x01, 0x00, 0x13, 0xFF};
    I2C_LowLevel_Init();
    I2C_Write(&buf, 4, 0x20);
}
1

There are 1 best solutions below

2
On

Just a guess: you have a typo in:

    RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

Change it to:

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);