简体   繁体   English

从 I2C Slave 识别 NACK 的原因

[英]Identify reason for NACK from I2C Slave

I am fairly new to I2C so please excuse my lack of knowledge.我对 I2C 相当陌生,所以请原谅我缺乏知识。 I am trying to read Data from an PAC1710 sensor using an Stm32H743ZI MCU with the HAL-Library and the cubemx code generator.我正在尝试使用带有 HAL-Library 和 cubemx 代码生成器的 Stm32H743ZI MCU 从PAC1710 传感器读取数据。

I can send the first part of my message but I don't get an acknowledge after sending the address.我可以发送消息的第一部分,但在发送地址后我没有得到确认。 I am using a 2700 Ohm resistor to ground on the ADDR_SEL Pin, ALERT goes to ground over an 10 kOhm resistor.我在 ADDR_SEL 引脚上使用 2700 Ohm 电阻接地,ALERT 通过 10 kOhm 电阻接地。

As for my code, this is my intializiation:至于我的代码,这是我的初始化:

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();
  }
}

My implementation is very simplistic:我的实现非常简单:

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

and in the main loop I have the following code:在主循环中,我有以下代码:

        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);

I chose 254 because I though the slave should be able to answer to that regardless of his measurement.我选择 254 是因为我认为奴隶应该能够回答这个问题而不管他的尺寸如何。 However I don't even get as far as sending the register, after looking into it with an oscilloscope I send the address and get a NACK.但是,我什至没有发送寄存器,在用示波器查看之后,我发送了地址并获得了 NACK。

Is there anything obvious I am missing?有什么明显的我遗漏了吗?

After some comments, there was more useful info, biggest part being that oscilloscope showed Start 1010100 0 1 Stop .经过一些评论,有更多有用的信息,最大的部分是示波器显示Start 1010100 0 1 Stop While 1010100 is the 0x54 address, the W bit needs to be counted as well, so the 8-bit data was actually 10101000 , instead of the expected 01010100 .虽然1010100是 0x54 地址,但W位也需要计算在内,因此 8 位数据实际上是10101000 ,而不是预期的01010100 Address should not have been shifted left, as it was already correct.地址应该被左移,因为它已经是正确的。

This is a somewhat common mistake with I2C.这是 I2C 的一个常见错误。 Attention needs to be paid to the exact address and R/!W bits, as in some documents and APIs they're shifted left, in some they aren't.需要注意确切的地址和R/!W位,因为在某些文档和 API 中,它们向左移动,而在某些文档和 API 中则不是。

A very helpful bit of info here was the oscilloscope trace, that really helped show what exactly is going on.这里的一个非常有用的信息是示波器跟踪,它确实有助于显示究竟发生了什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM