Jump to content

    
Sign in to follow this  
jenya7

Проблема с I2C

Recommended Posts

Камень MK10DN512.

Пишу

unsigned int I2C0_Wait(void)
{
      unsigned int timeout = 0;

      while((I2C0_S & I2C_S_IICIF_MASK)==0)
      {
          timeout++;

          if(timeout > I2C_TIMEOUT)
            return I2C_ERROR;
      }
  
      I2C0_S |= I2C_S_IICIF_MASK;

      return 0;
}


void MAX7300_Write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data)
{
    uint8_t slave_address = (slave_addr<<1) & 0xFE;

    //START
    I2C0_C1 |= I2C_C1_MST_MASK;
    I2C0_C1 |= I2C_C1_TX_MASK;

    I2C0_D = slave_address;
    I2C0_Wait();

    I2C0_D = reg_addr;
    I2C0_Wait();

    I2C0_D = *data;
    I2C0_Wait();

    //STOP
    I2C0_C1 &= ~I2C_C1_MST_MASK;
    I2C0_C1 &= ~I2C_C1_TX_MASK

    while (I2C0_S & I2C_S_BUSY_MASK) ;
}

Остаюсь в while (I2C0_S & I2C_S_BUSY_MASK). Флаг BUSY не очищается.

Хотя в документации сказано

Quote

BUSY

Indicates the status of the bus regardless of slave or master mode. This bit is set when a START signal is
detected and cleared when a STOP signal is detected.

0 Bus is idle
1 Bus is busy

 

Edited by jenya7

Share this post


Link to post
Share on other sites
1 час назад, jenya7 сказал:

Остаюсь в while (I2C0_S & I2C_S_BUSY_MASK). Флаг BUSY не очищается.

Точка с запятой где?

//STOP
I2C0_C1 &= ~I2C_C1_MST_MASK;
I2C0_C1 &= ~I2C_C1_TX_MASK

 

Анализатором в линию смотрели?

Share this post


Link to post
Share on other sites
43 minutes ago, Arlleex said:

Точка с запятой где?


//STOP
I2C0_C1 &= ~I2C_C1_MST_MASK;
I2C0_C1 &= ~I2C_C1_TX_MASK

 

Анализатором в линию смотрели?

Вижу сигналы на SDA и SCL. вроде правильные.

Share this post


Link to post
Share on other sites

1. Я бы while (I2C0_S & I2C_S_BUSY_MASK) ; поставил перед передачей
2. И в старте, мне кажется, нужно изменить порядок на

    I2C0_C1 |= I2C_C1_TX_MASK;    
    I2C0_C1 |= I2C_C1_MST_MASK;

Share this post


Link to post
Share on other sites
On 12/21/2018 at 11:20 AM, Integro said:

1. Я бы while (I2C0_S & I2C_S_BUSY_MASK) ; поставил перед передачей
2. И в старте, мне кажется, нужно изменить порядок на


    I2C0_C1 |= I2C_C1_TX_MASK;    
    I2C0_C1 |= I2C_C1_MST_MASK;

не помогло. единственное что приходит в голову - неправильное формирование старт-стоп или неправильная загрузка значений в регистр I2C0->F хотя там не особо много опций.

 

Мне кажется тут проблема вот в чем. Допустим мне нужна скорость СПИ 300К. Тогда  I2C baud rate = bus speed (Hz)/(mul × SCL divider) -> 48000000/160 = 300000.

Но делитель можно достичь разными путями 2*80, 4*20. Делитель тот же но параметры SDA hold time, SCL start hold time, SCL stop hold time  будут разные. И эти параметры, как мне кажется не подходят, их нужно подобрать.


 

Edited by jenya7

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this