1. 单通道电压采集与串口显示

单通道电压采集与串口显示 学习卡片

任务说明

本案例实现基于MCU内部ADC模块的单通道电压采集,并将采集到的原始值与换算后的实际电压值通过串口输出。目标为:完成ADC初始化、启动一次转换、读取结果、换算电压并发送至串口调试助手。硬件上使用MCU内部ADC通道(PA1),参考电压为3.3V,ADC分辨率为12位。

硬件连接

  • 电位器(或可调电压源)输出端接PA1引脚
  • 电位器两端分别接3.3V与GND
  • MCU的USART1(PA9-TX, PA10-RX)连接USB转串口模块

代码实现


#include "stm32f1xx_hal.h"

ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART1_UART_Init(void);

uint32_t adc_value;
float voltage;
char msg[64];

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_USART1_UART_Init();

    while (1)
    {
        HAL_ADC_Start(&hadc1);
        if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
        {
            adc_value = HAL_ADC_GetValue(&hadc1);
            voltage = (float)adc_value * 3.3f / 4095.0f;
            sprintf(msg, "ADC=%lu, Voltage=%.2fV\r\n", adc_value, voltage);
            HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 100);
        }
        HAL_Delay(500);
    }
}

static void MX_ADC1_Init(void)
{
    hadc1.Instance = 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;
    HAL_ADC_Init(&hadc1);
}

static void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    HAL_UART_Init(&huart1);
}

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_ADC1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

关键配置说明

  • ADC1通道1(PA1),12位分辨率,软件触发单次转换
  • 电压换算公式:Voltage = ADC_Value × 3.3 / 4095
  • 串口波特率115200,8数据位,无校验
  • 转换周期约10μs,轮询等待超时100ms

验证方法

  1. 将代码编译后下载至STM32F103系列开发板
  2. 调节电位器旋钮,改变PA1输入电压
  3. 打开串口调试助手(波特率115200),观察输出
  4. 判定标准:串口持续输出ADC=xxx, Voltage=x.xxV格式数据;调节电位器时ADC值与电压值同步变化;电压值范围在0.00V~3.30V之间,且与万用表实测误差不超过±0.05V
预期输出示例(当输入电压为1.65V时):
ADC=2048, Voltage=1.65V

ADC采集时序

初始化 启动转换 等待完成 读取+发送 t0 t1 t2 t3 循环(500ms间隔) ADC+UART配置 HAL_ADC_Start() PollForConversion GetValue+发送

注意事项

  • PA1引脚必须配置为模拟输入模式,否则ADC读数异常
  • 若使用其他STM32系列,需根据实际参考电压调整换算公式中的基准值
  • 电位器分压时,确保输入电压不超过VDDA(3.3V)
  • 串口助手需选择与代码一致的波特率,否则显示乱码