Перейти к содержанию
    

Проблема с 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

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jenya7 сказал:

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

43 minutes ago, Arlleex said:

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


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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

    I2C0_C1 |= I2C_C1_TX_MASK;    
    I2C0_C1 |= I2C_C1_MST_MASK;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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  будут разные. И эти параметры, как мне кажется не подходят, их нужно подобрать.


 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...