I2C на STM32L152 не работает

Я хочу подключить 2 устройства с I2C. Но у меня не работает I2c. Я много пробовал и просмотрел множество веб-сайтов, но все еще безуспешно. Я подключил свою схему к осциллографу, а затем увидел, что там не было отправки.

Я подключил все хорошо и добавил подтягивающий резистор.

Вот мой код:

#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);
}

person mbakker1996    schedule 04.11.2017    source источник
comment
Просмотрите stackoverflow.com/help/mcve. Поскольку функция I2C_Read не имеет значения, ее не следует включать.   -  person jwdonahue    schedule 05.11.2017
comment
Откуда вы знаете, что не нажимаете метку errReturn в I2C_Write?   -  person jwdonahue    schedule 05.11.2017
comment
#define Timed(x) Timeout = 0xFFFF; while (x) { if (Timeout-- == 0) goto errReturn;} не является надежным таймером. Он может очень быстро выполнить любую функцию, вызываемую x.   -  person jwdonahue    schedule 05.11.2017
comment
I2C on STM32L152 does not work нравится :). 100% работает, а ваша программа нет.   -  person 0___________    schedule 05.11.2017
comment
хаха @PeterJ_01 ты прав ;)   -  person mbakker1996    schedule 05.11.2017


Ответы (1)


Просто предположение: у вас опечатка в:

    RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

Измените его на:

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
person A.K.    schedule 04.11.2017
comment
А, спасибо! Теперь я вижу на осциллографе, что что-то происходит, но все еще нет действительного сигнала I2C. - person mbakker1996; 05.11.2017
comment
Я думаю, вам нужно выяснить, что происходит на прицеле. Обычно в даташитах на устройства есть формы сигнала I2C. - person A.K.; 06.11.2017