Перейти к содержанию

Обработка Инкрементального Энкодера На Прерываниях.


pryanic

Рекомендуемые сообщения

Вообще планирую запихать все действия в обаботчик, ведь если будет другой код, то х.з. в какой момент наступит прерывание...

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Ну и что с того. Сохранишь в стеке используемые в прерывании регистры, выполнишь прерывание, восстановишь регистры и продолжишь с момента "х.з.+1" (автоматом), как ничего и не было. Для этого прерывания и придуманы.

Ссылка на комментарий
Поделиться на другие сайты

Я о том, что часть вычислений в вашем алгоритме выполняется в основном цикле программы.

В данном случае это нормально, так как других действий МК не производит, но когда будут выполняться другие задачи, то лучше (мне кажется) выполнение целиком сделать в обработчике прерывания.

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Там не вычисления, там принятие логического решения и выполнение определенного действия. Вычисления и фильтр ошибок, как раз, в прерывании. В принципе, можно и в прерывании, если мало кода для действия.

Ссылка на комментарий
Поделиться на другие сайты

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Немного ошибся, точнее будет так (составлял по Вашему листингу):

post-122868-0-18982000-1355683906_thumb.png

Вот мой листинг: encoder_test3.zip

Изменено пользователем pryanic

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Вечером взгляну. А в железе работает? Посмотрел алгоритм, похоже на истину. В листинге нет выхода из прерывания (reti). В остальном - не вдавался, извини. Туго мысли идут (наверное перед праздником), а тут ты еще все перепахал под свой подчерк. Пробуй в железе, если что - звони, разберемся.

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

Геннадий, к сожалению в связи с наступающей сессией работа приостановлена. Еще раз посмотрел алгоритм (сверился с Вашим кодом).

Мне кажется такой вариант ветвления на спадающем фронте будет лучше. Получается в таком варианте программа будет реагировать на самый первый импульс. А в случае если бдуем при сравнении попадать на очистку флагов, то программа будет реагировать на последний импульс звона.

post-122868-0-07884700-1356288060_thumb.png

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Нашлось наконец-то время заняться. Но по прежнему все не особо весело.

Долго алгоритм не работал вообще, после тупления кода зараотал, но по-прежнему есть ложные срабатывания, причем характер этих срабатываний был во всех вариантах кода одинаков.

В аттаче проект студии.

encoder_test3.zip

Изменено пользователем pryanic

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Антон, как я понял, ты используешь механический энкодер. В таком случае нужно немного изменить последовательность действий. Поскольку существует дребезг контактов, то не нужно опрашивать состояние второго вывода энкодера сразу после тактового перепада на первом выводе. Попробуй так: тактовый перепад -> задержка 20-30 мс -> проверка состояния второго вывода.

Ссылка на комментарий
Поделиться на другие сайты

Алексей,пробовал. С такого алгоритма я начал. Пробовал разные задержки. - работало плохо.

Долго сейчас смотрел на картинку последнего алгоритма и понял, что от дребезга не защищает. в момент прощупывания порта направления из-за дребезга может быть выставлен неверный флаг.

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Геннадий, намек понял. Т.е. щупать несколько раз, пока не перестанет изменяться состояние?

Изменено пользователем pryanic

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Чтобы тут тоже было. Рабочий кусок. Сейчас работает в никитинском регуляторе.

unsigned int scanenc(void)
{
encnew=((PIND&0b00001100)>>2); //читаем состояние ног энкодера
if (encnew==(enccode&0b00000011)) return(code); //если состояние не поменялось, то возвращаем код.
enccode=(enccode<<2)|encnew; //запоминаем последовательно цепочку состояний

//сравниваем получившуюся последовательность с последовательностями для инкремента и декремента
if ((enccode == 0b10000111)&(code>0)) code--;
if ((enccode == 0b01001011)&(code<0x1F)) code++;
return (code);
}

Вызывается по прерываниям таймера антидребезга от обеих ног. Сначала делал тактовый/направление, работало плохо.

Прерывания INT0 и INT1 на обе ноги. По изменению уровня, то есть по обоим фронтам.

Можно просто ноги по таймеру опрашивать и эту же функцию вызывать. Но мне нужен был спящий режим, поэтому так не прокатывает.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо, Евгений. Но я на асме пишу.

Последние новости: все-таки заработало. Подшаманил несколько код с задержкой от таймера. Плюс решил собрать энкодер на макетке с резисторами, подтягивающими тактовые ноги к питанию и конденсаторами на землю (до этого сразу цеплял энкодер к портам микроконтроллера с внутренней подтяжкой).

post-122868-0-34421200-1361458579_thumb.gif

И все заработало как часы!!!! Правда задержку пришлось сделать меньше ожидаемой. Вначале была примерно 16 мс (4 МГц, предделитель 256), но при быстром вращении видимо цепляло уже из следующего цикла, установил предделитель на 8 и даже при самом быстром вращении не происходит никаких неожиданностей.

Спасибо всем учавствовавшим.

encoder_test2.zip

Изменено пользователем pryanic

Антон. Блог

HTPC -> foobar2000 -> SMSL M8A -> Nataly 2012 -> Focal JMLab Tantal 515

Ссылка на комментарий
Поделиться на другие сайты

Спасибо, Евгений. Но я на асме пишу.

Какая разница, главное ведь алгоритм :).

Последние новости: все-таки заработало. Подшаманил несколько код с задержкой от таймера. Плюс решил собрать энкодер на макетке с резисторами, подтягивающими тактовые ноги к питанию и конденсаторами на землю (до этого сразу цеплял энкодер к портам микроконтроллера с внутренней подтяжкой).

И все заработало как часы!!!!

Вот с кондерами у меня тоже по такому принципу нормально работало. А без кондеров либо лишние импульсы, либо приходится делать очень жесткий андидребезг и в итоге на высокой скорости вращения импульсы не считаются. Алгоритм, что я привел выше, замечательно работает без конденсаторов. Лишние детали - не наш метод )))

Изменено пользователем GeniusXZ
Ссылка на комментарий
Поделиться на другие сайты

  • 3 года спустя...

подниму старую тему.

на днях занялся освоением энкодера.

при "изучении" интернета понял, что практически существует только два алгоритма обработки:

1. через внешнее прерывание. канал А заводится на прерывание, например, INT0, а при обработке прерывания опрашивается канал В.

(именно с этого алгоритма и началась эта тема).

2. опрос по таймеру обоих сигналов энкодера.

логика обработки через внешнее прерывание на первый взгляд выглядит "железобетонно", и такое впечатление, что сбоев давать не должна. хотя в различных статьях надежность работы через внешнее прерывание оценивается гораздо ниже, чем второй способ (алгоритм).

соответственно кажущейся "железобетонности", я начал осваивать по внешнему прерыванию (INT0). в обработке прерывания я сразу же запрещал это прерывание и запускал таймер, которой через некоторое время опять разрешал это внешнее прерывание. прерывание по таймеру отключало этот таймер.

в общем, по внешнему прерыванию у меня вообще ничего не получилось. при вращении в одну сторону параметр и увеличивался и уменьшался, то есть, "крутился" вокруг исходного значения. то же самое происходило при вращении энкодера в другую сторону.

тогда я реализовал второй алгоритм. и, о чудо!, энкодер прекрасно заработал с первого раза, даже ничего не пришлось подправлять в тексте программы.

для МК  я пишу только на ассемблере. тексты на С я даже читать отказываюсь.

даю фрагменты своего текста, определяющие работу с энкодером.

Скрытый текст

.include "m8def.inc"	; ATMega8
; внутренний RC генератор 1 МГц

...

;------ настройка Таймера0 ------
ldi R16, 2			; предделитель = 8, интервал срабатывания Таймера0 2048 мкс
out TCCR0, R16

...

;--- прерывание по Таймеру0 ---
timer0:
push R16				; сохраним регистр, который использует прерывание
in R16, SREG			; сохраним SREG
push R16				; сохраним SREG
; канал A энкодера - порт D0
; канал B энкодера - порт D1
in new_state_enc, PinD
andi new_state_enc, 3

cp old_state_enc, new_state_enc	; если состояние не поменялось, то выходим
breq nothing

cpi new_state_enc, 0	; если состояние поменялось, выбираем подходящий вариант
breq case0
cpi new_state_enc, 1
breq case1
cpi new_state_enc, 2
breq case2
cpi new_state_enc, 3
breq case3
rjmp nothing			; блокировка на всякий случай, хотя до этой команды никогда не должно дойти

case0:
cpi old_state_enc, 1
breq Iref_plus
cpi old_state_enc, 2
breq Iref_minus
rjmp nothing			; блокировка на случай ошибочной комбинации состояний энкодера

case1:
cpi old_state_enc, 3
breq Iref_plus
cpi old_state_enc, 0
breq Iref_minus
rjmp nothing			; блокировка на случай ошибочной комбинации состояний энкодера

case2:
cpi old_state_enc, 0
breq Iref_plus
cpi old_state_enc, 3
breq Iref_minus
rjmp nothing			; блокировка на случай ошибочной комбинации состояний энкодера

case3:
cpi old_state_enc, 2
breq Iref_plus
cpi old_state_enc, 1
breq Iref_minus
rjmp nothing			; блокировка на случай ошибочной комбинации состояний энкодера

Iref_plus:
mov old_state_enc, new_state_enc	; копируем в темп1 новое состояние выводов
inc R14
brne no_0_R14
inc R15
no_0_R14:
rjmp nothing

Iref_minus:
mov old_state_enc, new_state_enc	; копируем в темп1 новое состояние выводов
ldi R16, 1
sub R14, R16
brcc no_R14
sbc R15, R31
no_R14:

nothing:
pop R16					; восстановим SREG
out SREG, R16			; восстановим SREG
pop R16					; восстановим регистр, который использует прерывание
reti

...

;--- это делается в основном цикле программы с интервалом 0,1 секунды ---
;--- обработка результата вращения энкодера ---
ldi R16, par_Iref	; подставим номер параметра "задание тока"
rcall get_parametr	; получим в R21:R20 параметр
add R20, R14
adc R21, R15
cp R20, R31
cpc R21, R31
brpl no_Iref_min
mov R20, R31
mov R21, R31
no_Iref_min:
ldi R16,  low(500)
ldi R17, high(500)
cp R16, R20
cpc R17, R21
brcc no_Iref_max
mov R20, R16
mov R21, R17
no_Iref_max:
ldi R30, spisok_par + (par_Iref<<1)
st Z+, R20
st Z, R21
clr R14				; очищаем регистры счетчика энкодера (приращение к параметру)
clr R15

...

 

забыл вставить в код этот комментарий, а редактирование уже вставленного кода недоступно.

;    R14, R15    - счетчик энкодера

как можно видеть, признаком направления вращения служит само число, точнее, знак числа в счетчике энкодера. при вращении вправо получается положительное число, а при вращении влево - отрицательное.

поэтому в основном цикле пропадает необходимость в анализе направления, и достаточно к параметру просто прибавить получившееся число энкодера.

после суммирования я делаю проверку на минимум, на ноль (в регистре R31 находится ноль), и проверку на максимум (число 500).

после чего я сохраняю новое значение параметра (или старое, если энкодер не вращали) и обнуляю счетчик энкодера.

 

блин... знаки табуляции разбежались и комментарии встали хаотически...

Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Ссылка на комментарий
Поделиться на другие сайты

я эту статью уже читал.

на Радиокоте уже дали хорошую подсказку.

счетчик энкодера перевел на регистры R24 и R25, благодаря чему удалось применить команды

adiw R24, 1
и
sbiw R24, 1

что сократило код на десяток байт.

 

Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Ссылка на комментарий
Поделиться на другие сайты

  • 2 года спустя...

Любезно прошу мимо проходящего выложить пример кода с поста 43 в виде кода. Нет у меня средств для чтения таких файлов. Спасибо.

Ссылка на комментарий
Поделиться на другие сайты

ISR(INT0_vect)//для atmega328 если появился сигнал на int0  PD2
{
	if (PINB&(1<<7))//то если на PB7 появилась 1 (крутим влево)
	{
		EncData++;
	}
	if (!(PINB&(1<<7)))//если на PB7 0 (крутим вправо)
	{
		EncData--;
	}
}

короче чтоб не срать в других темах буду .... здесь. как я понимаю это что типа так?

только я не понимаю как в нее передать и сохранить EncData.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...