I2 C драйвер низкого уровня - PullRequest
       30

I2 C драйвер низкого уровня

0 голосов
/ 11 февраля 2020

Я использую STM32L475, и у меня проблема со связью через I2 C. Мой код основан на примере, предоставленном ST.

void Handle_I2C_Master(I2C_TypeDef * I2Cx, uint32_t slave_addr, uint8_t *tx_data, uint8_t *rx_data,  uint8_t size)
{
    uint32_t Timeout;
    uint32_t len = 0;
    i2c_idx = 0;

    /* (1) Initiate a Start condition to the Slave device ***********************/

    /* Master Generate Start condition for a write request :              */
    /*    - to the Slave with a 7-Bit SLAVE_OWN_ADDRESS                   */
    /*    - with a auto stop condition generation when transmit all bytes */
    LL_I2C_HandleTransfer(I2Cx, slave_addr/*SLAVE_OWN_ADDRESS*/, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ /*LL_I2C_GENERATE_START_WRITE*/);

    /* (2) Loop until end of transfer received (STOP flag raised) ***************/

    Timeout = 0;  //I2C_SEND_TIMEOUT_TXIS_MS;

    /* Loop until STOP flag is raised  */
    while(!LL_I2C_IsActiveFlag_STOP(I2Cx))
    {
        /* (2.1) Transmit data (TXIS flag raised) *********************************/

        /* Check TXIS flag value in ISR register */
        if(LL_I2C_IsActiveFlag_TXIS(I2Cx))
        {
            /* Write data in Transmit Data register.
            TXIS flag is cleared by writing data in TXDR register */
            if (len < size)
                LL_I2C_TransmitData8(I2Cx, (*tx_data++));
            len++;

            Timeout = 0; //I2C_SEND_TIMEOUT_TXIS_MS;
        }

        Timeout++;
        Delay_ms(1);

        if(Timeout >= I2C_SEND_TIMEOUT_TXIS_MS)
        {
        }
    }

    /* (3) Clear pending flags, Data consistency are checking into Slave process */

    /* End of I2C_SlaveReceiver_MasterTransmitter Process */
    LL_I2C_ClearFlag_STOP(I2Cx);

    while (!i2c_data_ready) ;

    memcpy (rx_data, i2c_data_buf, i2c_idx);
    i2c_data_ready = 0; 
    i2c_idx = 0;    
}

И я использую прерывание. Я включаю его в функции настройки.

void I2C2_EV_IRQHandler(void)
{
    /* Check RXNE flag value in ISR register */
    if(LL_I2C_IsActiveFlag_RXNE(I2C2))
    {
        if (i2c_idx < 8)
        {
            i2c_data_buf[i2c_idx] =  LL_I2C_ReceiveData8(I2C2);
            i2c_idx++;
        }
    }
    /* Check STOP flag value in ISR register */
    else if(LL_I2C_IsActiveFlag_STOP(I2C2))
    {
        /* End of Transfer */
        LL_I2C_ClearFlag_STOP(I2C2);

        i2c_data_ready = 1;
    }
    else
    {
       /* Call Error function */
       //Error_Callback();
    }
}

И я пытаюсь прочитать с ведомого устройства регистр идентификатора

i2c_tx_data[0] = HTS221_WHO_AM_I_REG;
Handle_I2C_Master(I2C2, 0xBE, i2c_tx_data, i2c_rx_data, 1);

Но я застрял в то время (! LL_I2C_IsActiveFlag_STOP (I2Cx)). Я вижу первые посылочные часы на выводе SCL.

...