| 本帖最后由 YangTwo 于 2024-11-9 17:33 编辑 
 ADC简介
 STM32WB09系列的ADC有16中工作模式组合:
 • External signals through ADC_VINPx and ADC_VINMx, where x=0,1,2 or 3
 – Up to 4 differential inputs
 – Up to 8 single-ended inputs one single ended input to interface with a temperature sensor in a range up to 1.2 V
 • one single ended input connected to VBAT for battery level detector in a range up to 3.6 V
 • two single ended inputs connected to GND for calibration
 • two single ended inputs connected to 1.2 V for calibration
 • one single ended input connected to Temperature Sensor
 
 
 
   本次体验自带的温度传感器与一路外部模拟输入模式。其中外部输入采集到是DFROBOT的模拟声音传感器。
 模拟声音传感器简介
 MIC声音传感器是一款基于麦克风为声音检测的传感器,可用来对周围环境中的声音强度进行检测,具有300倍的放大器,输出模拟信号能使用3.3V和5V为基准AD采集,可以用来实现根据声音大小进行互动的效果、制作声控机器人、声控开关、声控报警等。产品参数引脚说明 传感器电路图:
 
   
 
 与STM32WB09连接实物图:
 
   
 
 在CubeMX里面配置ADC参数与DMA传输。
 
   
 
   
 
 本次不少STM32的芯片都自带了可以测量芯片内部结温的温度传感器,精度不是很高,通常±5V的误差都是标配。
 
   自动生成代码,查看ADC初始化:
 
 static void MX_ADC1_Init(void)
{
  /* USER CODE BEGIN ADC1_Init 0 */
  /* USER CODE END ADC1_Init 0 */
  ADC_ChannelConfTypeDef ConfigChannel = {0};
  /* USER CODE BEGIN ADC1_Init 1 */
  /* USER CODE END ADC1_Init 1 */
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ConversionType = ADC_CONVERSION_WITH_DS;
  hadc1.Init.SequenceLength = 2;
  hadc1.Init.SamplingMode = ADC_SAMPLING_AT_START;
  hadc1.Init.SampleRate = ADC_SAMPLE_RATE_16;
  hadc1.Init.InvertOutputMode = ADC_DATA_INVERT_NONE;
  hadc1.Init.Overrun = ADC_NEW_DATA_IS_LOST;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DownSamplerConfig.DataWidth = ADC_DS_DATA_WIDTH_12_BIT;
  hadc1.Init.DownSamplerConfig.DataRatio = ADC_DS_RATIO_1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  ConfigChannel.Channel = ADC_CHANNEL_TEMPSENSOR;
  ConfigChannel.Rank = ADC_RANK_1;
  ConfigChannel.VoltRange = ADC_VIN_RANGE_1V2;
  ConfigChannel.CalibrationPoint.Number = ADC_CALIB_POINT_1;
  ConfigChannel.CalibrationPoint.Gain = 0x0;
  ConfigChannel.CalibrationPoint.Offset = 0x0;
  if (HAL_ADC_ConfigChannel(&hadc1, &ConfigChannel) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  ConfigChannel.Channel = ADC_CHANNEL_VINP0;
  ConfigChannel.Rank = ADC_RANK_2;
  ConfigChannel.CalibrationPoint.Number = ADC_CALIB_NONE;
  ConfigChannel.CalibrationPoint.Gain = 0x00;
  ConfigChannel.CalibrationPoint.Offset = 0x00;
  if (HAL_ADC_ConfigChannel(&hadc1, &ConfigChannel) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
  /* USER CODE END ADC1_Init 2 */
}
主函数:
 
 int main(void)
{
  /* USER CODE BEGIN 1 */
  uint32_t tmp_index;
  /* Initialize ADC group regular data buffer values */
  for (tmp_index = 0; tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index++)
  {
    uhADCxConvertedData[tmp_index] = VAR_CONVERTED_DATA_INIT_VALUE;
  }
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* Configure the peripherals common clocks */
  PeriphCommonClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  /* Initialize LED on board */
  BSP_LED_Init(LD1);
  /* Start ADC group regular conversion */
  /* Note: First start with DMA transfer initialization, following ones
           with basic ADC start. */
  if (HAL_ADC_Start_DMA(&hadc1,
                        (uint32_t *)uhADCxConvertedData,
                        ADC_CONVERTED_DATA_BUFFER_SIZE
                       ) != HAL_OK)
  {
    /* Error: ADC conversion start could not be performed */
    Error_Handler();
  }
  /* Toggle LED at each ADC conversion */
  BSP_LED_On(LD1);
  HAL_Delay(LED_BLINK_SLOW);
  BSP_LED_Off(LD1);
  HAL_Delay(LED_BLINK_SLOW);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* Start ADC group regular conversion */
    if (HAL_ADC_Start(&hadc1) != HAL_OK)
    {
      /* Error: ADC conversion start could not be performed */
      Error_Handler();
    }
    /* Toggle LED at each ADC conversion */
    BSP_LED_On(LD1);
    HAL_Delay(LED_BLINK_SLOW);
    BSP_LED_Off(LD1);
    HAL_Delay(LED_BLINK_SLOW);
    
    /* Note: ADC group regular conversions data are stored into array         */
    /*       "uhADCxConvertedData"                                            */
    /*       (for debug: see variable content into watch window).             */
    /*       - uhADCxConvertedData[0]: ADC channel set on sequence rank 1     */
    /*                                 (ADC1 internal channel temper. sensor) */
    /*       - uhADCxConvertedData[1]: ADC channel set on sequence rank 2     */
    /*                                 (ADC1 channel 4))        */
    /* If ADC conversions and DMA transfer are completed, then process data */
    if(ubDmaTransferStatus == 1)
    {
      /* Computation of ADC conversions raw data to physical values           */
      /* using LL ADC driver helper macro.                                    */
      
      uhADCxConvertedData_VoltageGPIO_mVolt        = __LL_ADC_CALC_DATA_TO_VOLTAGE(LL_ADC_VIN_RANGE_3V6, uhADCxConvertedData[1], LL_ADC_DS_DATA_WIDTH_12_BIT);
      hADCxConvertedData_Temperature_DegreeCelsius = __LL_ADC_CALC_TEMPERATURE( uhADCxConvertedData[0], LL_ADC_DS_DATA_WIDTH_12_BIT);
      printf("\r\n Internal Temp Sensor:  %d Celsius", hADCxConvertedData_Temperature_DegreeCelsius);
      printf("\r\n External Voice Sensor: %d mVolt", uhADCxConvertedData_VoltageGPIO_mVolt);
      /* Update status variable of DMA transfer */
      ubDmaTransferStatus = 0;
      /* Toggle LED 4 times */
      tmp_index = 4*2;
      while(tmp_index != 0)
      {
        BSP_LED_Toggle(LD1);
        HAL_Delay(LED_BLINK_FAST);
        tmp_index--;
      }
      HAL_Delay(500); /* Delay to highlight toggle sequence */
    }
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
 串口输出:
 
   
 
 在有音乐播放的时候,采集到的电压值会变化:
 
   
 
 不过总感觉内部温度传感器采集到温度才2℃,有点不太符合通常25°左右的测量值,目前正常排查潜在的配置问题。
 
 
 |