CODE
void adc_init(void)
{
//настройка АЦП
ADCSRA|=(1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
ADMUX|=(1<<REFS0)|(0<<REFS1);
}
uint16_t make_single_adc_cycle(unsigned char port_number)
{
switch(port_number)
{
case 0:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
break;
case 1:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0);
break;
case 2:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(0<<MUX0);
break;
case 3:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(1<<MUX0);
break;
case 4:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(0<<MUX0);
break;
case 5:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
break;
case 6:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(1<<MUX1)|(0<<MUX0);
break;
case 7:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0);
break;
default:
return 0;
break;
}
ADCSRA|=(1<<ADSC);
while(!(ADCSRA & (1<<ADIF)));
ADCSRA|=(1<<ADIF);
return ADC;
}
int main (void)
{
volatile uint16_t result[4];
//...
//здесь заполняю массив данными для отправки через uart
for(unsigned char i=4; i<8; i++)
{
result[i-4]=make_single_adc_cycle(i);
}
sData[5]=result[0]>>8;
sData[6]=result[0];
sData[7]=result[1]>>8;
sData[8]=result[1];
sData[9]=result[2]>>8;
sData[10]=result[2];
sData[11]=result[3]>>8;
sData[12]=result[3];
//...
{
//настройка АЦП
ADCSRA|=(1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
ADMUX|=(1<<REFS0)|(0<<REFS1);
}
uint16_t make_single_adc_cycle(unsigned char port_number)
{
switch(port_number)
{
case 0:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
break;
case 1:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0);
break;
case 2:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(0<<MUX0);
break;
case 3:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(1<<MUX0);
break;
case 4:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(0<<MUX0);
break;
case 5:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
break;
case 6:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(1<<MUX1)|(0<<MUX0);
break;
case 7:
ADMUX|=(0<<MUX4)|(0<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0);
break;
default:
return 0;
break;
}
ADCSRA|=(1<<ADSC);
while(!(ADCSRA & (1<<ADIF)));
ADCSRA|=(1<<ADIF);
return ADC;
}
int main (void)
{
volatile uint16_t result[4];
//...
//здесь заполняю массив данными для отправки через uart
for(unsigned char i=4; i<8; i++)
{
result[i-4]=make_single_adc_cycle(i);
}
sData[5]=result[0]>>8;
sData[6]=result[0];
sData[7]=result[1]>>8;
sData[8]=result[1];
sData[9]=result[2]>>8;
sData[10]=result[2];
sData[11]=result[3]>>8;
sData[12]=result[3];
//...
Проблема в следующем: когда на ноге PA4 отсутствует напряжение (я могу включать и выключать его через PA0-PA3), а на остальных ногах (PA5-PA7) присутствует, то я не получаю нулевой результат измерения АЦП на PA4. По uart мне приходят данные, что на этой ноге еденица (мультиметр показывает ноль). Нулевого результата измерения получается добиться только один раз после сброса питания мк, после этого глюк возвращается. Аналогично в ситуации наоборот, когда на PA4 - единица, на PA5-7 - нули, то АЦП говорит, что на PA4 тоже ноль. И еще несколько комбинаций с подобным результатом.
Если проводить измерения одной ноги, а остальные вообще не трогать, то ничего подобного нет.
Напряжние на этих ногах 2,2В, к ним подключены фильтрующие кондеры 0,1 мкФ (не рядом с мк). АЦП работает от AVcc (4,98В), также подключен кондер 0,1 мкФ (уже рядом с мк), но без дросселя, как даташите Атмел. Частота кварца 7,3728 МГц.