一、ADC单通道采样函数
1. MX_ADC1_Init()
**函数原型:**通常为
void MX_ADC1_Init(void)
**功能:**ADC硬件基础初始化函数,由STM32CubeMX自动生成。配置ADC的时钟、分辨率、扫描模式、连续转换模式、数据对齐方式、采样时间等底层参数。
特点:
无参数,无返回值
必须在其他ADC操作之前调用
内部通常调用HAL_ADC_Init()函数
2. HAL_ADCEx_Calibration_Start()
函数原型:
HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc)
参数:
hadc:ADC句柄指针
**功能:**执行ADC自动校准,减小偏移误差,提高转换精度。校准过程会花费一定时间,期间不应进行其他ADC操作。
3. HAL_ADC_Start()
函数原型:
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
参数:
hadc:ADC句柄指针
**功能:**启动ADC转换过程。支持三种模式:
轮询模式:配合HAL_ADC_PollForConversion()使用
中断模式:转换完成时触发中断
DMA模式:自动传输多个转换结果
4. HAL_ADC_PollForConversion()
函数原型:
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
参数:
hadc:ADC句柄指针
Timeout:超时时间(毫秒)
返回值:
HAL_OK:转换完成
HAL_TIMEOUT:超时
HAL_ERROR:错误
**功能:**在轮询模式下等待ADC转换完成。会阻塞程序直到转换完成或超时。
5. HAL_ADC_GetValue()
函数原型:
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
参数:
hadc:ADC句柄指针
**返回值:**ADC转换结果值
12位分辨率:0-4095
10位分辨率:0-1023
8位分辨率:0-255
**功能:**读取ADC转换结果寄存器中的值。
二、示例实验
1. 实验现象
该程序会每隔500ms采集一次ADC1的模拟信号,将其转换为数字值,然后计算对应的电压值(参考电压为3.3V,ADC为12位分辨率,所以数字范围0-4095对应0-3.3V)。计算得到的电压值会通过串口以浮点数形式打印,保留三位小数。因此,在串口调试助手等工具上,会看到每隔约0.5秒打印一个电压值,该电压值随输入模拟信号的变化而变化。
2. 示例代码
ADC初始化
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0}; // 定义ADC通道配置结构体并初始化为0
/** ADC通用配置 */
hadc1.Instance = ADC1; // 设置ADC实例为ADC1
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // 禁用扫描模式(单通道)
hadc1.Init.ContinuousConvMode = DISABLE; // 禁用连续转换模式(单次转换)
hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁用间断模式
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 使用软件触发转换
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
hadc1.Init.NbrOfConversion = 1; // 转换序列数为1
// 初始化ADC,如果失败则调用错误处理函数
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** 配置规则通道 */
sConfig.Channel = ADC_CHANNEL_6; // 设置ADC通道6
sConfig.Rank = ADC_REGULAR_RANK_1; // 设置通道在规则组中的排名为第1个
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; // 设置采样时间为1.5个ADC时钟周期
// 配置ADC通道,如果失败则调用错误处理函数
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
主函数
uint16_t adc_get = 0; // 存储ADC原始转换值的变量
float vol = 0.0f; // 存储计算得到的电压值的变量
// 系统时钟配置函数声明
void SystemClock_Config(void);
/**
* @brief 应用程序主函数
* @retval int
*/
int main(void)
{
// HAL库初始化
HAL_Init();
// 系统时钟配置
SystemClock_Config();
// 初始化所有配置的外设
MX_GPIO_Init(); // GPIO初始化
MX_ADC1_Init(); // ADC1初始化
MX_USART1_UART_Init(); // USART1串口初始化
HAL_ADCEx_Calibration_Start(&hadc1); // 执行ADC校准
// 主循环
while (1)
{
// 启动ADC转换
HAL_ADC_Start(&hadc1);
// 等待转换完成,超时时间50ms
if (HAL_ADC_PollForConversion(&hadc1, 50) == HAL_OK)
{
// 获取ADC转换结果(12位,0-4095)
adc_get = HAL_ADC_GetValue(&hadc1);
// 将ADC值转换为电压值(假设参考电压3.3V)
vol = (float)adc_get / 4095 * 3.3f;
// 通过串口打印电压值,保留3位小数
printf("%.3f\r\n", vol);
}
// 延时500ms
HAL_Delay(500);
}
}