STM32 通过 I2C 发送 12 位 ADC

Posted

技术标签:

【中文标题】STM32 通过 I2C 发送 12 位 ADC【英文标题】:STM32 Sending 12bit ADC over I2C 【发布时间】:2018-06-20 09:48:46 【问题描述】:

如何理解通过 I2C 发送的 STM32F4 数据?我正在将此 I2C 流从一个 STM32F4 发送到另一个 STM32F4。

我收到了预期的 ACK,但数据本身看起来有点不寻常。

我有一个由 DMA 管理的 12 位 ADC。这是设置代码:

  volatile uint32_t ADCValue[2];
 if(HAL_ADC_Start(&hadc1) != HAL_OK)
        HAL_GPIO_WritePin(GPIOC, LED3_Pin, SET);
 if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCValue,4) != HAL_OK)
        HAL_GPIO_WritePin(GPIOC, LED4_Pin, SET);
 while(1)
 while(HAL_I2C_Master_Transmit(&hi2c3, 252, (uint8_t*) ADCValue[1], 4, 10000) != HAL_OK)

还有,这是 ADC 设置

ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;

/* ADC1 init function */
void MX_ADC1_Init(void)

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_8B;
  hadc1.Init.ScanConvMode = ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 2;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  
    _Error_Handler(__FILE__, __LINE__);
  

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
    */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  
    _Error_Handler(__FILE__, __LINE__);
  

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
    */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = 2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  
    _Error_Handler(__FILE__, __LINE__);
  


所以,很自然,我认为我在这里做的最愚蠢的事情是尝试将单个 ADCValue 元素分解为 4 个 8 位值,因为它被定义为 32 位 int...

地址字节后有 4 个字节,但我不确定我对 DMA 和强制转换类型所做的这件事是否存在根本缺陷。

任何 C 专家都了解如何使用 HAL 库通过 I2C 发送 32 位值?

【问题讨论】:

【参考方案1】:

我认为您正在向 I2C 发送无效指针:

 while(HAL_I2C_Master_Transmit(&hi2c3, 252, (uint8_t*) ADCValue[1], 4, 10000) != HAL_OK)

我不明白你想通过 I2C 发送什么,这意味着 ADCValue[1] 的值是一个指向要传输的数据的指针,也许你应该改变:

 while(HAL_I2C_Master_Transmit(&hi2c3, 252, (uint8_t*) ADCValue, 4, 10000) != HAL_OK)

如果你想发送ADCValue的值,或者如果你想移位1个字节:

 while(HAL_I2C_Master_Transmit(&hi2c3, 252, &((uint8_t*) ADCValue)[1], 4, 10000) != HAL_OK)

在这种情况下,如果你在 uin32 数组和 uint8 数组之间进行联合会更容易。

【讨论】:

指针让我感到困惑...谢谢,我会试试看 您确定此代码受到保护以防止良性竞争吗? 什么意思? 假设 I2C 开始传输,当发送 2 个字节时,ADC 结束转换并更新值,然后 I2C 传输另外 2 个字节。传输的值是旧值的一半,新值的一半。 有很多解决方案,如果 I2C 传输比 ADC 转换更快,您可以使用 2 个变量和一个指向最后一个值的指针。转换结束时,将指针更改为当前值,使用另一个变量开始新的转换。 I2C 始终使用指向最后一个值的指针。

以上是关于STM32 通过 I2C 发送 12 位 ADC的主要内容,如果未能解决你的问题,请参考以下文章

STM32中i2c数据发不出去

STM32 ADC详解

请教stm32的i2c接收问题

STM32部分开发板的对比

stm32 ADC采样速率的问题

如何使用stm32adc