Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Восстановление I2C (stm32)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Интерфейсы
Boriska
Пытаюсь вернуть i2c в рабочее состояние после сбоя.

В апп ноте написано:
Цитата
The procedure is as follows:
1) Master tries to assert a Logic 1 on the SDA line
2) Master still sees a Logic 0 and then generates a clock
pulse on SCL (1-0-1 transition)
3) Master examines SDA. If SDA = 0, go to Step 2; if
SDA = 1, go to Step 4
4) Generate a STOP condition
Note that this process may need to be repeated because
the cleared SDA line may have been cleared for the next
bit, which was a 1. There may be some concern about the
effect this additional clocking and STOPping has on other
peripherals. There is no adverse effect; other slaves are
not paying attention due to the fact that they have not
been addressed. Only the slave that had the interrupted
message will respond to the clocks.


Сделал так:
Код
GPIO_PinAFConfig(GPIO_SCL, GPIO_PinSource_SCL, 0); //GPIO_AF_I2Cx
    GPIO_PinAFConfig(GPIO_SDA, GPIO_PinSource_SDA, 0); //GPIO_AF_I2Cx
    //Configure and initialize the GPIOs
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCL;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIO_SCL, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_Init(GPIO_SDA, &GPIO_InitStructure);
    
    i=0;
    while((GPIO_ReadInputDataBit(GPIO_SDA,GPIO_Pin_SDA)==0)&&(i<20)){
        GPIO_ResetBits(GPIO_SCL,GPIO_Pin_SCL);
        delay10us(1);
        GPIO_SetBits(GPIO_SCL,GPIO_Pin_SCL);
        delay10us(1);
        i++;
    }    
    
    sEE_LowLevel_Init();


Подскажите, где может быть ошибка в реализации? И как можно инициировать сбой, чтобы отладить данный код?
Misile_Inc
А почему вы работаете с i2c как с GPIO? Где работа с регистрами периферии i2c?
Прошу прощения, если не правильно понял ваш код - с stm не имел дело.
Boriska
Цитата(Misile_Inc @ Mar 26 2013, 10:07) *
А почему вы работаете с i2c как с GPIO? Где работа с регистрами периферии i2c?

Регистры периферии i2c используются в остальной части программы.
Этот фрагмент - попытка восстановить работоспособность шины после сбоя, когда мастер думает, что все данные получены, а слейв еще хочет что-то передать.
Boriska
Нашел в Интернете вот такой фрагмент, правда он мне тоже не помогает.
Код
#define    I2C_MAX_RESET_FAIL_COUNT    20
I2C_DeInit(I2Cx);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_SetBits(GPIO_SCL, GPIO_Pin_SCL);
    GPIO_Init(GPIO_SCL, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SDA;
    GPIO_SetBits(GPIO_SDA, GPIO_Pin_SDA);
    GPIO_Init(GPIO_SDA, &GPIO_InitStructure);

    while((GPIO_ReadInputDataBit(GPIO_SDA, GPIO_Pin_SDA) == Bit_RESET) && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
        // Raise SCL, wait until SCL is high (in case of clock stretching)
        GPIO_SetBits(GPIO_SCL, GPIO_Pin_SCL);
        while ((GPIO_ReadInputDataBit(GPIO_SCL, GPIO_Pin_SCL) == Bit_RESET) && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
              delay10us(1);
              timeout_fails++;
        }
        delay10us(1);

        // Lower SCL, wait
        GPIO_ResetBits(GPIO_SCL, GPIO_Pin_SCL);
        delay10us(1);

        // Raise SCL, wait
        GPIO_SetBits(GPIO_SCL, GPIO_Pin_SCL);
        delay10us(1);
        timeout_fails++;
    }

    // Generate a start condition followed by a stop condition
    GPIO_SetBits(GPIO_SCL, GPIO_Pin_SCL);
    delay10us(1);
    GPIO_ResetBits(GPIO_SDA, GPIO_Pin_SDA);
    delay10us(1);
    GPIO_ResetBits(GPIO_SDA, GPIO_Pin_SDA);
    delay10us(1);

    // Raise both SCL and SDA and wait for SCL high (in case of clock stretching)
    GPIO_SetBits(GPIO_SDA, GPIO_Pin_SDA);
    GPIO_SetBits(GPIO_SCL, GPIO_Pin_SCL);
    while (GPIO_ReadInputDataBit(GPIO_SCL, GPIO_Pin_SCL) == Bit_RESET && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
        delay10us(1);
        timeout_fails++;
    }

    // Wait for SDA to be high
    while (GPIO_ReadInputDataBit(GPIO_SDA, GPIO_Pin_SDA) != Bit_SET && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
        delay10us(1);
        timeout_fails++;
    }


    sEE_Init();
    
    bmp085Init();
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.