跳到主要内容

STM32 HAL ADC

介绍

ADC(Analog-to-Digital Converter,模数转换器)是嵌入式系统中非常重要的外设之一,用于将模拟信号(如电压)转换为数字信号,以便微控制器进行处理。STM32 系列微控制器内置了高性能的 ADC 模块,支持多通道、高分辨率的模数转换。

在 STM32 HAL 库中,ADC 的配置和操作被封装成易于使用的函数,使得开发者可以快速上手。本文将详细介绍如何使用 STM32 HAL 库进行 ADC 的配置、启动和读取数据。

ADC 的基本概念

什么是 ADC?

ADC 是一种将连续的模拟信号转换为离散的数字信号的设备。在 STM32 中,ADC 可以将引脚上的电压值转换为数字值,通常以 12 位分辨率表示(即 0 到 4095)。

ADC 的主要参数

  • 分辨率:ADC 的分辨率决定了转换结果的精度。STM32 的 ADC 通常支持 12 位分辨率,即 4096 个不同的值。
  • 采样时间:采样时间是指 ADC 对输入信号进行采样的时间。较长的采样时间可以提高精度,但会降低转换速度。
  • 参考电压:ADC 的参考电压决定了输入电压的范围。STM32 的 ADC 通常使用 VREF+ 和 VREF- 作为参考电压。

STM32 HAL 库中的 ADC 配置

1. 初始化 ADC

在使用 ADC 之前,需要先对其进行初始化。STM32 HAL 库提供了 HAL_ADC_Init() 函数来初始化 ADC 外设。以下是一个简单的初始化示例:

c
ADC_HandleTypeDef hadc;

void ADC_Init(void) {
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.NbrOfConversion = 1;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;

if (HAL_ADC_Init(&hadc) != HAL_OK) {
// 初始化错误处理
}
}

2. 配置 ADC 通道

在初始化 ADC 后,需要配置要使用的 ADC 通道。STM32 的 ADC 支持多通道配置,每个通道对应一个 GPIO 引脚。以下是一个配置单通道的示例:

c
void ADC_Channel_Config(void) {
ADC_ChannelConfTypeDef sConfig = {0};

sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;

if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
// 通道配置错误处理
}
}

3. 启动 ADC 转换

配置完成后,可以通过 HAL_ADC_Start() 函数启动 ADC 转换。以下是一个启动 ADC 转换并读取结果的示例:

c
uint32_t ADC_Read(void) {
HAL_ADC_Start(&hadc); // 启动 ADC 转换
HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY); // 等待转换完成
uint32_t adc_value = HAL_ADC_GetValue(&hadc); // 读取转换结果
HAL_ADC_Stop(&hadc); // 停止 ADC 转换
return adc_value;
}

实际案例:读取电位器电压

假设我们有一个连接到 STM32 的电位器,我们希望读取其电压值并将其显示在串口终端上。以下是实现该功能的完整代码:

c
#include "stm32f4xx_hal.h"

ADC_HandleTypeDef hadc;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC_Init(void);

int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();

while (1) {
uint32_t adc_value = ADC_Read();
float voltage = (adc_value * 3.3) / 4095; // 将 ADC 值转换为电压值
printf("ADC Value: %lu, Voltage: %.2f V\n", adc_value, voltage);
HAL_Delay(1000);
}
}

void ADC_Init(void) {
// ADC 初始化代码
}

void ADC_Channel_Config(void) {
// ADC 通道配置代码
}

uint32_t ADC_Read(void) {
// ADC 读取代码
}
提示

在实际应用中,ADC 的参考电压通常是 3.3V。因此,将 ADC 值转换为电压值时,可以使用公式:电压 = (ADC 值 * 3.3) / 4095

总结

通过本文,我们学习了如何使用 STM32 HAL 库进行 ADC 的配置和操作。我们从 ADC 的基本概念入手,逐步讲解了 ADC 的初始化、通道配置和读取数据的过程,并通过一个实际案例展示了如何读取电位器的电压值。

希望本文能帮助你更好地理解 STM32 的 ADC 功能,并为你的项目开发提供帮助。

附加资源与练习

  • 练习 1:尝试配置多个 ADC 通道,并同时读取多个模拟信号。
  • 练习 2:使用 DMA(直接内存访问)来提高 ADC 的采样效率。
  • 参考文档:STM32 HAL 库用户手册、STM32 参考手册。
警告

在实际开发中,务必注意 ADC 的参考电压和输入电压范围,避免损坏 ADC 模块。