Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не принимается >1 байта с I2C
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > STM8
Spider
Всем привет!

Работаю с железкой по i2c, в основном "обращения" все по 1 байту - пишу адресс, читаю 1 байт. всё это работает. Но вот если хотя бы 2 байта, а то и более зависает приём на последнем байте.
Код
void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)
{
    // ENTR_CRT_SECTION();

    /* While the bus is busy */
    //while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));

    /* Send START condition */
    I2C_GenerateSTART(ENABLE);

    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

    /* Send MPU6050 address for write */
    I2C_Send7bitAddress(slaveAddr, I2C_DIRECTION_TX);

    /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Clear EV6 by setting again the PE bit */
    I2C_Cmd(ENABLE);

    /* Send the MPU6050's internal address to write to */
    I2C_SendData(readAddr);

    /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send STRAT condition a second time */
    I2C_GenerateSTART(ENABLE);

    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

    /* Send MPU6050 address for read */
    I2C_Send7bitAddress(slaveAddr, I2C_DIRECTION_RX);

    /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    volatile u8 t;
    
    /* While there is data to be read */
    while (NumByteToRead)
    {      
        if (NumByteToRead == 1)
        {
            /* Disable Acknowledgement */
            I2C_AcknowledgeConfig(I2C_ACK_NONE);

            /* Send STOP Condition */
            I2C_GenerateSTOP(ENABLE);
            
        t=0;
        }

        /* Test on EV7 and clear it */
        if (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            /* Read a byte from the MPU6050 */
            *pBuffer = I2C_ReceiveData();

            /* Point to the next location where the byte read will be saved */
            pBuffer++;

            /* Decrement the read bytes counter */
            NumByteToRead--;
        }
    }

    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2C_ACK_CURR);
    // EXT_CRT_SECTION();
}


t=0; чтобы отладчиком туда попасть после STOP sm.gif
Анализатором на щине i2c всё правильно - все байты приняты, последний NACK и STOP.
По коду же после STOP событие I2C_EVENT_MASTER_BYTE_RECEIVED не выставляется, но при 1 байте всё работает. Что я делаю не так? Да и код-то из примера STMовского...
RabidRabbit
А чем пугают прерывания? sm.gif Я бы сначала принял байт, а уж потом, в зависимости от обстоятельств, выставлял STOP.
Ruslan1
Вот хотите бейте меня палками, но беспроблемной реализации именно аппаратного I2C я нигде не видел. Где это Ерратами подтверждено, где просто битьем об стену лбом. Пока что мне "не везло" c PIC от 16 до 32, Atmel AT91RM9200, ST STM32F407. То зависает после захвата клока слейвом, то теряет или не выдает или вообще игнорирует аки/наки/стопы, то блокируется после нескольких суток работы.... везде свои хитрости и куча аппноутов и еррат с костылями.
Очень может быть, что я его так и научился готовить, но я пытался.
Так что таскаю давным-давно однажды отлаженную программную реализацию I2C из продукта в продукт, из процессора в процессор.
RabidRabbit
Цитата(Ruslan1 @ Jan 19 2015, 14:12) *
Вот хотите бейте меня палками, но беспроблемной реализации именно аппаратного I2C я нигде не видел.

Смотрите в сторону TWI на AVR; модуля I2C в MB91F362GB; SERCOM в режиме I2C на AT91SAMD21.
Harbinger
В сторону NXP надо смотреть. Как-никак авторы сего интерфейса. sm.gif
Ближе к теме. Для STM32F1 пришлось писать три процедуры чтения - для 1 байта, 2 и более 2. В STM8 I2C устроен сходным кривым образом. На сайте ST есть пример, в котором это всё разруливается (в периферийную библиотеку он не входит). AN3281.
Spider
Цитата(Harbinger @ Jan 20 2015, 08:40) *
В сторону NXP надо смотреть. Как-никак авторы сего интерфейса. sm.gif
Ближе к теме. Для STM32F1 пришлось писать три процедуры чтения - для 1 байта, 2 и более 2. В STM8 I2C устроен сходным кривым образом. На сайте ST есть пример, в котором это всё разруливается (в периферийную библиотеку он не входит). AN3281.

Именно так и сдала - работает. Очередной костыль.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.