три вольтметра на одной меге16
- Сообщения: 884
- Зарегистрирован: Пн июл 08, 2013 22:59:45
помогите сделать одновременно три вольтметра на одном контроллере, причём щупы на разных пинах и напряжения тоже разные
- Реклама
В чем конкретно вопрос? У всех AVR АЦП подключается через мультиплексор. Нужно просто периодически переключать вход между этими тремя щупами.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
- Сообщения: 884
- Зарегистрирован: Пн июл 08, 2013 22:59:45
т.е. в бесконечном цикле в регистре ADMUX менять MUX биты??, а прерывание останется одно?
Да, прерывание одно, каналы разные. Ещё пошерстите даташит на предмет точности первого измерения после переключения канала.
- Сообщения: 884
- Зарегистрирован: Пн июл 08, 2013 22:59:45
хорошо, другой вопрос, а что будет если на вход подать отрицательное напряжение? можно ли такое делать или обязательна защита от подобного?
- Реклама
У них диод защитный стоит анодом на землю. Ничего не будет, все уйдет в землю, но лучше еще внешний добавьте для надежности.
- Сообщения: 884
- Зарегистрирован: Пн июл 08, 2013 22:59:45
защитный добавить?? как я понимаю защитный диод нужен для защиты от перенапряжений, у меня для этих целей будет стабилитрон, а для защиты от обратного напряжения разве не обычный диод нужен??
откройте любой datasheet на любую мегу. Раздел I/O Ports. Первая же картинка. Два диода: один на питание, второй на землю. Первый защищает от превышения напряжения, второй - от переполюсовки.
Не понял, в чём проблема? В Мега16 ВОСЕМЬ каналов АЦП, и можно сделать ВОСЕМЬ вольтметров, правда у них будет один "общий" провод, и восемь "плюсовых"..kelod писал(а): три вольтметра на одном контроллере, причём щупы на разных пинах
А в зависимости от того, на что вы будете выводить индикацию- будете думать, КАК её вывести- например- на светодиодный семисегментный индикатор- просто делаете вывод значений разных входов- на разные разряды, если на ЖК- то в разные знакоместа..
зы.. у меня сын делал первый вариант ДВУХКАНАЛЬНОЙ паяльной станции- тоже на 16 меге- там была индикация установленных значений и индикация действующих значений- всего 4 трёхразрядных числа, и всё это выводилось на ДВА индикатора, сделанных по типу АЛС318
- Сообщения: 884
- Зарегистрирован: Пн июл 08, 2013 22:59:45
АлександрЛ, ну всё правильно 1 общий провод, а плюсы разные, вот у меня и вопрос как использовать одновременно два входа, как я понял одновременно не как, только по очереди переключая ножки или у вас другой вариант есть?? а про индикацию это совсем другая история, не относящаяся к данной теме
- Сообщения: 773
- Зарегистрирован: Пн сен 01, 2014 20:38:54
Я то же как-то задавался подобным вопросом на форуме, и выяснил, что ADC в МК только один, а значит и измерять напряжение можно только на одной ножке. И как понял, если быстро переключать ADC с одной ножки на другую, то качество будет страдать. Как вариант, использовать еще несколько простеньких МК, каждый из которых будет мерить "свое" напряжение, и по некой шине скидывать результаты главному контролеру.
Вы что делаете? Многоканальный осциллограф с "хорошей" скоростью отрисовки как для меги (сигналы до 10кГц)?MisHel64 писал(а):Как вариант, использовать еще несколько простеньких МК, каждый из которых будет мерить "свое" напряжение, и по некой шине скидывать результаты главному контролеру.
Для обычного вольтметра изменение измеренного значения 5 раз в сек на канал за глаза. 4 канала *5 = 20 измерений. Допустим, вы усредняете по 256 точкам. 256 * 20 = 5120 измерений в секунду. 5кГц это что много? Такое ацп меги тянет на раз, хотя ацп и дохленькое.
Переключили мультиплексор и десяток тактов подождали, пока значение на выходе стабилизируется. В чем проблема? Загляните в даташит, там более точно указаны временные интервалы.
- Сообщения: 773
- Зарегистрирован: Пн сен 01, 2014 20:38:54
eess9 Не, ну задачи то разные бывают. Кому-то хватит и того, что есть, а кому-то велосипед, потому, что стандартного не хватает.
По идеи да, переключился на ножку, отрисовал то что ранее считал, послал на новый замер, заснул.
По идеи да, переключился на ножку, отрисовал то что ранее считал, послал на новый замер, заснул.
Почему НИКАК? У вас в Мега16 ВОСЕМЬ АЦП! Они "считают", а вы просто выводите на индикацию значение того АЦП, которое вас в данный момент интересует.. Можно и одновременно выводить- просто тогда поставьте индикатор с нужной разрядностью.. По программе я вам подсказать, к сожалению, не смогу- так и не освоил- когда- то давно писал мелочёвку на бейсике для спектрума и на бейсике для ЕС ЭВМ..Ну, и для РС, конечно, тоже.. - а вот даже бейсик для АВР почему- то "не идёт"...kelod писал(а):АлександрЛ, ну всё правильно 1 общий провод, а плюсы разные, вот у меня и вопрос как использовать одновременно два входа, как я понял одновременно не как,
bascom avr?АлександрЛ писал(а): а вот даже бейсик для АВР почему- то "не идёт"...![]()
Ага.. А сын на нём пишет- нормально.. Я спрашивал про "более продвинутые языки" он сказал, что и на бейсике можно "что угодно написать".. 
- Сообщения: 773
- Зарегистрирован: Пн сен 01, 2014 20:38:54
Кто сказал?АлександрЛ писал(а):У вас в Мега16 ВОСЕМЬ АЦП! Они "считают",
Во!АлександрЛ писал(а):По программе я вам подсказать, к сожалению,
Тихо!! Я СКАЗАЛ! Или я тихо сказал? (с)MisHel64 писал(а):Кто сказал?
Не знаю как, но в ДВУХКАНАЛЬНОЙ ПС на индикацию выводятся ЧЕТЫРЕ показания значений АЦП при помощи ДВУХ многоразрядных светодиодных индикаторов,- по типу АЛС319
ну, да, в общем- то сейчас узнал- там действительно мультиплексирование восьми входов на один АЦП, а так- вопрос только в том, с какой скоростью вы хотите получать данные с АЦП..
- Сообщения: 884
- Зарегистрирован: Пн июл 08, 2013 22:59:45
сделал я два дополнительных вольтметра, подключил, всё вроде как замечательно, но обнаружился баг, первое измерение 1 вольтметра верное, переключаем ножку, меряем напряжение на втором вольтметре, тоже верно, переключаем опять на первый и опа, вместо 1200 АЦП насчитывает 1441, и так по всем напряжениям, переключаемся снова на второй, он отлично работает, считает как нужно,вольтметры написаны совершенно одинаково, отличаются лишь именами переменной
Код: Выделить всё
ADCSRA |= (1 << ADEN) // разрешение АЦП
|(1 << ADSC) // запуск преобразования
|(1 << ADATE) // непрерывный режим работы АЦП //|(1 << ADFR) // непрерывный режим работы АЦП
|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64 (частота АЦП 125kHz)
|(1 << ADIE); // разрешение прерывания
ADMUX |= (1 << REFS1)|(1 << REFS0) // внутренний ИОН 2,56V
|(0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
потом в цикле
switch(flag_volt)
{
case 0:
{
//akk1=0;
break;
}
case 1:
{
//ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
//ADC=0;
//delay_1(100);
//akk1=akk*15*pow(8,-1);
akk1=akk*(3121*pow(2000,-1));//akk1=akk*1.5605;
if (i123==10)
{
/*ADCSRA |= (1 << ADSC);
ADC=0;*/
flag_volt=2;
ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(1 << MUX0); // вход ADC1
i123=0;
}
break;
}
case 2:
{
//ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(1 << MUX0); // вход ADC1
//temp1=akk*pow(4,-1);
//(float)(768*2)/(4*100)
//koy-коэффициент усилителя
//rma-сопротивление миллиамперметра
//pgr-погрешность оу
int koy=2,
rma=83,
pgr=31;
//temp1=( rma*( ((float)1200/100)-((float)(akk*koy)/(4*100) - ((float)pgr/1000)) )/ (((float)(akk*koy)/(4*100))- ((float)pgr/1000)) );
temp1=( rma*( (1200*pow(100,-1))-((akk*koy)*pow((4*100),-1) - (pgr*pow(1000,-1))) )/ (((akk*koy)*pow((4*100),-1))- (pgr*pow(1000,-1))) );
//temp1=(9*(pow(7,-1)))*100;
//akk=0;
//(int)((83*(1200/100-(float)((768*2)/(4*100))))/(float)((768*2)/(4*100)));
if (i123==10)
{
ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
flag_volt=1;
i123=0;
}
break;
}
case 3:
{
if (i123==10)
{
flag_volt=1;
i123=0;
}
break;
}
}
что за кошмарный код?! ну хоть примерно как-то так надо:
далее, что за ужасные вычисления у вас? АЦП принимает значения от 0 до 1023. пусть у вас там на входе делитель такой, что если на него подается 50В, то с него снимается ровно 2,56В (равно опорному АЦП). тогда значение get_adc вам надо умножить на 50000/1023, чтобы получить значение на входе делителя в милливольтах. и никаких float не нужно!
как-то так...
Код: Выделить всё
// функция опроса канала АЦП
// получает в параметре chanel номер канала АЦП,
// возвращает измеренное значение по этому каналу
int get_adc(char chanel){
ADMUX = (1 << REFS1) | (1 << REFS0) | (chanel & 0x07);
ADCSRA |= (1<<ADEN);
while (ADCSRA & (1<<ADEN));
return ADC;
}
// где-то в main в цикле
int result_1 = get_adc(0);
int result_2 = get_adc(1);
// потом с result_1 и result_2 можете всякие вычисления делатькак-то так...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


