AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
19.04.2013, 09:03
|
|
Временная регистрация
Регистрация: 12.02.2010
Сообщений: 67
Сказал спасибо: 27
Сказали Спасибо 45 раз(а) в 15 сообщении(ях)
|
Алгоритмы фильтра дребезга avr
На входы int0 и int 1 подключены фотодатчики от последовательности их срабатывания зависит направление счёта. Прерывания настроены по нарастающему фронту. Ещё есть прерывание по таймеру, в нём переключаются разряды динамической индикации.
Проблема: корректность показаний.
Вот обработчик прерывания:
Код:
|
push sregg ;записать SREG
sbic PIND,2 ;если вывод PD2 не 0, то выходим
rjmp vh1
sei ; Разрешаем прерывания для индикации
cl1: sbis PIND,2 ; Пока тут не 1 крутимся в цикле
rjmp cl1
cli ; Запретим прерывания и
rcall chn ; увеличим значение счётчика
vh1: pop sregg ; восстановить SREG
reti |
Что тут плохого? Во-первых разрешая прерывания разрешаем и повторные прерывания по этому же событию.
Во-вторых цикл сделан для как раз блокировки счёта на период пока фотодатчик затенён. Но своей задачи не выполняет.
Что можно предпринять? Установку флага в начале прерывания и выход в случае если он был установлен? А снимать флаг в конце обработчика.
Нужно и не пропустить событие и не посчитать какие-то лишние импульсы.
Есть вариант вообще отказаться от прерываний а ставить флаг "кто затенён первый" при проверке, отсюда направление счёта.
Заранее благодарен за советы.
|
|
|
|
19.04.2013, 09:40
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Сообщение от _Ross_
|
Ещё есть прерывание по таймеру, в нём переключаются разряды динамической индикации.
|
Це есть плохо и крайне не кошерно. Поднимайте флаг. В основном цикле проверяйте и динамируйте. Иначе вам удачи не видать.
|
|
|
|
19.04.2013, 09:43
|
|
Временная регистрация
Регистрация: 12.02.2010
Сообщений: 67
Сказал спасибо: 27
Сказали Спасибо 45 раз(а) в 15 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Вы не заметили "глухой" цикл в прерывании по int ?
Тогда, динамическая индикация у меня будет дёргаться или вообще гаснуть, если в основном цикле переключать.
И потом, основной цикл в данном устройстве вообще не критичен, в нём никакой задачи нет.
Меня сейчас не столько индикация интересует сколько борьба с дребезгом.
Просто при счёте по прерыванию могли в секунду "прилететь" десятки срабатываний.
|
|
|
|
19.04.2013, 10:32
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Сообщение от _Ross_
|
Нужно и не пропустить событие и не посчитать какие-то лишние импульсы.
|
Какое-то противоречивое условие. Вы и только вы знаете, какие из пришедших импульсов можно и нужно отнести к категории "лишних".
Ваши определения уходят во временнУю область. Т.е. вам надо самому определиться, в какой конкретно отрезок времени ваши импульсы будут считаться "лишними". На этом чаще всего и строятся алгоритмы дебонсинга. Есть еще и другие, но чаще всего просто игнорируются перепады в "защитном" интервале.
Цитата:
|
cl1: sbis PIND,2 ; Пока тут не 1 крутимся в цикле
rjmp cl1
|
А это ваще! В прерывании...
А если там навечно "не 1"?
__________________
С уважением,
Vic / ut1wpr
Последний раз редактировалось ut1wpr; 19.04.2013 в 10:35.
|
|
|
|
19.04.2013, 11:39
|
|
Временная регистрация
Регистрация: 12.02.2010
Сообщений: 67
Сказал спасибо: 27
Сказали Спасибо 45 раз(а) в 15 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Я понимаю что во временную. Состояние фотодиода зависит от скорости объекта в основном тут. Исходя из задачи где-то 20 мс гарантированное минимальное время "нужного" сигнала. И ещё известно что за конкретный период времени, может быть не более 3 срабатываний подряд потом некоторая пауза. Другое дело что я не знаю длительность помехи.
Насчёт "вечного" цикла в прерывании- ничего страшного.
Динамическая индикация происходит в другом прерывании. А если там вечно не "1" значит:
а) Объект остановился в этой точке.
б) Фотодиод неисправен
В обоих вариантах или работа счётчика при этом нам не нужна или невозможна в принципе. Поэтому не вижу ошибки в реализации.
Я ещё немного слышал про "Сбросить флаг прерывания, затем запретить их и через какое-то время разрешить" Но поможет ли это от кратковременных всплесков, ведь всякая помеха вызывает прерывание по фронту.
Или грамотнее читать состояние выводов всегда и ставить флаг приоритета где произошло изменение первым...Отсюда направление счёта. Тут можно фиксировать изменения только после прохождения объектом обоих барьеров.
Последний раз редактировалось _Ross_; 19.04.2013 в 11:45.
|
|
|
|
19.04.2013, 12:46
|
|
Временная регистрация
Регистрация: 08.02.2010
Сообщений: 62
Сказал спасибо: 4
Сказали Спасибо 14 раз(а) в 12 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
вот замечательная функция обработки енкодера от Леонида Ивановича, использую давно, нареканий нет.
//----------------------------------------------------------------------------
//Ìîäóëü ïîääåðæêè ýíêîäåðà
//Ýíêîäåð ïîäêëþ÷àåòñÿ ê ïîðòàì ENC_F1 (ôàçà 1) è ENC_F2 (ôàçà 2).
//Ôóíêöèÿ Enc_Scan() âûçûâàåòñÿ â îñíîâíîì öèêëå.
//Ðåçóëüòàò îáðàáîòêè ýíêîäåðà ïåðåäàåòñÿ â ìîäóëü
//îáðàáîòêè êëàâèàòóðû ÷åðåç ôóíêöèþ Keyboard_SetCode().
//----------------------------------------------------------------------------
#include ‹Main.h›
#include ‹Encoder.h›
#include ‹Keyboard.h›
//----------------------------- Êîíñòàíòû: -----------------------------------
enum { State0, StateA, StateB, StateAB }; //ñîñòîÿíèÿ ýíêîäåðà
//----------------------------- Ïåðåìåííûå: ----------------------------------
static char EncPrev; //ïðåäûäóùåå ñîñòîÿíèå ýíêîäåðà
static char EncPrevPrev; //ïðåä-ïðåäûäóùåå ñîñòîÿíèå ýíêîäåðà
//----------------------- Èíèöèàëèçàöèÿ ýíêîäåðà: ----------------------------
void Encoder_Init(void)
{
EncPrev = State0; //èíèöèàëèçàöèÿ ïðåäûäóùåãî ñîñòîÿíèÿ
EncPrevPrev = State0; //èíèöèàëèçàöèÿ ïðåä-ïðåäûäóùåãî ñîñòîÿíèÿ
}
//------------------------- Îáðàáîòêà ýíêîäåðà: ------------------------------
void Encoder_Exe(void)
{
char EncCur = 0;
if(!Pin_ENC_F1) EncCur = StateA; //îïðîñ ôàçû 1 ýíêîäåðà
if(!Pin_ENC_F2) EncCur |= StateB; //îïðîñ ôàçû 2 ýíêîäåðà
if(EncCur != EncPrev) //åñëè ñîñòîÿíèå èçìåíèëîñü,
{
if(EncPrev == StateAB && //åñëè ïðåäûäóùåå ñîñòîÿíèå StateAB
EncCur != EncPrevPrev ) //è òåêóùåå è ïðåä-ïðåäûäóùåå íå ðàâíû,
{
if(EncCur == StateB) //åñëè òåêóùåå ñîñòîÿíèå StateB,
Keyboard_SetCode(ENC_DN); //øàã âíèç
else //èíà÷å
Keyboard_SetCode(ENC_UP); //øàã ââåðõ
}
EncPrevPrev = EncPrev; //ñîõðàíåíèå ïðåä-ïðåäûäóùåãî ñîñòîÿíèÿ
EncPrev = EncCur; //ñîõðàíåíèå ïðåäûäóùåãî ñîñòîÿíèÿ
}
}
//----------------------------------------------------------------------------
Последний раз редактировалось s64; 19.04.2013 в 12:50.
Причина: что то на русском текст не выводится...
|
|
|
|
19.04.2013, 13:31
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Коллеги, пользуйтесь, пожалуйста тегами CODE (Значок # в панели инструментов при создании/редактировании поста). Легче воспринимать ваши листинги. Особенно, когда они представляют собой всю программу (это не к автору вопроса).
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
19.04.2013, 13:34
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Сообщение от _Ross_
|
Насчёт "вечного" цикла в прерывании- ничего страшного.
|
Мое дело посоветовать. Следовать совету или нет - ваше дело. Равно, как и ваши будущие проблемы.
Лично я бы предпочел другой способ индикации критического состояние, кроме "завешивания" тела программы. Но если тело пусто и вся программа состоит из одних прерываний, тут я пас. Думайте сами.
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
19.04.2013, 16:46
|
|
Временная регистрация
Регистрация: 12.02.2010
Сообщений: 67
Сказал спасибо: 27
Сказали Спасибо 45 раз(а) в 15 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Спасибо.
Просто задача цикла была не допустить счёта покуда объект не вышел из зоны датчика. Теперь думаю так: Попросту отказаться от прерываний и фиксировать изменения в реальном времени, в цикле. С проверкой флагов. А в прерывании по таймеру только переключать разряды индикации.
Последний раз редактировалось _Ross_; 19.04.2013 в 16:50.
|
|
|
|
20.04.2013, 06:58
|
|
Заблокирован
Регистрация: 23.09.2007
Сообщений: 761
Сказал спасибо: 84
Сказали Спасибо 352 раз(а) в 151 сообщении(ях)
|
Re: Алгоритмы фильтра дребезга avr
Как вариант - сделайте прерывание по таймеру с периодом t, в n раз (5-10) меньшим времени срабатывания датчика. То есть, если у вас датчик работает в цикле 990 мсек выкл -10 мсек вкл, нужно сделать прерывание 1-2 мсек. В этом прерывании сделайте проверку пина процессора, соответствующего входу датчика. При наличии на входе сработки датчика инкрементируйте переменную х. При отсутствии на входе сработки датчика записывайте у=х, если х!=0, и обнуляйте х. Соответственно, если у сильно меньше или больше n - ошибка. По у можно вычислить скорость вращения, девиацию, и ещё много чего полезного. Недостаток - время выполнения подпрограмм всех прерываний не должно быть больше или равно t. Зато можно легко сделать анализ, вплоть до нечёткой логики. Прерывания типа int0, как мне кажется, не для этого случая.
Последний раз редактировалось kosmos440o; 20.04.2013 в 07:15.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 00:26.
|
|