c
#include "adc.h"
// 定义全局变量
ADC_HandleTypeDef hadc2; // ADC2外设句柄
uint16_t ADC_Value = 0; // 存储ADC转换结果
float Voltage = 0.0; // 存储计算后的电压值
/**
* @brief ADC2初始化函数
* @note 配置ADC2的基本参数和通道参数
* @retval None
*/
void MX_ADC2_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0}; // ADC通道配置结构体
/* 配置ADC2基本参数 */
hadc2.Instance = ADC2; // 选择ADC2外设
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE; // 禁用扫描模式(单通道)
hadc2.Init.ContinuousConvMode = ENABLE; // 启用连续转换模式
hadc2.Init.DiscontinuousConvMode = DISABLE; // 禁用间断转换模式
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 使用软件触发转换
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
hadc2.Init.NbrOfConversion = 1; // 1个转换在规则序列中
HAL_ADC_Init(&hadc2); // 初始化ADC2
/* 配置ADC2通道参数 */
sConfig.Channel = ADC_CHANNEL_0; // 选择通道0 (PA0)
sConfig.Rank = ADC_REGULAR_RANK_1; // 规则组第1个转换
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; // 采样时间为239.5个周期
HAL_ADC_ConfigChannel(&hadc2, &sConfig); // 配置ADC通道
/* 执行ADC校准 */
HAL_ADCEx_Calibration_Start(&hadc2);
}
/**
* @brief 获取ADC转换值
* @note 启动ADC转换并等待转换完成,返回转换结果
* @retval ADC转换值(12位分辨率)
*/
uint16_t Get_ADC_Value(void)
{
HAL_ADC_Start(&hadc2); // 启动ADC转换
// 等待转换完成,超时时间100ms
HAL_ADC_PollForConversion(&hadc2, 100);
// 判断转换是否完成(检查EOC标志位)
if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc2), HAL_ADC_STATE_REG_EOC))
{
return HAL_ADC_GetValue(&hadc2); // 返回转换结果
}
return 0; // 转换失败返回0
}
/**
* @brief 获取平均电压值
* @param times: 采样次数
* @note 多次采样取平均值以提高精度,并转换为电压值
* @retval 计算后的电压值(单位:伏特)
*/
float Get_Average_Voltage(uint8_t times)
{
uint32_t temp_val = 0; // 临时累加值
uint8_t t; // 循环计数器
// 多次采样累加
for (t = 0; t < times; t++)
{
temp_val += Get_ADC_Value(); // 获取ADC值并累加
HAL_Delay(5); // 每次采样间隔5ms
}
// 计算平均ADC值
temp_val = temp_val / times;
// 将ADC值转换为电压值(假设参考电压为3.3V,12位分辨率)
return (float)temp_val * (3.3 / 4096);
}
/**
* @brief ADC MSP初始化
* @param adcHandle: ADC句柄指针
* @note 此函数由HAL_ADC_Init()调用,用于底层硬件初始化
* 包括: 1. 使能外设时钟
* 2. 配置GPIO
* 3. 配置中断
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 判断是否为ADC2外设
if (adcHandle->Instance == ADC2)
{
/* 1. 使能ADC2时钟 */
__HAL_RCC_ADC2_CLK_ENABLE();
/* 2. 配置ADC通道对应的GPIO */
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
GPIO_InitStruct.Pin = GPIO_PIN_0; // 选择PA0引脚
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // 模拟输入模式
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIO
/* 3. 配置ADC中断 */
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0); // 设置中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); // 使能ADC中断
}
}
/**
* @brief ADC MSP反初始化
* @param adcHandle: ADC句柄指针
* @note 此函数由HAL_ADC_DeInit()调用,用于底层硬件反初始化
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef *adcHandle)
{
// 判断是否为ADC2外设
if (adcHandle->Instance == ADC2)
{
/* 1. 禁用ADC2时钟 */
__HAL_RCC_ADC2_CLK_DISABLE();
/* 2. 反初始化GPIO */
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0); // 反初始化PA0引脚
/* 3. 禁用ADC中断 */
HAL_NVIC_DisableIRQ(ADC1_2_IRQn); // 禁用ADC中断
}
}