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
相关产品推荐
相关产品推荐

