Jump to content

    

Проблема с I2C

Камень 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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this