You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NUCLEO-F767ZI串口仅输出Hello World,无ADC采集数据输出求助

问题排查与修复方案

核心问题分析

串口仅输出"Hello World",后续ADC数据和"Measurement done"无输出,主要由以下几个关键问题导致:

1. 时间循环逻辑错误

HAL_GetTick()返回的是毫秒级时间戳,代码中HAL_GetTick() - start_time < 5000000的判断是让循环执行5000秒(约83分钟),而非注释中所说的5秒。程序会一直卡在这个循环里,永远到不了后续的输出代码。

2. ADC未完成初始化

init_adc()函数为空,全局变量hadc仅声明但未配置任何参数(如ADC实例、通道、分辨率、时钟等)。调用HAL_ADC_Start(&hadc)时,HAL库会因ADC未初始化而进入阻塞或错误状态,直接导致循环内的代码无法正常执行。

3. GPIO未初始化

init_gpio()函数为空,ADC对应的模拟输入引脚未配置为正确的模式,即使ADC初始化完成,也无法采集到有效数据。

4. 错误状态未检查

所有HAL库函数(如HAL_ADC_Start、HAL_ADC_PollForConversion)都有返回值,代码未对这些返回值进行判断,无法定位初始化或操作过程中的错误。


修复后的代码示例

以下是补全关键部分后的代码,针对NUCLEO-F767ZI的ADC1通道1(对应引脚PA1)进行配置:

#include <stdio.h>
#include <stdlib.h>
#include "stm32f7xx_hal.h"

/* Define your UART handle */
UART_HandleTypeDef huart3;
ADC_HandleTypeDef hadc;

void Error_Handler(void) { while (1); }

void SystemClock_Config(void) {
  // 基于NUCLEO-F767ZI生成的系统时钟配置
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 180;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
    Error_Handler();
  }
}

/* Initialize UART */
void init_uart(void) {
    huart3.Instance = USART3;
    huart3.Init.BaudRate = 9600;
    huart3.Init.WordLength = UART_WORDLENGTH_8B;
    huart3.Init.StopBits = UART_STOPBITS_1;
    huart3.Init.Parity = UART_PARITY_NONE;
    huart3.Init.Mode = UART_MODE_TX_RX;
    huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart3.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart3) != HAL_OK) {
        Error_Handler();
    }
}

/* Custom implementation of _write for printf redirection */
int _write(int file, char *ptr, int len) {
    HAL_UART_Transmit(&huart3, (uint8_t*)ptr, len, HAL_MAX_DELAY);
    return len;
}

/* Initialize ADC GPIO (PA1 for ADC1 Channel 1) */
void init_gpio(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    // Configure PA1 as analog input
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void init_adc(void) {
    ADC_ChannelConfTypeDef sConfig = {0};

    __HAL_RCC_ADC1_CLK_ENABLE();

    hadc.Instance = ADC1;
    hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc.Init.Resolution = ADC_RESOLUTION_12B;
    hadc.Init.ScanConvMode = DISABLE;
    hadc.Init.ContinuousConvMode = DISABLE;
    hadc.Init.DiscontinuousConvMode = DISABLE;
    hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc.Init.NbrOfConversion = 1;
    hadc.Init.DMAContinuousRequests = DISABLE;
    hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    if (HAL_ADC_Init(&hadc) != HAL_OK) {
        Error_Handler();
    }

    // Configure ADC Channel 1
    sConfig.Channel = ADC_CHANNEL_1;
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
        Error_Handler();
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    init_uart();
    init_gpio();
    init_adc();

    uint32_t start_time = 0;
    float input_voltage = 0.0f;

    while (1) {
        printf("Hello World\r\n");

        start_time = HAL_GetTick();

        // 修正为5秒(5000毫秒)
        while (HAL_GetTick() - start_time < 5000)
        {
            if (HAL_ADC_Start(&hadc) != HAL_OK) {
                Error_Handler();
            }
            if (HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY) != HAL_OK) {
                Error_Handler();
            }

            uint32_t adc_value = HAL_ADC_GetValue(&hadc);
            input_voltage = (float)adc_value / 4095.0f * 3.3f;

            HAL_ADC_Stop(&hadc);

            printf("Time: %lu ms, Input Voltage: %.2f V\r\n", HAL_GetTick() - start_time, input_voltage);

            HAL_Delay(100); // 调整为100ms间隔,避免串口输出过于频繁
        }

        printf("Measurement done\r\n");
        HAL_Delay(1000); // 测量结束后暂停1秒,便于观察
    }
}

额外注意事项

  • 确保STM32CubeIDE中已正确开启USART3、ADC1及对应GPIO的时钟(代码中已通过__HAL_RCC_xxx_CLK_ENABLE()开启,也可配合STM32CubeMX生成基础配置代码,减少手动配置错误)。
  • PuTTY终端需设置正确的换行模式(建议选择CR+LF),避免输出换行异常。
  • 如果仍有问题,可通过调试模式查看hadc.State的值,判断ADC是否处于正常状态。

内容的提问来源于stack exchange,提问作者Annie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:35:02