Arduino Uno使用ADC寄存器替代analogRead测量电容结果错误求助
寄存器版本代码问题排查与修复
核心问题点
- 参考电压配置错误
原analogRead默认使用AVcc(5V)作为参考电压,你寄存器配置中ADMUX |= B10000000对应REFS1=1、REFS0=0,属于ATmega328P保留配置,实际参考电压远低于5V。阈值972对应5V参考下的约4.74V,在低参考电压下对应的实际充电电压极低,自然充电时间大幅缩短,电容计算结果偏小。 - ADC转换未完成就读取结果
你设置ADSC位触发转换后,没有等待转换完成就直接读取ADCL/ADCH寄存器,拿到的是无效的旧值或未完成转换的错误值,进一步导致采样逻辑异常。 - PD5引脚拉低逻辑错误
放电阶段的PORTD &= B00000100会清空PORTD除第2位外的所有引脚电平,仅关闭PD5的正确写法是PORTD &= ~(1 << 5),错误的电平操作也会影响充放电逻辑。
修正后的寄存器版本代码
unsigned long starttime = 0; unsigned long endtime = 0; double C = 0; float n = 3.0; //时间常数 float resistor = n*998000.0; int value = 0; void setup() { Serial.begin(9600); // 设置PD5为输出,不影响其他引脚方向 DDRD |= B00100000; PORTD &= ~B00100000; sei(); ADMUX &= B00000000; //清空所有位 ADMUX |= B01000000; // REFS1=0、REFS0=1,使用AVcc作为参考电压,和默认analogRead配置一致,选择A0通道 ADCSRA |= B10000110; // 开启ADC,预分频64,ADC时钟250KHz } void loop() { // 启动充电 PORTD |= (1<<5); starttime = micros(); do{ ADCSRA |= (1 << ADSC); // 触发ADC转换 while(ADCSRA & (1 << ADSC)); // 等待转换完成 value = ADCL | (ADCH << 8); // 先读ADCL再读ADCH,读取转换结果 Serial.println(value); }while(value<972); endtime = (micros() - starttime); C = ((double)endtime/resistor); Serial.println(C, 9); // 启动放电,仅拉低PD5 PORTD &= ~(1 << 5); do{ ADCSRA |= (1 << ADSC); while(ADCSRA & (1 << ADSC)); value = ADCL | (ADCH << 8); }while(value > 0); }
验证说明
修正后参考电压和官方analogRead完全一致,每次ADC采样都等待转换完成拿到正确值,充放电引脚操作逻辑正确,采样速率会比官方analogRead快3~5倍,电容测量结果和原代码一致。
内容的提问来源于stack exchange,提问作者BeneKunz
相关产品推荐
相关产品推荐

