При отправке байта по I2C Proteus досылает сдвинутый вправо байт, а контроллер получает байт, сдвинутый влево

Посылка по I2C на запись или изменение значения регистра на запись должна выглядеть следующим образом:

S <адрес> <регистр>[ <значение>] P

При этом не должно быть никаких сдвигов. Однако если отлаживать на отладчике I2C Proteus, то он досылает байт, сдвинутый побитово вправо, а контроллер получает байт, сдвинутый влево. Собираю из Atmel Studio 7, SDK встроенный. Как побороть данную проблему?

Код обработчика прерываний от I2C

ISR(TWI_vect)
{
    //cli();
    
  switch(TW_STATUS)
  {
    case TW_SR_DATA_ACK:
      // received data from master, call the receive callback
      // расчет на то, что при приеме данных первым байтом 
      // будет регистр, куда будут записываться данные
      I2C_recv(TWDR, is_data_recv);
      
      if (is_data_recv == 0) {
          is_data_recv = 1;
          I2C_ack();
      }
      else I2C_nack();
      //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
      break;
    case TW_ST_SLA_ACK:
      // master is requesting data, call the request callback
      I2C_req();
      //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
      break;
    case TW_ST_DATA_ACK:
      // master is requesting data, call the request callback
      I2C_req();
      //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
      break;
    case TW_BUS_ERROR:
      // some sort of erroneous state, prepare TWI to be readdressed
      TWCR = 0;
      //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
      break;
    case TW_SR_STOP:
      is_data_recv = 0;
      I2C_on_stop();
      //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
      break;
    default:
      //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
      break;
  }
  
  
  //sei();
  //TWCR |= (1<<TWINT);
  TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEN);
} 

Код callback

// Прием по I2C регистров/данных
void i2c_receive_cb(uint8_t byte_received, uint8_t is_data) {
    if (is_data == 0) regaddr = byte_received;
    else regdata = byte_received;
}

// Выдача данных при задание одного из регистров на чтение
void i2c_response_cb() {
    uint8_t data_out = 0;
    //uint8_t ack = 0;
    switch (regdata)
    {
    case GET_ANALOG:
        data_out = (data_block % 2 == 0 ? analog_h[data_block] : analog_l[data_block]);
        data_block++;
        if (data_block > 15) {
            data_block = 0;
            I2C_nack();
        }
        else {
            I2C_ack();
        }
        //ack = 0;
        break;
    case GET_ERRORS:
        data_out = 0x66;                // Выдача кода ошибки
        I2C_nack();
    }
    
    I2C_transmitByte(data_out);
}

// Применение данных из регистра на запись, или сброс счетчика блоков данных
void i2c_on_stop_cb() {
    data_block = 0;
    
    
}

Ссылка на проект

Как это выглядит в proteus


Ответы (0 шт):