[STM32C0] 【STM32C092RC 测评】+09 使用内部ADC数据的采集功能

[复制链接]
2089|2
 楼主| 聪聪哥哥 发表于 2025-5-23 20:20 | 显示全部楼层 |阅读模式
本帖最后由 聪聪哥哥 于 2025-5-23 20:24 编辑

使用ADC实现位移传感器的采集功能
内置的12位模数转换器嵌入到STM32C091xB/xC和STM32C092xB/xC设备中。该ADC最多有19个外部通道和2个内部通道。通道(温度传感器、电压参考)。LT在单次测量或扫描模式下执行转换。在扫描模式下,对选定的一组模拟输入执行自动转换。
ADC的频率独立于CPU的频率,即使在CPU速度较低的情况下,也可以达到2.5MSps的最大采样率。自动关机功能可确保除在活动转换阶段外ADC处于关机状态。
ADC可以由DMA控制器提供服务。它可以在整个VDD供电范围内运行。
模拟看门狗功能允许对一个、某些或所有扫描通道的转换电压进行非常精确的监控。当转换电压超出预定义的阈值时,将生成中断。
通用定时器(TIMx)产生的事件可以在内部连接到ADC开始触发器,使应用程序能够将A/D转换与定时器同步。

一:温度传感器
温度传感器
温度传感器(TS)产生一个随温度线性变化的电压VTS。
温度传感器与ADC输入端内部连接,将传感器输出电压转换为数字值。
该传感器具有良好的线性度,但必须进行校准才能获得良好的温度测量整体准确性。由于工艺变化,温度传感器的偏移可能会因部件而异,因此未校准的内部温度传感器仅适用于相对温度测量。
为了提高温度传感器的准确性,每个部分都单独由ST进行工厂校准,校准数据被存储在部分的工程字节中,在只读模式下可访问。

二:内部电压参考(VREFINT)
内部电压参考(VREFINT)为ADC提供稳定的(带隙)电压输出。VREFINT内部连接到ADC输入。VREFINT电压在生产测试期间由ST为每个部件单独精确测量,并存储在部件的工程字节中。它可以在只读模式下访问。三:STM32cube MX 软件配置
1.png 2.png 3.png

四:软件代码如下:
  1. static void MX_ADC1_Init(void)
  2. {

  3.   /* USER CODE BEGIN ADC1_Init 0 */

  4.   /* USER CODE END ADC1_Init 0 */

  5.   ADC_ChannelConfTypeDef sConfig = {0};

  6.   /* USER CODE BEGIN ADC1_Init 1 */

  7.   /* USER CODE END ADC1_Init 1 */

  8.   /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  9.   */
  10.   hadc1.Instance = ADC1;
  11.   hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  12.   hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  13.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  14.   hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  15.   hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  16.   hadc1.Init.LowPowerAutoWait = DISABLE;
  17.   hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  18.   hadc1.Init.ContinuousConvMode = DISABLE;
  19.   hadc1.Init.NbrOfConversion = 3;
  20.   hadc1.Init.DiscontinuousConvMode = ENABLE;
  21.   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  22.   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  23.   hadc1.Init.DMAContinuousRequests = ENABLE;
  24.   hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  25.   hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_79CYCLES_5;
  26.   hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
  27.   hadc1.Init.OversamplingMode = DISABLE;
  28.   hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  29.   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  30.   {
  31.     Error_Handler();
  32.   }

  33.   /** Configure Regular Channel
  34.   */
  35.   sConfig.Channel = ADC_CHANNEL_4;
  36.   sConfig.Rank = ADC_REGULAR_RANK_1;
  37.   sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  38.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  39.   {
  40.     Error_Handler();
  41.   }

  42.   /** Configure Regular Channel
  43.   */
  44.   sConfig.Channel = ADC_CHANNEL_VREFINT;
  45.   sConfig.Rank = ADC_REGULAR_RANK_2;
  46.   sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
  47.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  48.   {
  49.     Error_Handler();
  50.   }

  51.   /** Configure Regular Channel
  52.   */
  53.   sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  54.   sConfig.Rank = ADC_REGULAR_RANK_3;
  55.   sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  56.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  57.   {
  58.     Error_Handler();
  59.   }
  60.   /* USER CODE BEGIN ADC1_Init 2 */

  61.   /* USER CODE END ADC1_Init 2 */

  62. }
在主程序下添加如下代码:
  1.     /* Start ADC group regular conversion */
  2.     if (HAL_ADC_Start(&hadc1) != HAL_OK)
  3.     {
  4.       /* Error: ADC conversion start could not be performed */
  5.       Error_Handler();
  6.     }

  1.     if(ubDmaTransferStatus == 1)
  2.     {
  3.       /* For this example purpose, calculate analog reference voltage (Vref+) */
  4.       /* from ADC conversion of internal voltage reference VrefInt.           */
  5.       /* This voltage should correspond to value of literal "VDDA_APPLI".     */
  6.       /* Note: This calculation can be performed when value of voltage Vref+  */
  7.       /*       is unknown in the application                                  */
  8.       /*       (This is not the case in this example due to target board      */
  9.       /*       supplied by a LDO regulator providing a known constant voltage */
  10.       /*       of value "VDDA_APPLI").                                        */
  11.       /*       In typical case of Vref+ connected to Vdd, it allows to        */
  12.       /*       deduce Vdd value.                                              */
  13.       uhADCxConvertedData_VrefAnalog_mVolt = __LL_ADC_CALC_VREFANALOG_VOLTAGE(uhADCxConvertedData[1], LL_ADC_RESOLUTION_12B);

  14.       /* Computation of ADC conversions raw data to physical values           */
  15.       /* using LL ADC driver helper macro.                                    */
  16.       uhADCxConvertedData_VoltageGPIO_mVolt        = __LL_ADC_CALC_DATA_TO_VOLTAGE(uhADCxConvertedData_VrefAnalog_mVolt, uhADCxConvertedData[0], LL_ADC_RESOLUTION_12B);
  17.       uhADCxConvertedData_VrefInt_mVolt            = __LL_ADC_CALC_DATA_TO_VOLTAGE(uhADCxConvertedData_VrefAnalog_mVolt, uhADCxConvertedData[1], LL_ADC_RESOLUTION_12B);
  18.       hADCxConvertedData_Temperature_DegreeCelsius = __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(INTERNAL_TEMPSENSOR_AVGSLOPE,INTERNAL_TEMPSENSOR_V30,INTERNAL_TEMPSENSOR_V30_TEMP,VDDA_APPLI,uhADCxConvertedData[2],LL_ADC_RESOLUTION_12B);
  19.       /* Update status variable of DMA transfer */
  20.       ubDmaTransferStatus = 0;

  21.       /* Toggle LED 4 times */
  22.       tmp_index = 4*2;
  23.       while(tmp_index != 0)
  24.       {
  25.         BSP_LED_Toggle(LED1);
  26.         HAL_Delay(LED_BLINK_FAST);
  27.         tmp_index--;
  28.       }
  29.       HAL_Delay(500); /* Delay to highlight toggle sequence */
  30.     }
实测图如下:
4.png
suncat0504 发表于 2025-5-26 20:22 | 显示全部楼层
这个ADC采样处理结果的一致性怎么样?
 楼主| 聪聪哥哥 发表于 2025-5-27 11:29 | 显示全部楼层
suncat0504 发表于 2025-5-26 20:22
这个ADC采样处理结果的一致性怎么样?

基本上不飘动,等等在细研究
您需要登录后才可以回帖 登录 | 注册

本版积分规则

108

主题

307

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部