请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C031 评测】ADC采样测试

[复制链接]
落花又见流水 发布时间:2024-3-30 17:00

STM32C031拥有12 位 ADC 是逐次趋近型模数转换器。它具有多达 23 个复用通道,可测量来自 19 个外部源和 4 个内部源的信号。各种不同通道的 A/D 转换可在单次、连续、扫描或不连续采样模式下进行。 ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限。采用了高效的低功耗模式,在低频下可实现极低的功耗。内置硬件过采样器,可提高模拟性能,同时还能减轻 CPU 进行相关计算的负担。

下面是ADC外设的特性:

image.png

下面就来测试一下ADC采样吧。首先打卡STM32CubeMX配置ADC外设功能。

选了外部2路采样端口PA0和PA1,以及内部电压通道和温度传感器通道。

image.png

接下来配置ADC初始化参数。

image.png

使能ADC采样中断。

image.png

好了,接下来生成代码。然后添加代码读取ADC采样值。

下面是ADC的生成初始化代码了。

/**
  * @brief ADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** 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_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 4;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_79CYCLES_5;
  hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_12CYCLES_5;
  hadc1.Init.OversamplingMode = DISABLE;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_VREFINT;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

接下来重写ADC采样完成的中断回调函数。其中ADC_FLAG_EOC表示每个通道转换完成中断标志。ADC_FLAG_EOS表示一个序列组内所有通道采样转换完成标志。

//adc回调
uint32_t adc_value[4];
volatile uint32_t adc_index = 0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC))
    {
        adc_value[adc_index++] = HAL_ADC_GetValue(hadc);
    }
    if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
    {
        adc_index  = 0;
        printf("%u\t %u\t",adc_value[0],adc_value[1]);
        printf("%u\t %u\r\n",adc_value[2],adc_value[3]);
    }
}

下面我使用了串口SHELL方式命令控制转换和定时启动转换。

void shell_adc(char argc, char *argv)
{
    uint16_t    ps;
    uint32_t    als;

    printf("Start ADC...\r\n");
    HAL_ADC_Start_IT(&hadc1); //中断方式启动ADC1转换。
}
NR_SHELL_CMD_EXPORT(adc, shell_adc, "Start ADC.");
//主循环中调用触发采样。并在OLED上显示
    if(timeout_1 == 0)
    {
        timeout_1 = 100;    //100MS
        HAL_ADC_Start_IT(&hadc1); //中断方式启动ADC1转换。

        sprintf(buff,"A0:%d",adc_value[0]);
        ssd1306_SetCursor(0,0);
        ssd1306_WriteString(buff, Font_11x18, White);

        sprintf(buff,"A1:%d",adc_value[1]);
        ssd1306_SetCursor(0,24);
        ssd1306_WriteString(buff, Font_11x18, White);
        ssd1306_UpdateScreen();
    }

image.png

然后编译下载程序测试。

image.png

效果如下,看到ADC采样的数据很稳定,跳动的幅度很小。image.png

image.png

image.png

image.png
收藏 评论1 发布时间:2024-3-30 17:00

举报

1个回答
背影101 回答时间:2024-4-7 12:22:30

大佬

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版