Nucleo F401RE ADC双通道切换异常问题求助
Nucleo F401RE ADC通道切换异常问题排查与解决
问题描述
在Nucleo F401RE开发板上配置双ADC通道:通道8(Rank1)读取热敏电阻,通道1(Rank2)读取电位器。按键切换通道时仅能从通道8切换到通道1,反向切换无效。尝试交换Rank值、设置相同Rank、禁用其他通道均未解决,禁用通道后设置Rank=2时还会读到来源不明的热敏电阻数值(约1310)。
核心问题分析
- 初始化配置错误:Rank2的通道未正确设置为
ADC_CHANNEL_1,导致初始序列两个Rank均对应通道8 - 模式不匹配:ADC配置为扫描模式(
ScanConvMode = ENABLE)且转换数量为2,但切换通道时未同步修改转换数量和序列,实际扫描序列与预期不符 - 切换逻辑不完整:通道切换函数未完全清理旧的序列配置,残留Rank导致转换结果异常
分步解决方案
1. 修复ADC初始化配置
修改初始化代码,确保Rank2对应正确的通道:
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_8; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_1; // 明确设置Rank2的通道 sConfig.Rank = 2; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); }
2. 调整通道切换逻辑(推荐单通道模式)
如果切换仅需读取单个通道,修改change_channel函数,将ADC切换为单通道模式:
void change_channel(uint32_t channel) { ADC_ChannelConfTypeDef sConfig = {0}; ADC_InitTypeDef ADC_InitStruct = hadc1.Init; // 修改为单通道转换配置 ADC_InitStruct.ScanConvMode = DISABLE; ADC_InitStruct.NbrOfConversion = 1; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } // 配置目标通道为Rank1 sConfig.Channel = channel; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } global_channel = channel; global_rank = 1; }
同步修改任务中的调用:
if(mod1==0)//自动模式 { change_channel(ADC_CHANNEL_8); // ... 转换读取逻辑 } if(mod1==1)//手动模式 { change_channel(ADC_CHANNEL_1); // ... 转换读取逻辑 }
3. 优化转换读取逻辑
确保配置前停止ADC,避免残留状态影响结果:
if(mod1==0)//自动模式 { HAL_ADC_Stop(&hadc1); // 先停止ADC change_channel(ADC_CHANNEL_8); HAL_ADC_Start(&hadc1); if(HAL_ADC_PollForConversion(&hadc1, 1000) == HAL_OK) { readValue = HAL_ADC_GetValue(&hadc1); voltage = (float)readValue / 4095.0f * 3.3f; globalvoltage = voltage; globalreadValue = readValue; } HAL_ADC_Stop(&hadc1); osMessageQueuePut(queque_voltageHandle, &voltage, 0, 0); osDelay(100); } if(mod1==1)//手动模式 { HAL_ADC_Stop(&hadc1); // 先停止ADC change_channel(ADC_CHANNEL_1); HAL_ADC_Start(&hadc1); if(HAL_ADC_PollForConversion(&hadc1, 1000) == HAL_OK) { readValue = HAL_ADC_GetValue(&hadc1); voltage = (float)readValue / 4095.0f * 3.3f; globalvoltage = voltage; globalreadValue = readValue; } HAL_ADC_Stop(&hadc1); osMessageQueuePut(queque_voltageHandle, &voltage, 0, 0); osDelay(100); }
4. 解决不明数值问题
之前出现的1310数值是初始化时Rank2通道配置错误导致的残留转换值,修复初始化和切换逻辑后该问题会自动消失。
内容的提问来源于stack exchange,提问作者liviu
相关产品推荐
相关产品推荐

