samedi 22 août 2015

Амперметр переменного тока на ATmega8

Всем доброго времени суток!
Уважаемые форумчане, требуется Ваша помощь! Пытаюсь сделать амперметр переменного тока в корпусе на DIN-рейку (2 места) на ATmega8 и трансформаторе тока ASM-030. Высокая точность не нужна, хотя хотелось бы, чтобы отсчет показаний начинался с 0,5А, правда по даташиту на ТТ равномерная характеристика начинается примерно с 1 Ампера. Для этих целей в схеме стоит ОУ AD8541AS, чтобы усилить напряжение с ТТ, и фиксировать значения менее 1 А (хотя оно будет сильно нелинейное). В Протеусе симуляция идет прекрасно, в изделии - непонятные показания в пределах 40-70 ампер хаотически меняющиеся, причем независимо от тока нагрузки. Опорное напряжение для АЦП - AVCC. Делитель на резисторах на входе, чтобы получить половину AVCC. Бит ADLAR установлен в 1. АЦП измеряет среднее, а не среднеквадратичное напряжение.
Именно с битом ADLAR и опорным напряжением я окончательно запутался, а от них собственно и зависит код программы.
Вот фрагмент кода, написанный в CVAVR для АЦП, частота МК - 4МГц.

#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (1<<ADLAR)) // опорное напр. AVCC и сдвигаем результат преобразования влево

void sampleADC() // работа АЦП
{
static unsigned long int indication; // переменная значения измеренного напряжения
static unsigned int adc_count; // внутренный счётчик количества измерений
static unsigned long int value;
static unsigned char I; // счетчик обновления индикатора
static unsigned long int M;

ADMUX = ADC_VREF_TYPE | (0x02); // вход PINC.2
delay_us(10);

ADCSRA |= (1<<ADSC); // запуск АЦП
while(!(ADCSRA & (1<<ADIF))); // ждём окончания конвертирования
ADCSRA |=(1<<ADIF); // сбрасываем флаг записью 1

adc_count++; // увеличиваем счетчик счётчик количества измерений на 1

value = value + ADCW; // накапливаем и записываем показания в value

if (adc_count==480) // если произведено 480 измерений ( ~100мс )
{


indication = (value/adc_count)%10000; // симуляция в Протеусе с усилителем AD8541


Iporog = indication%1000; // записываем в Uporog значение в Амперах

I++; // увеличиваем счетчик обновления индикатора

if (I>=10) // если счетчик досчитал до 10 ( ~1с )
{
if (Iporog>=100) // если показания меньше 10 Ампер
{
count3 = indication%1000/100; // 1-й разряд - десятки Ампер
count2 = indication%100/10; // 2-Й разряд - единицы Ампер
count1 = indication%10/1; // 3-й разряд - десятые доли Ампера
}
else
{
count3 = 10; // 1-й разряд - гасим разряд
count2 = indication%100/10; // 2-Й разряд - единицы Ампер
count1 = indication%10/1; // 3-й разряд - десятые доли Ампера
};


I=0; // обнуляем счетчик обновления индикатора
};
};

if (adc_count>480) // если произведено более 480 измерений ( ~100мс )
{
value = 0; // обнуляем переменную максимального значения напряжения
adc_count = 0; // обнуляем счётчик количества измерений
};
}

Инициализация АЦП:
ADMUX=ADC_VREF_TYPE; // опорное напр. AVCC и сдвигаем результат преобразования влево
ADCSRA = (1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64 (частота АЦП 62,500 kHz)
|(1 << ADEN) // разрешение работы АЦП
|(1 << ADFR); // непрерывный режим работы АЦП

while (1)
{
sampleADC(); // работа АЦП
}


Подскажите, в чем может быть проблема. Может обвязку входа АЦП неправильно сделал? Хотя перед этим перебрал много всяких вариантов обвязки и программу работы АЦП - результат один - в изделии отказывается работать.

Вот схема в Протеусе:

Изображения
Тип файла: jpg 11.jpg (624.7 Кб)


Амперметр переменного тока на ATmega8

Aucun commentaire:

Enregistrer un commentaire