Можно и в виде махонького специально под энкодер приготовленного ПИКа ... Как тестер контактной группы viewtopic.php?p=2808012#p2808012 и как собственно ""вспомогательный девайс" viewtopic.php?p=2809072#p2809072 то я чей-то тему "упустил на время"... Кому будет интересно - пользуйтесь. На АВРке подобного соорудить будет весьма напряжно даже под ассемблером - а как "прикладная микруха" ПИК вполне может пригодиться...
Только согласно специфике команд один и тот же алгоритм для разных МК прийдется реализовать на разных типах команд. Как пример - реализация варианта на attiny13a: viewtopic.php?p=2816604#p2816604
подниму старую тему. на днях занялся освоением энкодера. при "изучении" интернета понял, что практически существует только два алгоритма обработки: 1. через внешнее прерывание. канал А заводится на прерывание, например, INT0, а при обработке прерывания опрашивается канал В. 2. опрос по таймеру обоих сигналов энкодера. логика обработки через внешнее прерывание на первый взгляд выглядит "железобетонно", и такое впечатление, что сбоев давать не должна. хотя в различных статьях надежность работы через внешнее прерывание оценивается гораздо ниже, чем второй способ (алгоритм). соответственно кажущейся "железобетонности", я начал осваивать по внешнему прерыванию (INT0). в обработке прерывания я сразу же запрещал это прерывание и запускал таймер, которой через некоторое время опять разрешал это внешнее прерывание. прерывание по таймеру отключало этот таймер. в общем, по внешнему прерыванию у меня вообще ничего не получилось. при вращении в одну сторону параметр и увеличивался и уменьшался, то есть, "крутился" вокруг исходного значения. то же самое происходило при вращении энкодера в другую сторону. тогда я реализовал второй алгоритм. и, о чудо!, энкодер прекрасно заработал с первого раза, даже ничего не пришлось подправлять в тексте программы. для МК я пишу только на ассемблере. тексты на С я даже читать отказываюсь. даю фрагменты своего текста, определяющие работу с энкодером.
как можно видеть, признаком направления вращения служит само число, точнее, знак числа в счетчике энкодера. при вращении вправо получается положительное число, а при вращении влево - отрицательное. поэтому в основном цикле пропадает необходимость в анализе направления, и достаточно к параметру просто прибавить получившееся число энкодера. после суммирования я делаю проверку на минимум, на ноль (в регистре R31 находится ноль), и проверку на максимум (число 500). после чего я сохраняю новое значение параметра (или старое, если энкодер не вращали) и обнуляю счетчик энкодера.
_________________ Мудрость приходит вместе с импотенцией...
Любая разработка начинается с чтения документации и изучения доступных средств разработки. Данный материал целиком посвящен средствам разработки, включая детальные инструкции по запуску вашего первого приложения на BlueNRG-LP. Описана работа с отладкой STEVAL-IDB011V1, набором инструментов и пакетом ПО позволяющим разработчику быстро войти в курс дела.
Что привлекает в SiC по сравнению с кремнием, и какие особенности делают компоненты SiC часто используемыми, несмотря на более высокую стоимость в сравнении с кремниевыми высоковольтными устройствами? – Объясняет специалист ведущего разработчика силовых приборов из карбида кремния, компании Infineon.
Отказ от си - банальный страх перед кажущейся сложностью. Я тоже когда-то был ярым приверженцем асма. Как съесть слона, ведь он большой. Кусочками. Ищете книжку по си, которая наиболее подходит вам по восприятию. Читаете понемножку. Перечитываете, что непонятно. И так каждый день. В определенный момент критическая масса достигнет предела и приходит понимание. Не всего, не сразу. Но приходит. Теперь начинаете пробовать. С практикой понимание еще больше наступает. Как-то так.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе удивительно, но при взгляде на многих сверху ничего не меняется...
Заголовок сообщения: Re: Программная обработка Энкодера на AVR
Добавлено: Вт ноя 15, 2016 09:33:59
Собутыльник Кота
Карма: 25
Рейтинг сообщений: 641
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2641 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Starichok51 писал(а):
в обработке прерывания я сразу же запрещал это прерывание и запускал таймер, которой через некоторое время опять разрешал это внешнее прерывание. прерывание по таймеру отключало этот таймер. в общем, по внешнему прерыванию у меня вообще ничего не получилось.
Возможно Вы перед разрешением прерывания не сбрасывали флаг прерывания. Если Вы определяли направление вращения по фронту, то прерывание "дребезжания" спада следует игнорировать, чего Вы скорее всего не делали.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
очень давно, когда я игрался с энкодером (надо признать, что и с Си я тогда в основном игрался), я сделал такую реализацию... без прерываний и таймеров, т.к. и по сей день уверен, что для пользовательского интерфейса все эти "быстродействия" совершенно не нужны. то есть 300 мс - это не проблема для пользовательского интерфейса.
предлагаю всем поглядеть на моё творчество и, как обычно, раскритиковать его в пух и прах
encoder.h
Код:
#ifndef _ENCODER_ #define _ENCODER_ 1 /********************************************************************* Модуль программной поддержки контактного квадратурного энкодера типа РЕС16 и аналогичных (без использования прерываний)
Внимание! Вы можете использовать данный модуль по своему усмотрению в любых проектах. При любой публикации ваших проектов, использующих этот модуль, следует указать ссылку на сайт http://arv.radioliga.com
Требуется компилятор WinAVR **********************************************************************/
#define ENC_A_PIN 3 /* номер линии порта для сигнала А энкодера */ #define ENC_B_PIN 6 /* номер линии порта для сигнала B энкодера */ #define ENC_A_PORT PIND /* порт, к которому подключен сигнал А энкодера */ #define ENC_B_PORT PINB /* порт, к которому подключен сигнал B энкодера */
#define rotate_fast(x) (x > ENC_FAST_ROTATE) #define DDR(x) (*(&x + 1)) #define PORT(x) (*(&x + 2)) /* Использование модуля элементарно: в начале программы следует вызвать функцию enc_init(), которая настроит нужные порты ввода-вывода. Затем в основном цикле в нужном месте можно обратиться либо к функции enc_rotate(), которая вернет значение, соответствующее направлению вращения энкодера, либо функцию enc_delta(), которая кроме направления возвратит и условную величину скорости вращения. enc_rotate() позволяет использовать энкодер, как 2 кнопки "+1" и "-1" enc_delta() уже может заменить 4 кнопки "+1", "+100", "-1" и "-100". Функция способна отличать "рывки туда-сюда" от простого вращения в одном направлении.
Нажатие встроенной кнопки энкодера НЕ ОБРАБАТЫВАЕТСЯ */
// инициализирует порты, к которым подключен энкодер void enc_init(void);
/* возвращает направление и скорость вращения энкодера параметр speed - указатель на переменную, в которую возвращается условная скорость вращения (число от 0 до 100)
возвращает: -1 - вращение влево (против часовой стрелки) 0 - нет вращения 1 - вращение вправо (по часовой стрелке)
ВНИМАНИЕ! функция выполняется достаточно длительное время: максимально (при остановленном энкодере) ENC_MAX_SPEED миллисекунд, при вращении возвращает управление раньше */ signed char enc_rotate(unsigned char * speed);
/* возвращает приращение энкодера: 1 или -1 при медленном вращении, 0 - при остановленном ENC_BIG_STEP или -ENC_BIG_STEP при быстром вращении
ВНИМАНИЕ!!! Функция выполняется долго!!! при быстром вращении возвращает управление только ПОСЛЕ ОСТАНОВКИ энкодера! остановкой считается, если в течение 2*ENC_MAX_SPEED миллисекунд не было импульсов с энкодера. */ signed char enc_delta(void);
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе удивительно, но при взгляде на многих сверху ничего не меняется...
какие дефайны тебя интересуют? единственное, что я не дал, вот это .def old_state_enc = R24 ; предыдущее состояние энкодера .def new_state_enc = R25 ; новое состояние энкодера
Demiurg писал(а):
Отказ от си - банальный страх перед кажущейся сложностью.
страха перд С у меня нет. для компа я пишу на С++ (Мелкософтовская вижл студия). для любопытствующих - в разделе Питание (на верху списка тем) есть моя большая тема с большим числом моих программ для расчетов трансформаторов и дросселей. но для МК у меня ассемблер - дело принципа. ведь, я же не говорил, что я не понимаю и что я боюсь С...
Z_h_e писал(а):
Возможно Вы перед разрешением прерывания не сбрасывали флаг прерывания.
да, я про его сброс даже не подумал. видимо, прерывание запрещено, а флаг все равно устанавливается. но когда у меня уже всё прекрасно заработало, что-то не хочется возвращаться к экспериментам с внешним прерыванием. мне так понравилась четкая работа по второму алгоритму, что я вчера перед сном не удержался и включил плату, чтобы еще раз полюбоваться прекрасной работой энкодера с этим алгоритмом.
_________________ Мудрость приходит вместе с импотенцией...
Так вот вроде простенько, на ассемблере и для АВРки: download/file.php?id=257389 ни таймеров там ни прерываний. Исходник открытый - интересно "доработать" - вполне на Ваш вкус...
спасибо, но принять твои исправления не представляется возможным, так как регистры R18 и R19 уже заняты под другие цели и у меня не осталось свободных регистров, допускающих работу с непосредственным операндом. придется пока оставить ; R14, R15 - счетчик энкодера и всё остальное без изменений.
но еще не всё потеряно, похоже, именно в этом проекте я могу функции четырех регистров R20-R23 переложить на регистры с номерами ниже 16-ти. тогда у меня появится возможность сделать определения, например, .def new_state_enc = R22 .def old_state_enc = R23 ; R24, R25 - счетчик энкодера и применить команды ADIW и SBIW. хотя применение этих команд не даст существенного выигрыша в длине кода (в данном случае "экономия" составит 10 байт кода).
_________________ Мудрость приходит вместе с импотенцией...
да это понятно, что можно всё опустить ниже 16-го номера. но это приводит к лишним "телодвижениям". но этот второй твой вариант меня не устраивает. я уже переделал программу. функции регистров R20-R23 опустил на регистры R10-R13. и сделал такие определения:
Принципиальность - нужная вещь. Но не в угоду самой принципиальности. Посмотрите на последние сообщения. Речь о регистрах и экономии АЖ ЦЕЛЫХ 10-ти байтах. Абалдеть не встать. Все ваши мысли об этом. И ни слова об алгоритмах, решениях.
дело не в экономии байт, места во флеши вполне хватает. но подкупает "красивость" решения, когда одной строкой можно заменить 3 или 4 строки. а какие еще нужны слова об алгоритмах и решениях, если я привел полный текст алгоритма и своих решений? а также очень положительно высказался в пользу этого алгоритма. если ты считаешь, что я о чем-то умолчал, то лучше задай вопросы, а не устраивай подобные "наезды"...
_________________ Мудрость приходит вместе с импотенцией...
Это не наезд. Повторяю, я тоже когда-то был приверженцем асма. Но в определенный момент я честно признался себе, что асм не решает многих моих задач. Что мои проекты стали сложны, чтобы продолжать ковыряться в песочнице регистрах. Я стал изучать си. Когда стало получаться, я бросил асм и проекты до тех пор, пока боле-менее не освоил си. Перенес многие свои наработки на си. И спустя некоторое время я пожалел, что был таким упертым. Я забыл что такое регистры и всякую прочую ерунду. Если раньше мне приходилось держать в голове состояние регистров, указателей, стека и так далее, то сейчас я оперирую переменными, функциями, модулями. Вот что я пытаюсь вам сказать. Если вы цепляетесь за асм, то я могу сказать одно - ваши проекты относительно простые. Другого объяснения я не вижу. Иначе вы бы уже замучались. Лично я увидел предел в асме, когда начал делать проекты с меню. Когда в указателях указатели на указатели указателей, мой мозг не выдержал такого насилия. Вот тогда я понял, что асм себя исчерпал.
я могу сказать одно - ваши проекты относительно простые.
ты абсолютно прав. у меня нет сложных проектов. и для моих домашних нужд и не нужны сложные проекты. более того, мои потребности настолько просты, что в своих проектах я обхожусь всего тремя кнопками, так как сложной "навигации" у меня нет, и мне хватает трех кнопок, чтобы управлять всеми режимами работы и настраивать все используемые параметры. понятное дело, что при сложной иерархической структуре меню трех кнопок явно не хватит. и несмотря на свой возраст (скоро исполнится 66 лет), я еще способен держать в голове состояние всех регистров. а чтобы не мучиться, вспоминая где что "лежит", существуют имена и метки, которые гораздо легче помнить, чем просто адреса, по которым размещены используемые данные и переменные. а назначая осмысленные, целевые, имена (а метка - это тоже имя), вообще нет никаких проблем писать на ассемблере программы любой сложности. не стану на 100% утверждать, но я думаю, что смогу на ассемблере одолеть во много раз сложнее проекты, чем те, которые уже у меня сделаны. и еще раз скажу - не надо меня агитировать за Си. мне нравится ковыряться в регистрах. и мне нравится получать минимальную длину кода с помощью ассемблера. и мне НЕ нравится, чтобы Си генерировал код, в несколько раз длиннее, чем можно сделать на ассемблере. и еще. я живу на "голую" пенсию. я купил несколько штук АТМега8. и я НЕ ХОЧУ покупать АТМега16 или АТМега32, когда мне Си сгенерирует такую кучу своего мусора, который не поместится в АТМегу8...
но и тебя я могу понять. если у тебя постоянно идут сложные проекты, то делая на Си, ты потратишь гораздо меньше времени на разработку, чем делая на ассемблере. а мне спешить некуда...
_________________ Мудрость приходит вместе с импотенцией...
Чтож, ваша позиция и мотивы понятны. Все-таки напоследок скажу. Когда более-менее разобрался с си, у меня получилось писать программы так, чтобы компилятор выдавал более-менее приемлемый результат.
Последний раз редактировалось Demiurg Ср ноя 16, 2016 17:17:27, всего редактировалось 2 раз(а).
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения