Страница 1 из 1
АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 12, 2010 01:21:24
Александр 2677
Всех приветствую.
Столкнулся с одной проблемой, нужно реализовать такую схему, чтобы можно было остановить двигатель по срабатыванию нескольких концевиков которые подключены последовательно, и при этом нужно чтобы высвечивался номер концевика. Параллельно концевикам подключены переменные резисторы.
Нашёл подходящий код для моей программы, изменил её под себя, в Proteus работает как надо. А вот на отладочной плате не хочет. После старта программы показывает индикацию как будто на ADC0 всё время +5в. , даже если я провод сажаю напрямую на землю. Кто знает в чём может быть дело?
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
#define FIRST_ADC_INPUT 0
#define LAST_ADC_INPUT 0
unsigned char adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1];
#define ADC_VREF_TYPE 0x20
interrupt [ADC_INT] void adc_isr(void) //стандартное прерывание по ADC от CVAVR
{
static unsigned char input_index=0;
// Read the 8 most significant bits
// of the AD conversion result
adc_data[input_index]=ADCH;
// Select next ADC input
if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT))
input_index=0;
ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
}
void main(void)
{
PORTD=0x00;
DDRD=0xFF;
ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff);
ADCSRA=0xCC;
#asm("sei")
while (1)
{
while((adc_data[0]<24)) // Индикация кнопка стоп
{
PORTB.1=0; // Выключить реле двигателя
PORTD=0xF0;
delay_ms (300);
PORTD=0x27;
delay_ms (300); };
if((adc_data[0]>25)&&(adc_data[0]<50)) //Индикация концевик №1
PORTD=0xEB;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>50)&&(adc_data[0]<75)) //Индикация концевик №2
PORTD=0x32;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>75)&&(adc_data[0]<100)) //Индикация концевик №3
PORTD=0xA2;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>100)&&(adc_data[0]<125)) //Индикация концевик №4
PORTD=0xE1;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>125)&&(adc_data[0]<150)) //Индикация концевик №5
PORTD=0xA4;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>150)&&(adc_data[0]<175)) //Индикация концевик №6
PORTD=0x24;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>175)&&(adc_data[0]<200)) //Индикация концевик №7
PORTD=0xEA;
PORTB.1=0; // Выключить реле двигателя
if((adc_data[0]>200)&&(adc_data[0]<225)) //Индикация концевик №8
PORTD=0x20;
PORTB.1=0; // Выключить реле двигателя
//else PORTD=0x00;
while((adc_data[0]>225)) // Индикация работы двигателя
{
PORTB.1=1; // Вкючить реле двигателя
PORTD=0xFE;
delay_ms (50);
PORTD=0xFB;
delay_ms (50);
PORTD=0xEF;
delay_ms (50);
PORTD=0xbf;
delay_ms (50);
PORTD=0x7F;
delay_ms (50);
PORTD=0xFD;
delay_ms (50); };
};
}
Re: АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 12, 2010 11:26:01
pyzhman
Фича ADC в том, что сначла нужно читать ADCL, и только потом ADCH. Напишите так
Код: Выделить всё
adc_data[input_index]=ADCL;
adc_data[input_index]=ADCH;
Re: АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 12, 2010 12:16:10
Александр 2677
Здесь
http://easyelectronics.ru/avr-uchebnyj- ... e-acp.html описывается как читать толко из ADCH .
Делаем выравнивание по левому краю. И загребаем старшие разряды только из регистра ADCH, а на младший забиваем. Итого, у нас число отсчетов становится 256. За выравнивание отвечает бит ADLAR в регистре ADMUX 0 — выравнивание по правой границе, 1 — по левой.
Но наверное дело не в этом, ведь в Proteus вроде работает?
Re: АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 12, 2010 17:02:21
Александр 2677
Всё отбой, на отладочной плате не было перемычки между AVCC и AREF.
Вопрос эта перемычка должна стоять только когда контроллер работает в режиме АЦП?
Re: АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 12, 2010 17:23:53
Meteor
Вывод AREF нужен для подачи опорного напряжения, а каким оно будет = VCC или меньшим определяет разработчик на этапе проектирования
Re: АЦП несколько датчиков по двум проводам
Добавлено: Пн дек 13, 2010 21:16:37
BCluster
А еще можно настроить чтоб АЦП брал опорку от AVCC (:
Re: АЦП несколько датчиков по двум проводам
Добавлено: Чт дек 16, 2010 17:08:25
Александр 2677
Помогите мне пожалуйста усовершенствовать прибор. Как подключить и настроить два входа АЦП, с примером кода.
И ещё вопрос , провода с датчиками находятся на улице, и длинна провода метров 500. Можно ли их подключать напрямую к микроконтроллеру?
Re: АЦП несколько датчиков по двум проводам
Добавлено: Чт дек 16, 2010 21:04:28
Roman Venom
Александр 2677
И ещё вопрос , провода с датчиками находятся на улице, и длинна провода метров 500. Можно ли их подключать напрямую к микроконтроллеру?
Нет.
Как подключить и настроить два входа АЦП, с примером кода.
Настроить можно по-разному... Есть режим однократного преобразования, есть постоянного. Скорость тоже не ясно какую вам надо (рекомендуется 50-200кГц). А входа переключать "вручную" надо регистром ADMUX.
П.С. Я читал про настройку АЦП в книге Ревича+даташит. И вам того же советую. Будет эффективнее чем на форум писать.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Чт дек 16, 2010 22:00:21
Александр 2677
И ещё вопрос , провода с датчиками находятся на улице, и длинна провода метров 500. Можно ли их подключать напрямую к микроконтроллеру?
Нет.
А как их подключать?
Re: АЦП несколько датчиков по двум проводам
Добавлено: Чт дек 16, 2010 22:17:22
Roman Venom
Александр 2677
А как их подключать?
Ну для этого существует интерфейс RS485. С усилителем и гальванической развязкой от МК. На счёт усилителя подсказать не могу - не делал, ибо шнур 2 метра.
А так без усилителя потребуются следующие детальки:
-микросхема ST485
-оптотранзисторы (любые)
-переходник USB-RS485.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Чт дек 16, 2010 22:47:30
Александр 2677
Что то я не понял как это всё подключать , и зачем нужен переходник USB. Я пробовал подключать эти датчики через бухту провода почти километр 0.75 мм2 и всё работало без проблем. Может меня неправильно поняли по поводу схемы подключения. На протяжении всего кабеля ~ 500м в разрыв подключены 10 концевиков с параллельно припаянным резистором.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Чт дек 16, 2010 23:00:29
Roman Venom
Александр 2677
и зачем нужен переходник USB
Я почему-то подумал что управление будет с компьютера... Если нет, то такой штуки не надо.
Я пробовал подключать эти датчики через бухту провода почти километр 0.75 мм2 и всё работало без проблем. Может меня неправильно поняли по поводу схемы подключения. На протяжении всего кабеля ~ 500м в разрыв подключены 10 концевиков с параллельно припаянным резистором.
Как бы там оно не было подключено, но развязка оптомарами нужна, ибо МК может заглючить (мало ли какие там на улице наводки на 500-метровом проводе). Если всё работает без усилителя - это конечно хорошо, однако 500м всё же не мало... Для гарантии стабильной работы он не помешал бы.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Пт дек 17, 2010 09:18:30
Александр 2677
Набросайте пожалуйста схемку развязки оптопары для ацп, а то я в электронике не силён, сам схемы грамотные составлять пока не умею)). Мой вариант такой
Но мне кажется что не получится так сделать, кстати на концевиках стоят подстроечные резисторы на 20ком.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Пт дек 17, 2010 16:06:55
Roman Venom
Александр 2677
Подумал я на счёт развязки аналогового входа... Используя обычные оптопары теряется непрерывный измеряемый сигнал (напряжение). А спец. развязки стоят прилично.
Поэтому рассмотрите вариант разместить ещё один МК возле датчиков. И передавать с него данные уже дискретно по SPI, USART, ШИМ... Тогда уже можно использовать обычные оптопары не боясь потерять информацию.
Короче где-то так. Выходы оптопар - на второй МК. Включить передачу - кнопка№2. Увеличить скорость передачи - кнопка№1(нажимается только когда выкл№2). Для простоты использовал ШИМ.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Сб дек 18, 2010 14:38:34
Александр 2677
Поставить ещё микроконтроллеры возле датчиков не представляется возможным. Я попробовал собрать макет с оптопарой, также подклчил его через бухту провода. И он заработал

Единственное что подстроечные резисторы не во всём диапазоне работают.

Как вручную переключить регистр ADMUX что то не разобрался. Придётся в один корпус, два МК засунуть

Re: АЦП несколько датчиков по двум проводам
Добавлено: Сб дек 18, 2010 15:48:25
Roman Venom
Александр 2677
Я попробовал собрать макет с оптопарой, также подклчил его через бухту провода. И он заработал
Странно... Вообще-то не должен был
Как раз хотел написать про резисторы...в обвязке оптопары.
Поставьте Р9 примерно 330Ом, а Р8 1.2кОм. Такая корректировка коэффициента передачи оптопары (соотношение 1к3) у меня проверено работает.
Как вручную переключить регистр ADMUX что то не разобрался. Придётся в один корпус, два МК засунуть
Записью в регистр значений от 0b000 до (в атмеге 16) 0х111. Т.е. в первом случае обрабатывается канал АЦП№0, а остальные выключены. В последнем - канал №7. Вот так. Алгоритм примерно следующий:
прерывание АДС:
(по включению питания, допустим, выбран канал 0)
1.считать число АЦП
2.поместить число в ячейку СРАМ_0
3. переключить канал АЦП
4. выход
В другом прерывании(по переполнению таймера, например), можно копировать значение СРАМ_0 в другую ячейку памяти и потом их как минимум усреднять, или сваять какой-то простейший цифровой фильтр.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 19, 2010 12:44:54
Александр 2677
Спасибо за советы , начинаю потихоньку разбираться. Пошли вторые сутки за компьютером, поправте пожалуйста, а то в голове уже всё путается от этих ADMUX, ADCSRA, итд итп
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
char in1=0,in2=0 ,port;
// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
TCNT2=0xFB;
PORTB=in1; // отобразить горящими светодиодами число in1
PORTD=in2; // отобразить горящими светодиодами число in2
}
#define ADC_VREF_TYPE 0x00
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
ADCSRA|=0x40; // начать новое АЦ преобразование
if ( ADMUX==0) // Еси ADC0, то поместить число
{
in1=(unsigned char) ADCW; // ADCW в переменную in1
};
if ( ADMUX==1) // Еси ADC1, то поместить число
{
in2=(unsigned char) ADCW; // ADCW в переменную in2
};
delay_us(10);
ADMUX^= (1 << 0); // Перекючить вход ADC
}
Re: АЦП несколько датчиков по двум проводам
Добавлено: Вс дек 19, 2010 13:21:32
Roman Venom
Александр 2677
Изучение С пока что только в планах... Поэтому советую почитать ссылку:
http://radiokot.ru/forum/viewtopic.php? ... 35&start=0
Так как раз на счёт настройки АЦП на меге8 и как раз на С
П.С. Сразу бросается в глаза следующее. ADCSRA|=0x40. А зачем это делать в прерывании? Настройте этот регистр(частоту 50-200кГц) и т.д. в инициализации АЦП, т.е. ДО прерывания. В основном цикле программы разрешайте однократное преобразование битом ADSC. А в самом прерывании АЦП можно вначале выключать АЦП битом ADEN и вконце прерывания его включать. И то это обязательно для PIC-контроллеров, иначе каналы АЦП не переключаются... Зачем же сбрасывать настройки?
Короче почитайте ту темку.
Re: АЦП несколько датчиков по двум проводам
Добавлено: Ср дек 22, 2010 12:25:55
Александр 2677
Ну вот наконец то закончил свою программу , осталось спаять схему.
Возник вопрос как подключить полевой транзистор IRF7311 к мк для того чтобы переключать семисегментный индикатор, я имею в виду какой резистор поставить на выход с мк, или можно подключить его напрямую. В одной статье было нарисована схема без резистора.

Re: АЦП несколько датчиков по двум проводам
Добавлено: Ср дек 22, 2010 22:13:09
Roman Venom
я бы затвор подтянул резистором 10кОм.
и транзистор должен быть логического уровня.