为什么不管输入如何,ADC总​​是读取1023

时间:2019-05-10 22:52:17

标签: arduino embedded avr attiny winavr

我正在尝试使用attiny85中的ADC读取模拟电压。但是,无论给出什么输入,ADC寄存器总是读取1023。

此外,当用万用表测量ADC引脚时,其电压接近3.1V。我认为它是上拉的,但事实是,当我将引脚连接到其模拟输入时,引脚上的电压会干扰输入电压电路。我不知道为什么会这样。相同的代码在6个月前运行良好,但现在却没有。原因不明。谁能解释我实际上在做错什么?我使用USBasp作为编程器,使用attiny85作为目标微控制器,使用arduino作为编译器。我也尝试使用WinAVR进行编译,但模拟输入引脚的电压仍然接近3.1V。 在此先感谢:)

#define F_CPU 16000000UL
#define myTx PB1 //PB1
#define myRx PB0 //PB0
#define ADC_CH_2 PB4
#define ADC_CH_3 PB3

#include <SoftwareSerial.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
float ADCval;
int i = 0, p;

SoftwareSerial myPort(myRx, myTx); //rx,tx

ISR(ADC_vect) {

  p = ADCW;
  ADCval = (float)p * 5.00f / 1024.0f;


  //logging the data
  myPort.print(i++);
  myPort.print(" ADC: ");
  myPort.print(p);

  myPort.print(" voltage: ");
  myPort.println(ADCval);

}

int main(void) {
myPort.begin(9600);
MCUCR &= ~(1 << PUD); //disabling Pull Up Disable i.e, enabling pullups

//I/O configuration
DDRB &= ~(1 << ADC_CH_2) & ~(1 << ADC_CH_3); //configuring as input
PORTB |= (1 << ADC_CH_2) | (1 << ADC_CH_3); //  writing 1 to an input pin activates pullup-resistor
DIDR0 |= (1 << ADC_CH_2) | (1 << ADC_CH_3); // disable digital buffer
myPort.print("DDRB: ");
myPort.println(DDRB);

myPort.print("PORTB: ");
myPort.println(PORTB);

//ADC configuration

ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADIE); //enable conversion complete interrupt
ADCSRA |= (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2); // prescaler 128 - 16000000/128=125khz;
myPort.print("ADCSRA: ");
myPort.println(ADCSRA);

ADMUX &= ~(1 << ADLAR); // right most shift in ADCH and ADCL i.e, ADCH has two MSB bits and ADCL has 8 LSB bits



ADMUX |= (1 << REFS1) | (1 << REFS2); ADMUX &= ~(1 << REFS0); //Vref as 2.56V
ADMUX |= (1 << MUX1) | (1 << MUX0) ; ADMUX &= ~(1 << MUX2) & ~(1 << MUX3); //adc3

sei(); // enable all interrupts
myPort.print("ADMUX: ");
myPort.println(ADMUX);

while (1)
{
_delay_ms(1000);
ADCSRA |= 1 << ADSC;
myPort.print("DDRB: ");
myPort.println(DDRB);
myPort.print("ADMUX: ");
myPort.println(ADMUX);
myPort.print("ADCSRA: ");
myPort.println(ADCSRA);
myPort.print("PORTB: ");
myPort.println(PORTB);

}




return 0;
}

更新

下图描述了在相同输入电压下我不同ADC通道的输出。

callbacks

output of ADC channel 2

1 个答案:

答案 0 :(得分:2)

当将ADC配置为2.56V作为参考电压时,所有处于2.56和更高电平的电压将被读取为ADC的最大值,即1023。 3.1 V也是如此。

问题可能出在启用的内部上拉上

PORTB |= (1 << ADC_CH_2) | (1 << ADC_CH_3); //  writing 1 to an input pin activates pullup-resistor

启用的上拉将提供额外的电流并更改输入端的电压。千万不要将内部上拉与ADC一起使用,因为上拉的值在20k ... 50k范围内因部件而异,并且很难预测确切的值。

您应该禁用它:

PORTB &= ~(1 << ADC_CH_2) & ~(1 << ADC_CH_3); //  disable pull-ups

根据需要使用已知值的外部上拉电阻。