STM32C542开发(7)----ADC电压采集

STM32C542开发.7--ADC电压采集

概述

本章介绍如何使用 STM32C5 的 ADC1 实现模拟电压采集。ADC配置为 12位分辨率,采用 Regular Group 和软件触发方式,通过 HAL2 的轮询模式启动转换、等待转换完成并读取采样数据。

实验中将上一讲 PA4(DAC1_OUT1)输出的 1.65 V 电压连接至 PA1(ADC1_IN1),ADC读取原始采样值后,根据参考电压将数字量换算为实际电压。

需要样片的可以加群申请:925643491 / 615061293 。

视频教学

https://www.bilibili.com/video/BV1DNby6UExC/

样品申请

https://www.wjx.top/vm/OhcKxJk.aspx#

源码下载

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。

主控为STM32C542CCT6

参考程序

https://github.com/CoreMaker-lab/STM32C542_SENSOR

https://gitee.com/CoreMaker/STM32C542_SENSOR

ADC配置

打开 STM32CubeMX2,进入 ADC 外设配置界面,配置步骤如下。

  1. 进入 Peripherals 外设配置页面。
  2. 在 Analog 分类中选择 ADC1。
  3. 点击 Active 使能 ADC1 外设。
  4. ADC 分辨率设置为 12 bit,Sampling mode 选择 Normal;使能 ADC1_IN1 通道,采样时间设置为 289 ADC clock cycles,输入模式选择 Single-ended。
    本实验使用 Regular Group 进行普通 ADC 转换,触发方式选择 Software start,Continuous mode 设置为 Single,即每次由软件启动一次 ADC 转换。STM32C5 HAL2 支持软件触发 Regular Group,并可通过轮询方式获取转换结果。

继续向下配置 System 参数。

ADC1 Channel 1 的输入信号 ADC1_IN1 选择 PA1 引脚,GPIO 工作模式设置为 Analog,并选择 No pull-up and no pull-down。STM32C5 的 PA1 支持 ADC1_IN1 模拟输入功能,可用于采集外部模拟电压。

生成项目

  1. 修改配置后,左下角会提示 Click to save,需要先保存当前工程配置
  2. 点击左侧 Project settings,进入工程生成设置页面
  3. 在 IDE Project Generation 中选择工程格式和工具链,本例选择 CMake + GCC,然后点击 Generate IDE project 生成工程

导入STM32CubeIDE

  1. 打开 STM32CubeIDE,点击菜单栏 File
  2. 选择 Import...,准备导入 STM32CubeMX2 生成的 CMake 工程
  1. 在 Import 窗口中展开 Import STM32 Project
  2. 选择 STM32 CMake Project
  3. 点击 Next,进入 CMake 工程路径选择页面
  1. Project name:填写导入到 STM32CubeIDE 中显示的工程名称
  2. Source directory:选择 STM32CubeMX2 生成的 CMake 工程目录
  3. 点击 Next,继续完成工程导入
  1. Toolchain:选择 MCU ARM GCC,表示使用 ARM GCC 工具链进行编译
  2. MCU:确认芯片型号为 STM32C542CCTx,与前面 STM32CubeMX2 中选择的 MCU 保持一致
  3. CPU/Core:确认内核为 Cortex-M33,Core 为 0
  4. 点击 Finish,完成 CMake 工程导入

设置工程编码

  1. 在 Project Explorer 中选中当前工程
  2. 点击菜单栏 Project
  3. 选择 Properties,进入工程属性设置
  1. 在工程属性中选择 Resource
  2. Text file encoding 选择 Other
  3. 编码格式输入 GBK
  4. 点击 Apply and Close 保存设置

宏定义

该宏定义用于表示 12 位 ADC/DAC 的最大数字量。

c 复制代码
/* 12-bit ADC/DAC maximum digital value */
#define ADC_DAC_MAX_VALUE   4095U
c 复制代码
	    uint32_t adc_value = 0;
	    uint32_t adc_voltage_mv = 0;


	    /* Get ADC1 handle */
	    hal_adc_handle_t *hadc1 = mx_adc1_gethandle();

	    if (hadc1 == NULL)
	    {
	        return (-1);
	    }

	    /*
	     * Configure ADC1 Channel 1.
	     *
	     * This section can be removed if ADC1_IN1 has already
	     * been added to Regular Sequencer Rank 1 in CubeMX2.
	     */
	    hal_adc_channel_config_t adc_channel_config;

	    adc_channel_config.group          = HAL_ADC_GROUP_REGULAR;
	    adc_channel_config.sequencer_rank = 1;
	    adc_channel_config.sampling_time  = HAL_ADC_SAMPLING_TIME_289CYCLES;
	    adc_channel_config.input_mode     = HAL_ADC_IN_SINGLE_ENDED;

	    if (HAL_ADC_SetConfigChannel(hadc1,
	                                 HAL_ADC_CHANNEL_1,
	                                 &adc_channel_config) != HAL_OK)
	    {
	        return (-1);
	    }

	    /* Activate ADC1 */
	    if (HAL_ADC_Start(hadc1) != HAL_OK)
	    {
	        return (-1);
	    }

	    /* ADC self calibration */
	    if (HAL_ADC_Calibrate(hadc1) != HAL_OK)
	    {
	        return (-1);
	    }
	    printf("\r\nSTM32C542 ADC Voltage Test\r\n");

初始化

该部分代码主要完成 ADC1 的初始化准备和采样通道配置。首先定义变量用于保存 ADC 原始采样值和换算后的电压值,然后通过 mx_adc1_gethandle() 获取 ADC1 句柄,并将 ADC1 Channel 1 配置到 Regular Group 的 Rank 1,采样时间设置为 289 个 ADC 时钟周期,输入模式选择单端输入。配置完成后调用 HAL_ADC_Start() 启动 ADC,并通过 HAL_ADC_Calibrate() 执行 ADC 自校准,为后续 PA1 电压采集做好准备。ST 官方 STM32C5 HAL2 的 ADC Polling 流程同样包含通道配置、ADC 启动和校准步骤。

c 复制代码
	    uint32_t adc_value = 0;
	    uint32_t adc_voltage_mv = 0;


	    /* Get ADC1 handle */
	    hal_adc_handle_t *hadc1 = mx_adc1_gethandle();

	    if (hadc1 == NULL)
	    {
	        return (-1);
	    }

	    /*
	     * Configure ADC1 Channel 1.
	     *
	     * This section can be removed if ADC1_IN1 has already
	     * been added to Regular Sequencer Rank 1 in CubeMX2.
	     */
	    hal_adc_channel_config_t adc_channel_config;

	    adc_channel_config.group          = HAL_ADC_GROUP_REGULAR;
	    adc_channel_config.sequencer_rank = 1;
	    adc_channel_config.sampling_time  = HAL_ADC_SAMPLING_TIME_289CYCLES;
	    adc_channel_config.input_mode     = HAL_ADC_IN_SINGLE_ENDED;

	    if (HAL_ADC_SetConfigChannel(hadc1,
	                                 HAL_ADC_CHANNEL_1,
	                                 &adc_channel_config) != HAL_OK)
	    {
	        return (-1);
	    }

	    /* Activate ADC1 */
	    if (HAL_ADC_Start(hadc1) != HAL_OK)
	    {
	        return (-1);
	    }

	    /* ADC self calibration */
	    if (HAL_ADC_Calibrate(hadc1) != HAL_OK)
	    {
	        return (-1);
	    }
	    printf("\r\nSTM32C542 ADC Voltage Test\r\n");

主程序

这段主循环主要实现 ADC1 的周期性电压采集与串口显示。程序通过 HAL_ADC_REG_StartConv() 启动一次规则组转换,再使用 HAL_ADC_REG_PollForConv() 轮询等待转换完成,随后读取 ADC 原始值,并按照参考电压和 12 位满量程 4095 换算成实际电压值。STM32C5 HAL2 官方文档将 StartConv + PollForConv 作为 ADC Polling 模式的标准使用方式。

c 复制代码
    while (1) {

        /* Start ADC regular conversion */
        if (HAL_ADC_REG_StartConv(hadc1) == HAL_OK)
        {
            /* Wait for conversion complete */
            if (HAL_ADC_REG_PollForConv(hadc1, 100) == HAL_OK)
            {
                /* Read ADC conversion data */
                adc_value =
                    (uint32_t)HAL_ADC_REG_ReadConversionData(hadc1);

                /*
                 * Convert ADC value to voltage.
                 *
                 * Voltage = ADC_Value × VREF / 4095
                 */
                adc_voltage_mv =
                    (adc_value * DAC_VREF_MV) / ADC_DAC_MAX_VALUE;

                printf("ADC Value: %4lu, Voltage: %4lu mV\r\n",
                       (unsigned long)adc_value,
                       (unsigned long)adc_voltage_mv);
            }
            else
            {
                printf("ADC conversion timeout!\r\n");
            }
        }

        HAL_Delay(1000);

    }

测试结果

将 PA4(DAC1_OUT1)与 PA1(ADC1_IN1)连接,ADC 对上一讲 DAC 输出的 1.65 V 电压进行实时采集,串口输出结果如下图所示。

相关推荐
记帖1 天前
STM32C542开发(4)----输出PWM及修改频率与占空比R
stm32cubeide·stm32c5·stm32cubemx2·stm32c542cct6·stm32c542rct6
sramdram3 天前
模数转换器Sigma-Delta ADC前端解决方案
adc·模数转换器·sigma-delta adc
sramdram6 天前
高精度ADC芯片转换原理及ADC芯片架构分类
adc·adc芯片·高精度adc
小僧景贤13 天前
STM32 工程文件深度解析(Keil‑MDK + STM32CubeIDE)
stm32·单片机·stm32cubeide
记帖21 天前
STM32C5开发LSM6DSOW(1)----轮询获取陀螺仪数据
imu·stm32cubeide·mems·stm32c5·stm32cubemx2·stm32c542cct6·lsm6dsow
记帖22 天前
STM32C5开发LSM6DSR(1)----轮询获取陀螺仪数据
imu·stm32cubeide·mems·stm32c5·stm32cubemx2·stm32c542cct6·lsm6dsr
BSD_CGQ24 天前
FSR压力传感器的MCU采集方案与校准算法实现
人工智能·计算机视觉·目标跟踪·adc·压力传感器·fsr·深圳源头厂家
记帖1 个月前
STM32C5A3R开发(1)----点亮LED
stm32cubeide·stm32c5·stm32cubemx2·stm32c5a3rgt6
你是我的解忧王子1 个月前
10进制和16进制 超声波 FFT 变换分析筛选系统误差-ADC采样筛选工具
数据分析·adc·fft·系统误差