Jestem dość nowy w I2C, więc wybacz mój brak wiedzy. Próbuję przeczytać dane z Czujnik PAC1710 za pomocą STM32H743ZI MCU z biblioteką halową i generatorem kodu CubeMX.

Mogę wysłać pierwszą część mojej wiadomości, ale nie dostaję potwierdzenia po wysłaniu adresu. Używam rezystora 2700 Ohm na ziemię na pinach Addr_sel, alert przechodzi do ziemi na podstawie rezystora 10 KOHM.

Jeśli chodzi o mój kod, to moja intiacjalizacja:

void MX_I2C2_Init(void)
{
  hi2c2.Instance = I2C2;
  hi2c2.Init.Timing = 0x307075B1;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c2) != HAL_OK) {
    Error_Handler();
  }
  /** Configure Analogue filter */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK) {
    Error_Handler();
  }
  /** Configure Digital filter */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) {
    Error_Handler();
  }
}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if (i2cHandle->Instance == I2C2) {
  /* USER CODE BEGIN I2C2_MspInit 0 */

  /* USER CODE END I2C2_MspInit 0 */
  
    __HAL_RCC_GPIOF_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C2 GPIO Configuration    
    PB11     ------> I2C2_SDA
    PF1     ------> I2C2_SCL 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C2 clock enable */
    __HAL_RCC_I2C2_CLK_ENABLE();
  }
}

Moja implementacja jest bardzo prosta:

uint8_t i2cbuffer[8];
uint16_t val = 0;
HAL_StatusTypeDef ret;

W głównej pętli mam następujący kod:

        i2cbuffer[0] = 254;
        ret = HAL_I2C_Master_Transmit(&hi2c2, PAC1710Address << 1, i2cbuffer, 1, HAL_MAX_DELAY);   
        if (ret == HAL_OK) {
            ret = HAL_I2C_Master_Receive(&hi2c2, PAC1710Address << 1 , i2cbuffer, 2, HAL_MAX_DELAY);
            if (ret == HAL_OK) {
                val = i2cbuffer[0];
            }
        }
        HAL_Delay(500);

Wybrałem 254, ponieważ chociaż niewolnik powinien być w stanie odpowiedzieć na to niezależnie od jego pomiaru. Jednak nawet nie dostaję nawet o wysłanie rejestru, po tym, jak patrzyłem do go oscyloskopem wysłać adres i dostać Nack.

Czy brakuje czegoś oczywistego?

0
Yamira 5 październik 2020, 10:19

1 odpowiedź

Najlepsza odpowiedź

Po niektórych komentarzach było więcej przydatnych informacji, największa część była tym, że oscyloskop pokazał Start 1010100 0 1 Stop. While 1010100 jest adresem 0x54, a także bit W. Adres powinien nie został przesunięty w lewo, ponieważ był już poprawny.

Jest to nieco powszechny błąd z I2C. Należy zwrócić uwagę na dokładny adres, a {x0}} bitów, jak w niektórych dokumentach i API są przesunięte w lewo, w niektórych nie są.

Bardzo pomocnym biletem informacji tutaj był ślad oscyloskopowy, który naprawdę pomógł pokazać, co dokładnie się dzieje.

1
domen 5 październik 2020, 10:59