помогите опросить энкодер
помогите опросить энкодер
здравствуйте,вот у меня возникла небольшая проблемка с опросом энкодера,подскажите пожалуйста как это осуществить.
пишу на СИ для пик
За раннее благодарен за оказанную помощ
пишу на СИ для пик
За раннее благодарен за оказанную помощ
Последний раз редактировалось vovik15 Сб янв 22, 2011 09:57:42, всего редактировалось 3 раза.
- Реклама
- Meteor
- Друг Кота
- Сообщения: 3961
- Зарегистрирован: Пн июл 13, 2009 14:37:39
- Откуда: Московская область, наукоград.....
- Контактная информация:
Про энкодер.
Подцепить лучше его к входам с прерываниями на внешнее событие и ждать когда сработает оно. Там формируется 2 импульса, один относительно другого сдвинут на "пол периода".
Остальное - стандартный счетчик - их тут море описано уже
Подцепить лучше его к входам с прерываниями на внешнее событие и ждать когда сработает оно. Там формируется 2 импульса, один относительно другого сдвинут на "пол периода".
Остальное - стандартный счетчик - их тут море описано уже
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
-
Smirnov
- Прорезались зубы
- Сообщения: 206
- Зарегистрирован: Сб фев 27, 2010 11:58:50
- Откуда: Горец: Уральские горы
а я делал энкодер проще, т.к. мне нужно было сделать энкодер который вращать будет человек, т.е. не быстро:
1. я сделал прерывание, 1000 раз в сек.
2. В прерывании опрашиваю состояние двух линий энкодера, т.е. 2 бита
3. Беру из буферных переменных, предыдущие состояние энкодера, т.е. 2 бита которые были в предыдущий момент прерывания.
4. Т.е. получается 4 бита, т.е. 16 значений, они служат адресом в таблице, соответствено попросту по полученному адресу беру код события, + или - или пусто, если например состояние энкодера не изменилось.
Всё, результат готов, по факту получился формальный анализ и последующий синтез алгоритма преобразователя состояния энкодера в код события + или - или пусто.
В случае автора можно доработать как нибудь, пусть сам решает я честно не понял как доложно увеличиваться и как тогда отличать - от +.
1. я сделал прерывание, 1000 раз в сек.
2. В прерывании опрашиваю состояние двух линий энкодера, т.е. 2 бита
3. Беру из буферных переменных, предыдущие состояние энкодера, т.е. 2 бита которые были в предыдущий момент прерывания.
4. Т.е. получается 4 бита, т.е. 16 значений, они служат адресом в таблице, соответствено попросту по полученному адресу беру код события, + или - или пусто, если например состояние энкодера не изменилось.
Всё, результат готов, по факту получился формальный анализ и последующий синтез алгоритма преобразователя состояния энкодера в код события + или - или пусто.
В случае автора можно доработать как нибудь, пусть сам решает я честно не понял как доложно увеличиваться и как тогда отличать - от +.
- AI_Disable
- Сверлит текстолит когтями
- Сообщения: 1116
- Зарегистрирован: Чт окт 15, 2009 14:16:18
- Откуда: Екб
- Контактная информация:
- Реклама
- Meteor
- Друг Кота
- Сообщения: 3961
- Зарегистрирован: Пн июл 13, 2009 14:37:39
- Откуда: Московская область, наукоград.....
- Контактная информация:
Он вынужден делать высокую частоту опроса потому что опрашивает и запоминает состояние входов. Если к примеру энкодер имеет 20 импульсов на 1 оборот и скорость вращения 1 сек. То длительность импульса не превышает 25 мс. А если прикошачить энкодер к внешним прерываниям можно просто ждать на каком из этих двух входах появится первый импульс и соответсвенно либо инкрементировать либо декрементировать некую переменную. Не тратя системное время на бесполезный опрос. Другая схемная реализация вынудит искать другие решения и возможно запись окажется оптимальным из них
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
-
Smirnov
- Прорезались зубы
- Сообщения: 206
- Зарегистрирован: Сб фев 27, 2010 11:58:50
- Откуда: Горец: Уральские горы
сделал по таймеру потому что так было проще. Во первых задача была не сложная, это управление кучей лазеров, измерение их параметров, регулирование мощности по этим параметрам, применение цифровых фильтров и как результат адаптивной подстройки мощности по множеству параметров. А так же отработка менюшек на графическом дисплейчике 640х200. С такой задачей у контроллера оставалось очень много запаса по быстродействию даже написав всё в лоб на Си без оптимизации.
А во вторых ясно что энкодер имеет всего 16 состояний с учётом предыдущих, я их попросту вывел на дисплейчик и посмотрел какие коды за что отвечают, ну и вбил. В итоге на отработку энкодера в прерывании тратилось не более 2 мкс.
Хотя насчёт прерываний согласен, тоже будет просто. Может быть даже проще моего случая. Дерзайте
По просьбе трудящихся пример, предположим состояние энкодера у тебя находится в PORT в младших 2х битах тогда:
выполнять с большой частотой, минимум 100 раз в секунду.
А во вторых ясно что энкодер имеет всего 16 состояний с учётом предыдущих, я их попросту вывел на дисплейчик и посмотрел какие коды за что отвечают, ну и вбил. В итоге на отработку энкодера в прерывании тратилось не более 2 мкс.
Хотя насчёт прерываний согласен, тоже будет просто. Может быть даже проще моего случая. Дерзайте
По просьбе трудящихся пример, предположим состояние энкодера у тебя находится в PORT в младших 2х битах тогда:
выполнять с большой частотой, минимум 100 раз в секунду.
Код: Выделить всё
temp1=PORT&0x03; // Читаем энкодер, берём 2 бита
temp2=temp1; //запоминаем новое состояние енкодера
temp1=temp1 | old_encoder; // формируем из старого и нового состояние 4 бита
old_encoder=temp2<<2; // запоминаем старое состояние энкодра
temp1=enc_table[temp1]; // адресуемся по таблице, извлекаем из неё код события если есть
if (temp1!=0) event=temp1; //если извлекли не нулевой код события то записываем его в переменную нового события, сюда можно поставить добавление события в очередь событий.- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
а можно посмотреть на этот проект? он уже реализовал аппаратно? если да, то видео может?Smirnov писал(а):Во первых задача была не сложная, это управление кучей лазеров, измерение их параметров, регулирование мощности по этим параметрам, применение цифровых фильтров и как результат адаптивной подстройки мощности по множеству параметров. А так же отработка менюшек на графическом дисплейчике 640х200.
Ставим плюсы: )
-
Smirnov
- Прорезались зубы
- Сообщения: 206
- Зарегистрирован: Сб фев 27, 2010 11:58:50
- Откуда: Горец: Уральские горы
ibiza11 писал(а):а можно посмотреть на этот проект? он уже реализовал аппаратно? если да, то видео может?
Видео нет, ибо часть приборов шло воякам с соответствующими предостарожностями, это было 5 лет назад и я кое как выпросил видео для защиты диплома, до сегодняшнего дня оно не дожило и противоречит правилам форума ибо видео операции зрелище такое что даже если человек заверяет что ему безразлично то всё равно в лучшем случае отворачивается.
нашел только простейший вариант, самый первый который я делал, без энкодера, но управление а полная автоподстройка уже была:
http://www.srz-holding.ru/katalog/index02.php?id=6
http://medprom.ru/medprom/mpp_0004849
Meteor писал(а):Про энкодер.
.. Там формируется 2 импульса, один относительно другого сдвинут на "пол периода"...
Может, и такие есть, но если имеется в виду инкрементирующий энкодер контактного типа как в регуляторах музыкальных центров/микроволновок, то мне попадались только такие у которых "импульс" короче чем "полпериода", а в равновесном положении оба контакта разомкнуты. Такой энкодер опрашивается так же, как если бы было просто две кнопки (плюс и минус) по принципу - кто первый тот и прав, т.е. какая первая кнопка нажата, та и обрабатывается, затем запрещается обработка до тех пор, пока обе кнопки не будут отпущены. На асме я сделал так:
Код: Выделить всё
_mainloop:
.
.
.
in r16,pinc ;разрешать ли прерывания по пинам?
andi r16,0x03
cpi r16,0x03
brne _mainloop
ldi r16,0
out pcifr,r16 ;очистка флагов
ldi r16,2
sts pcicr,r16 ;разрешить прерывания от энкодера
rjmp _mainloop
_pci1_int:
push r16
in r16,sreg
push r16
ldi r16,0
sts pcicr,r16 ;запрет pci1_int до особого распоряжения
in r16,pinc
andi r16,0x03 ;маска для PC0,PC1
cpi r16,0x01
breq _minus
cpi r16,0x02
breq _plus
rjmp _eoi2
_plus:
lds r16,T
cpi r16,250 ;правый упор
brsh _eoi2
inc r16
sts T,r16
rjmp _eoi2
_minus:
lds r16,T
cpi r16,30 ;левый упор
brlo _eoi2
dec r16
sts T,r16
rjmp _eoi2
_eoi2:
pop r16
out sreg,r16
pop r16
retiНемного кривовато написано, но работает. Энкодер у меня подключен к PC0, PC1; дребезг давится аппаратно - кондеры по 10нФ на землю.
вот тут делал с энкодером, есть комментария и проект протеуса, поидее должно работать с любыми энкодерами http://radiokot.ru/forum/viewtopic.php?p=386004#386004 без использования прерываний и таймеров.
-
ZUB
- Открыл глаза
- Сообщения: 66
- Зарегистрирован: Пт сен 04, 2009 20:16:35
- Откуда: Симферополь-Севастополь
- Контактная информация:
Пример на прерывании:
цепляешь на внешнее прерывание, другую ногу на любой другой пин (PIN*.*). В основном цикле программы смотришь на temp, он и определяет направление вращения.
Код: Выделить всё
interrupt [EXT_INT0] encoder(void)
{
if(PIN*.*){delay_ms(2); temp=1;}
else {delay_ms(2);temp=0;};
}
цепляешь на внешнее прерывание, другую ногу на любой другой пин (PIN*.*). В основном цикле программы смотришь на temp, он и определяет направление вращения.
-
ZUB
- Открыл глаза
- Сообщения: 66
- Зарегистрирован: Пт сен 04, 2009 20:16:35
- Откуда: Симферополь-Севастополь
- Контактная информация:
ooogo писал(а):ZUB а зачем делать пауза 2 мс ? впринципе можно и вприрывание необходимый код запихнуть.что конкретно нужно?а как быть со счетчиком нажатий на кнопку?
задержка для защиты от дребезга (может у меня такой энкодер разболтаный, что сильный дребезг, но без задержки часто были ложные срабатывания).
Если код запихнуть в прерывание то будет работать криво, лучше использовать "флаги".
Я тут думал все уже знают как правильно работать с энкодерами. Не надо никаких подавителей дребезга. Все решается несложной машиной состояний. Движение вправо: два последовательных перехода 00 -> 01 -> 11. Т.е. если он дребезднет 00-01-00-01-00-01-11-01 - все равно отработает только стабильный кусок (выделен). При этом можно использовать табличную технологию которую описал Smirnov. Конечно, разрешающая способность при этом падает в два раза, по сравнению с отсчетом по каждому переходу, но зато появляется надежность. При этом необязательно делать чтения показаний через равные интервалы времени. Главное делать достаточно часто чтобы не произошел пропуск события. Естественно, два подряд одинаковых состояния энкодера не учитываются.


