STM32F030寄存器级ADC单转换扫描模式配置故障排查
STM32F030 ADC单扫描模式:首次转换正常后续报错的排查与修复
核心问题分析
首次转换触发EOSEQ但后续报错,大概率是EOSEQ标志未正确清除,或是初始化时的序列配置、校准步骤存在疏漏。STM32F030的ADC在序列转换完成后会置位EOSEQ,若不手动清除,下次启动转换时会触发错误状态。
关键配置要点(寄存器级)
1. 时钟与基础初始化
确保ADC时钟不超过14MHz,且正确开启ADC时钟:
// 开启ADC时钟(APB2总线) RCC->APB2ENR |= RCC_APB2ENR_ADCEN; // 配置ADC时钟分频(APB2=48MHz,分频4得到12MHz,符合规格) RCC->CFGR |= RCC_CFGR_ADCPRE_DIV4;
2. ADC校准(必须步骤)
ADC开启后必须执行校准,否则转换结果会异常:
// 开启ADC ADC1->CR2 |= ADC_CR2_ADON; // 启动校准 ADC1->CR2 |= ADC_CR2_CAL; // 等待校准完成 while(ADC1->CR2 & ADC_CR2_CAL);
3. 序列与扫描模式配置
- 扫描模式:置位ADC_CR1的SCAN位
- 序列长度:ADC_SQR1的L位设为
通道数-1(2个通道则L=1) - 通道序列:在ADC_SQR3中配置SQ1、SQ2为目标通道
- 单转换模式:ADC_CR2的CONT位设为0,确保一次启动完成所有序列转换后停止
// 启用扫描模式 ADC1->CR1 |= ADC_CR1_SCAN; // 配置序列长度为2个通道(L[3:0] = 1) ADC1->SQR1 &= ~ADC_SQR1_L; ADC1->SQR1 |= (1 << ADC_SQR1_L_Pos); // 配置序列通道:SQ1=通道0,SQ2=通道1(可根据需求替换通道号) ADC1->SQR3 &= ~(ADC_SQR3_SQ1 | ADC_SQR3_SQ2); ADC1->SQR3 |= (0 << ADC_SQR3_SQ1_Pos) | (1 << ADC_SQR3_SQ2_Pos); // 单转换模式(CONT=0) ADC1->CR2 &= ~ADC_CR2_CONT; // 配置软件触发(直接通过SWSTART位启动,无需外部触发配置) ADC1->CR2 &= ~(ADC_CR2_EXTSEL | ADC_CR2_EXTEN);
4. 转换流程与标志清除
每次启动转换后,需等待序列完成(EOSEQ置位),读取所有通道结果后手动清除EOSEQ标志,否则下次转换会报错:
uint16_t adc_results[2]; // 启动转换 ADC1->CR2 |= ADC_CR2_SWSTART; // 等待序列转换完成(EOSEQ置位) while(!(ADC1->SR & ADC_SR_EOSEQ)); // 读取结果:按序列顺序读取,读DR会自动清除EOC标志 adc_results[0] = ADC1->DR; adc_results[1] = ADC1->DR; // 手动清除EOSEQ标志(写0清除) ADC1->SR &= ~ADC_SR_EOSEQ;
常见错误排查
- EOSEQ未清除:这是后续转换报错的最常见原因,每次序列转换完成后必须清除该标志
- 序列长度配置错误:若L位设为0(对应1个通道),第二个通道不会被转换,可能触发异常
- 校准缺失:跳过校准步骤会导致ADC转换结果异常,甚至触发错误
- CONT位误设为1:CONT=1会进入连续转换模式,与单转换扫描需求冲突,导致序列重复触发
- 时钟超标:ADC时钟超过14MHz会导致转换不稳定,触发错误
内容的提问来源于stack exchange,提问作者Andrea
相关产品推荐
相关产品推荐

