我一直在使用ATmega128,现在我正在寻找ATmega2560。我已经在128试过了ADC。当我在2560年尝试它时,我没有问题,除非我改变它。我在codevision中编写了这段代码。当仅使用单个通道时,它工作正常但在更换通道时存在不稳定的行为。有什么问题?
这里是代码
void ADC_init(void)
{
PINF=0;
PORTF=0;
PINK=0;
PORTK=0;
ADMUX = 0b01000000;
ADCSRA =0x87; //ADEN=1,ADIE=0
ADCSRB=0x00;
}
void ADC1_read(void)// current - ADC1
{
ADMUX=0x41;
ADCSRA|=0x40; //ASSC=1 (ad_start)
ADCSRB=0x00;
while((ADCSRA&(1<<ADSC))); //while((ADCSRA&0x10)==0);
ADCSRA |= (1<<ADIF);
cur_l=ADCL;
cur_h=ADCH;
cur_buf=cur_h;//0x03;
cur_buf=(cur_buf<<8)|cur_l;
cur_vol = (unsigned long)(((unsigned long)cur_buf*500)/1023);
}
void ADC3_read(void) //temp sensor - ADC3
{
unsigned long temp_volt;
ADMUX = 0xC3;
ADCSRA|=0x40; //ASSC=1 (ad_start)
ADCSRB=0x00;
while((ADCSRA&0x10)==0);
ADCSRA |= (1<<ADIF);
temp_l=ADCL;
temp_h=ADCH;
temp_buf=temp_h;//0x03;
temp_buf<<=8;
temp_buf|=temp_l;
temp_volt = (unsigned long)(((unsigned long)temp_buf*256)/1023);
temp_analog = (unsigned long)(((unsigned long)temp_buf*256)/1023)-50;
}
Main内部的过程函数是这样的:
void process(void)
{
static unsigned char tick_2sec=0, tick_3sec=0;
unsigned char rx2;
if (tick_1sec){
tick_2sec++;
tick_3sec++;
tick_1sec = 0;
}
if (tick_2sec == 2){
tick_2sec = 0;
if (t2 == 1){
t2 = 0;
ADC3_read(); //temp
}
}
if (tick_3sec == 3){
tick_3sec = 0;
if (t3 == 1){
t3 = 0;
ADC1_read(); //current
}
}
}
我使用温度传感器TMP36输入ADC3,在20 C时,输出电压约为0.7 V.当只有ADC 3使用2.56 V参考电压时,从ADCH和ADCL获取的值为0x118。同样,我将ADC1连接到正常情况下输出2.48伏的电压源。当我只使用参考电压为5伏的ADC1时,ADCH和ADCL的输出为509.随着电压的变化,ADCH和ADCL寄存器也相应地改变。当我调用函数以2秒和3秒的间隔读取ADC1和ADC3时,如代码所示,在相同电压下,ADCH和ADCL内容与上面不同。 ADC3具有ADCH,L为137-140,ADC1具有ADCH,L为340-352。
答案 0 :(得分:1)
过去从不同的ADC引脚读取时,我遇到过类似的问题。事实证明,最后一次读数影响了目前的读数。当前值向上或向下倾斜的方向偏向最后读数。
我当时解决了我的问题,从同一个引脚读取两次,只使用第二个。
我已经了解到问题可能来自电路中的电容。一些残余电荷从先前的电压停留在电路中,这影响下一次读数的电压。我怀疑为正在读取的设备添加电容可能会克服这个问题,但我从来没有机会测试它。
答案 1 :(得分:0)
与任何此类ADC一样,AVR ADC使用&#34;采样和保持&#34;输入配置。 &#34; Hold&#34;功能是使用电容器实现的。 当你从一个频道切换到另一个频道时,这个&#34; Hold&#34;电容需要时间来适应新的价值。 此时间取决于您的硬件/软件配置(增益设置,输入源阻抗等)。 这就是为什么读取值两次解决你的问题,一些额外的时间给予&#34; Hold&#34;电容器以达到新值。 选择通道然后等待一下应该会得到相同的结果。