vetbaston 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 · Жалоба Есть MEGA64 и инкрементальный энкодер PEC12-4220F , кто работал с энкодером посоветуйте , как правильно обстучать его? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
XsanyaX 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 (изменено) · Жалоба Один из сигналов (А или В ) я заводил на внешнее прерывание, второй на любую ногу порта, сконфигурированую как вход. Прерывание - по любому логическому изменению сигнала. В обработчике, исходя из предыдущего и текущего значения сигналов А и В (предыдущее значение - значение А и В, при предыдущем вызове обработчика внешнего прерывания ) принимал решение в какую сторону происходит вращение и соотв. увеличивал или уменьшал значение требуемой переменной. Вот краткий алгоритм работы.. если нужно более подробное описание - обращайтесь... Изменено 19 сентября, 2006 пользователем XsanyaX Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Леонид Иванович 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 · Жалоба Обработка энкодера по прерываниям неудобна, так как требуется давить дребезг. Более того, чтобы корректно реализовать квадратурный декодер 1х (или 2х, 4х), прерывания должны происходить не по фронту или спаду одного из сигналов, а по любому изменению состояния энкодера. Отсюда следует порочность декодера типа "программный D-триггер, один сигнал энкодера на вход D, второй - на C". При такой реализации INC/DEC всегда происходит по фронту одного из сигналов энкодера, что есть неправильно. Если вал энкдера просто пошевелить на месте, может насчитаться куча импульсов. INC/DEC нужно делать по изменению состояния двух сигналов, чтобы и INC, и DEC происходили в одной и той же точке, но при её проходе с разными направлениями вращения. Информацию о построении правильных квадратурных декодеров можно почерпнуть из описания спец. микросхем, например, HCTL-2000. Я обрабатываю энкодер и его кнопку в основном цикле программы. Если программа чем-то занята, то она всё равно не сможет отреагировать на вращение энкодера, а буферизовать проделанный поворот и откладывать его обрботку - это уже слишком. Практика показала, что для комфорного использования энкодера задержки на подавление дребезга не должны превышать 500 мкс, иначе становится заметным пропуск шагов при резком повороте ручки. Я использую 300 мкс. Столь малые времена, к сожалению, не могут быть сформированы системным таймером как большинство других временных интервалов в программе. Поэтому приходится применять "тупую" задержку в виде цикла. Для таких малых интервалов это вполне допустимо, потери производительности процессора будут минимальными. Тем более, что обработка энкодера - это общение с пользователем, который всегда является самым медленным звеном системы :) Более того, если какая-то задача в основном цикле захочет временно забрать все ресурсы процессора (за вычетом потерь на прерывания), она сможет это сделать. В это время энкодер обслуживаться не будет. Для кнопки время подавления дребезга должно быть существенно большим, я использую 50 мс. Уж очень разные механические характеристики контактных групп кнопки и энкодера. Сюда выложил пример обработки энкодера на асме для AVR: http://upload.caxapa.ru/Enc.txt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psw 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 · Жалоба Есть MEGA64 и инкрементальный энкодер PEC12-4220F , кто работал с энкодером посоветуйте , как правильно обстучать его? здесь кусок обслуживающий кодер, кнопку сам допишешь. Полностью согласен с Леонидом Ивановичем, поэтому функцию вызываю из основной программы примерно раз в 20мСек, избавляюсь от дребезга и слишком быстрого вращения define PIN_Coder PIND//PD0,PD1 char status,encoder = 0; //----------------------------------------------------------------------------------- signed char ReadEncoder(void) { register signed char temp = 0; encoder = (~PIN_Coder & 0x03);//ïðîâåðÿåì PD0,PD1 if(status != encoder) { switch(encoder) { case 0: if(status == 1) temp = 1; else if(status == 2) temp = -1; break; case 1: if(status == 3) temp = 1; else if(status == 0) temp = -1; break; case 2: if(status == 0) temp = 1; else if(status == 3) temp = -1; break; case 3: if(status == 2)temp = 1; else if(status == 1) temp = -1; break; } status = encoder; } return temp; } //----------------------------------------------------------------------------------- Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetbaston 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 · Жалоба Спасибо всем! Буду пробовать! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NikolaKirov 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 · Жалоба Не невозможно сделат на 2 перервания. Вот я делал. Прилагаю изходник. Ето работает стабилно. encoder_if.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shurmas 0 19 сентября, 2006 Опубликовано 19 сентября, 2006 · Жалоба советую апноут микрочип AN696 - там схемотехника и Си код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BALDA 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба Обработка энкодера по прерываниям неудобна, так как требуется давить дребезг. Я обрабатываю энкодер и его кнопку в основном цикле программы. А я наоборот отказался от полинга работы с энкодером когда имеем достаточный загруз контроллера - иногда очень не аккуратно получалось ;-) сейчас работаю по прерыванию как уже говорилось выше... но несколько застраховавшись от дребезга, введя переменную "чувствительности" энкодера - она, кстати, очень полезна.. хотя дребезг есть также последствие мех воздействия и его отметать тоже не стоит - а нужно проанализировать... проблем уже как 3 года не наблюдаю причем даже с нонейм энкодерами, и энкодерами имеющие достаточный мех износ.... плюс ко всему под прерывание все прекрасно ложиться - и ресурсов кушает очень мало... так что вот ещё автору, тема для обмозгования.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Леонид Иванович 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба А какой физический смысл несет переменная "чувствительность энкодера"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shurmas 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба проблем уже как 3 года не наблюдаю причем даже с нонейм энкодерами, и энкодерами имеющие достаточный мех износ.... плюс ко всему под прерывание все прекрасно ложиться - и ресурсов кушает очень мало... Если не жалко - можно пример кода на Си ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба Для устранения дребезга по нескольким входам с одинаковой динамикой удобно использовать алгоритм "вертикальных счетчиков". Выходы енкодера обрабатывались по 100 мкс прерываниям фильтром на вертикальных счетчиках. Результат: PIn - отфильтрованные входы, PInChg - изменения по входам. Извините, прога на ассемблере под PIC'и. C-шный код достаточно раскомментировать. PIn и PInChg можно дальше обработать в основном цикле, или, если напряг по времени, не отходя от кассы. PInChg должен быть обработан до следующего прерывания. Применительно к энкодеру в предположении, что обрабатываются только два входа: uchar EncPos = 0; // IA и IB , естесно, равны номерам битов входов, на которые бегут выходы енкодера // bit-fields располагаются соответственно #define IA 0 #define IB 1 union { uchar i; struct { uchar A: 1; uchar B: 1; } b; } PIn, PInChg; ... if(PInChg.i == ((1<<IA)|(1<<IB))) { switch (PIn.i) { не вдаваясь в подробности case 0: ... case (1<<IA): ... case (1<<IB): ... case ((1<<IA)|(1<<IB)): ... } EncPos = PIn.i; } Ограничения: битовые позиции входов по портам (если обрабатываются входы с нескольких портов) не должны пересекаться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladimir_T 1 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба Еще есть такое решение: По тику таймерного прерывания заполняется кольцевой буфер. С каждым тиком в буфер засылается значение состояния энкодера. Анализируются элементы массива буфера: при равенстве элементов в массиве, возвращаем код состояния энкодера. Следующее заполнение кольцевого буфера только после обнаружения перекрытия фаз сигналов. Кольцевой буфер на 4-е элемента, частота опроса - 20 Гц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Леонид Иванович 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба Если частота опроса 20 Гц, то получится страшно тормозной энкодер. При быстром вращении он будет пропускать шаги - это некомфортно. Нужна частота опроса в 100 раз выше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BALDA 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба А какой физический смысл несет переменная "чувствительность энкодера"? фактически это счетчик инкрементов или декриментов очень хорошо когда энкодеры на различное число импульсов на оборот Если не жалко - можно пример кода на Си ? увы на си для 8 бит не пишу... а алгоритм описан выше - ничего секретного... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_artem_ 0 21 сентября, 2006 Опубликовано 21 сентября, 2006 · Жалоба Наверно загадочность заключается в том что : - при первом же прерывании устанавливается флаг состояния порта и первого прерывания(переменная) и наверно (если нужна перепроверка состояния порта через определенное время) запускается таймер. При этом для предотврашения многочисленных прерываний от порта вследствии дребезга - прерывание порта деактивизируется. - при прерывании таймера прочитывается порт и сверяется с предыдушим, полученным при прерывании от порта если совпадает - то рапортуем в коунтер, если нет то в обратное состояни . И также прерывание таймера деактивизируется и прерывание порта опять активизируется . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться