stm32f103c8t6 adc读取电压
时间: 2025-04-12 10:33:35 浏览: 85
<think>好的,我现在需要帮助用户了解如何使用STM32F103C8T6的ADC模块读取电压。用户要求示例代码或教程,所以我要详细解释步骤,并确保代码正确。
首先,用户提到的参考电压连接是VREF+和VDDA相连,VREF-和VSSA相连,这意味着ADC的参考电压是3.3V。因此,ADC的数值0对应0V,4095对应3.3V。这需要确认在代码中正确配置ADC的参数,比如设置正确的对齐方式和时钟分频。
接下来,我需要考虑STM32的ADC初始化过程。通常步骤包括启用GPIO和ADC时钟,配置GPIO引脚为模拟输入模式,设置ADC的参数如分辨率、扫描模式、连续转换模式等,然后校准ADC。这些步骤必须正确无误,否则ADC无法正常工作。
然后是关于示例代码的结构。用户可能需要使用HAL库,因为这是ST官方推荐的库,简化了开发流程。代码部分应包括初始化函数、ADC配置、启动转换和读取结果。需要注意的是,DMA或中断方式可以提高效率,但对于初学者,轮询方式可能更容易理解。
另外,用户可能会遇到一些常见问题,比如电压读数不稳定,可能需要添加滤波处理,如多次采样取平均。同时,需要确保硬件连接正确,比如被测电压不能超过3.3V,否则可能损坏芯片。
最后,生成相关问题时,要考虑用户可能进一步的需求,比如多通道ADC读取、提高精度的方法或其他ADC模式的使用。这些问题有助于用户深入学习和解决问题。</think>### 使用STM32F103C8T6的ADC读取电压值
#### 1. 硬件原理
STM32F103C8T6的ADC模块为12位精度,最大量化值为$0$~$4095$,对应电压范围为$0$~$3.3\mathrm{V}$(当VREF+接VDDA时)[^1]。以测量PA1引脚电压为例:
$$ V_{in} = \frac{\mathrm{ADC\_Value}}{4095} \times 3.3\mathrm{V} $$
#### 2. 代码实现步骤(基于HAL库)
```c
#include "stm32f1xx_hal.h"
ADC_HandleTypeDef hadc1;
void ADC_Init(void) {
// 1. 启用GPIO和ADC时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
// 2. 配置GPIO为模拟输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 3. 配置ADC参数
hadc1.Instance = ADC1;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
HAL_ADC_Init(&hadc1);
// 4. 配置通道参数
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 5. 校准ADC
HAL_ADCEx_Calibration_Start(&hadc1);
}
uint16_t Read_Voltage(void) {
HAL_ADC_Start(&hadc1); // 启动转换
HAL_ADC_PollForConversion(&hadc1, 10); // 等待转换完成
return HAL_ADC_GetValue(&hadc1); // 返回12位ADC值
}
```
#### 3. 关键配置说明
- **采样时间**:71.5周期适合中速信号(如温度传感器)
- **参考电压**:需确保VDDA和VREF+稳定在3.3V
- **滤波建议**:通过多次采样取平均提高精度
```c
#define SAMPLE_TIMES 32 // 采样次数
float Get_Average_Voltage(void) {
uint32_t sum = 0;
for(int i=0; i<SAMPLE_TIMES; i++){
sum += Read_Voltage();
}
return (sum * 3.3f) / (SAMPLE_TIMES * 4095.0f);
}
```
阅读全文
相关推荐


















