HAL_ADC_Start()
是一个用于启动 ADC(模数转换器)转换的函数,那为什么有时候我们会看到它被放在 while
循环里呢?其实取决于你使用的是哪种ADC采样方式,我们来细说👇:
🧠 一、先搞清楚你是哪种采样方式
STM32 HAL 提供的 ADC 工作方式主要有这几种:
模式 | 是否自动连续转换? | 是否需要每次手动 HAL_ADC_Start() ? |
---|---|---|
1. 单次转换(Single Conversion) | ❌ 否 | ✅ 是,必须每次调用 |
2. 连续转换(Continuous Conversion) | ✅ 是 | ❌ 否,只需启动一次 |
3. 扫描+DMA(Scan + DMA) | ✅ 是 | ❌ 否,只需启动一次 |
4. 触发模式(Timer触发、EXTI触发等) | ❌ 或 ✅ | 取决于触发机制 |
🧪 二、HAL_ADC_Start()
放在 while
里的意义
✅ 如果你写的是这种代码:
while (1)
{HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);uint32_t adc_value = HAL_ADC_GetValue(&hadc1);HAL_Delay(100);
}
这表示你是每次循环手动触发一次ADC采样,即处于 “单次转换模式”,每一次 HAL_ADC_Start()
都会启动一次新的采样。
这种方式适合你:
-
不需要太快的采样速率
-
想手动控制采样频率(如每100ms采一次)
❌ 如果你已经开启了连续转换模式:
ADC_InitStruct.ContinuousConvMode = ENABLE;
那你只需要在 main()
里调用一次 HAL_ADC_Start()
:
HAL_ADC_Start(&hadc1);while (1)
{if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK){adc_val = HAL_ADC_GetValue(&hadc1);}
}
就不需要每次循环都调用 HAL_ADC_Start()
了。
🛠️ 三、实战建议
👉 如果你看到别人把 HAL_ADC_Start()
写进 while
里,说明:
-
他们用的是“手动单次触发”模式;
-
这样可以节省功耗;
-
也能避免 ADC 占满总线或 DMA 通道。
✅ 总结一句话:
把
HAL_ADC_Start()
放在while
里,通常是因为你在用 单次转换模式,每次都要手动启动一次采样。如果你用的是 连续转换 或 DMA 模式,就不需要反复调用它了。
你用的是哪种采样方式?我可以直接帮你写一段对应方式的初始化和采样代码~