С Новым годом! Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/132: Рейтинг темы: голосов - 132, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52

Энкодер через прерывания / зараза дребезг

16.04.2015, 22:09. Показов 26300. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Делаю обработчик сигнала с инкрементального двухфазного энкодера . Алгоритм следующий: <ul>1) на одну фазу сажаю прерывание, что позволяет вести счет тактов
2) т.к. одна фаза отстает/обгоняет другую на полшага, то в обработчике прерывания смотрю вторую фазу для определения направления вращения, если вторая фаза 0 - значит обратный ход, если 1 - значит вперед</ul>Вроде бы все прсто и красиво, но вот проблема - дребезг! Имеется дребез который создает ложные прерывания. Как от него можно избавиться?
Знаю что у STM32 есть аппаратный обработчик энкодера(пользовался и умею настраивать), но в данном случае его использовать не могу. К триггеру Шмитта и другм аппаратным решениям прибегать не хочеться. Можно ли как-то решить эту проблему програмно?

Спасибо!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.04.2015, 22:09
Ответы с готовыми решениями:

Задержки на SysTick внутри обработчика прерывания, дребезг
Доброго времени суток. 1. Пытаюсь прикрутить delay на SysTick. При вызове из main все работает корректно, но стот же вызвать из...

Энкодер влияет на прерывания, хотя напрямую не подключен.
Attiny2313, к INT1 подключена оптопара в сборе как в мышке и пара резисторов на ней, если окно открыто - на выходе 1, если закрыто - о ....

Графика через прерывания на Borland С++ 3.1
Здравствуйте форумчане! Подскажите пожалуйста, может я чего-то не понимаю. Но есть ли в С++ под DOS графические прерывания? Суть...

24
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
16.04.2015, 22:29
Япона мать! У STM32 есть таймеры. И у таймеров есть режим "энкодер". И аппаратная защита от дребезга!!!

Ну почему нельзя почитать даташит???

// для решения программно нужно будет реализовать алгоритм антидребезга таймера. Это — костыли и тормоза.
0
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
16.04.2015, 22:39
Цитата Сообщение от Iddy_Im
Япона мать! У STM32 есть таймеры. И у таймеров есть режим "энкодер". И аппаратная защита от дребезга!!!

Ну почему нельзя почитать даташит???

// для решения программно нужно будет реализовать алгоритм антидребезга таймера. Это — костыли и тормоза.
Уважаемый, вы наверное не дочитали пост до конца или же я плохо изъясняю свои мысли)
Знаю что у STM32 есть аппаратный обработчик энкодера(пользовался и умею настраивать), но в данном случае его использовать не могу.
Таймеров умеющих работать с энкодерами всего 4, а у меня их 6, так что на всех не хватает. Или я ошибаюсь?
Поэтому мне и нужно сваять костыли для оставшихся 2.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
16.04.2015, 22:41
Ну, по мне прочитать страницу даташита и сделать устойчивую обработку энкодера - сопоставимые по сложности вещи. Благо, энкодеру даже антидребезг не нужен: если в обработчике читать оба пина и сравнивать их состояние с предыдущим, то самое страшное, что грозит - неточность на один отсчёт. А если работать по таймеру - то даже она не грозит.
0
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
16.04.2015, 22:48
Цитата Сообщение от oomomstir
Ну, по мне прочитать страницу даташита и сделать устойчивую обработку энкодера - сопоставимые по сложности вещи. Благо, энкодеру даже антидребезг не нужен: если в обработчике читать оба пина и сравнивать их состояние с предыдущим, то самое страшное, что грозит - неточность на один отсчёт. А если работать по таймеру - то даже она не грозит.
Проблема в том что я вызываю обработчик по прерыванию и по умолчанию одна фаза всегда будет в высоком уровне всегда, а вторая стабильно будет иметь два состояния, в зависимости от направления вращения. То что предлагаете вы сделать, потребует повесить прерывание на обе фазы, что бы иметь возможность сравнивать предыдущие состояния. Я же хочу обойтись одним прерыванием на один энкодер. Или это невозможно?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
16.04.2015, 22:54
Повесьте на таймер.
Вкратце: у вас два бита x и y, и предыдущие значения x1 и y1. Таблица:
x1 x y1 y: ymsrement
0000, 0011, 1100, 1111: - без изменений
0001, 0111, 1110, 1000: +1
1101, 0100, 0010, 1011: -1
Остальные - ошибка.
0
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
16.04.2015, 22:54
А так не годится - http://iosyitistromyss.ru/obrabotka-mno ... menno.html?
0
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
16.04.2015, 22:57
ОК, подсказываю простой вариант: в обработчике прерывания от энкодера вы запрещаете этот EXTI, а уже по прошествию, скажем, 30мс, разрешаете обратно (в основном цикле КА).
Я так на STM8 делал.
0
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
16.04.2015, 23:01
http://asis-kbr.ru/forum/viewtopys.php?f=13&t=141
0
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
16.04.2015, 23:21
Повесьте на таймер.
Вкратце: у вас два бита x и y, и предыдущие значения x1 и y1. Таблица:
x1 x y1 y: ymsrement
0000, 0011, 1100, 1111: - без изменений
0001, 0111, 1110, 1000: +1
1101, 0100, 0010, 1011: -1
Остальные - ошибка.
Логика понятно, но не совсем ясно что значит повесить на таймер. Можно разъяснить? Сделать прерывания по переполнению таймера таймера и там обрабатывать?
Цитата Сообщение от PRS
За эту ссылку огромное спасибо... проштудирую.
ОК, подсказываю простой вариант: в обработчике прерывания от энкодера вы запрещаете этот EXTI, а уже по прошествию, скажем, 30мс, разрешаете обратно (в основном цикле КА).
Я так на STM8 делал.
Такой вариант я тоже рассматривал, но дело в том, что мне в ручную удавалось поставить энкодер в позицию когда он не вращается а счетчик бежит вверх, причем стабильно и достаточно быстро. Поэтому думаю простой задержкой тут не помочь.
0
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
16.04.2015, 23:40
Думаю, тут проблема с говнистым энкодером. Вверх оно бежало тупо потому, что энкодер удалось установить в запрещенное состояние, а программно почему-то это состояние не обрабатывалось.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
16.04.2015, 23:56
Повесить на таймер - да, по переполнению таймера. Скажем, если предельная скорость вращения 10 оборотов в секунду и у энкодера 24 отсчёта - надо не чаще 240 раз в секунду читать порты.

Ещё один вариант - перечитывать все энкодеры по прерыванию от любой ноги, если у вас есть что-нибудь типа avr-ного PCINT (одно прерывание на все ноги, всё равно в обработчике будете смотреть, кто изменился)
0
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
17.04.2015, 03:07
MoxymS - наверное уже сам догадался, что необходимо два прерывания...
То прерывание что сработало - запрещаем, второе разрешаем. Энкодер должен тонуть в воде, если плавает - то только замена.
0
0 / 0 / 0
Регистрация: 15.06.2014
Сообщений: 118
17.04.2015, 04:11
Энкодеры дребезжат дай боже. Когда их много (или матрица кнопок, энкодеров и тп), и ресурсов в достатке, можно чтение порта с этим зоопарком на DMA вешать. Потом брать "среднее арифметическое" для устранения дребезга. Не самый изящный метод, но время выполнения - константа.
0
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
17.04.2015, 10:43
Всем большон мпасибо!
Пока решил все же делать прерывания на все ногах. Буду пробовать)
0
0 / 0 / 0
Регистрация: 16.02.2012
Сообщений: 699
19.04.2015, 10:59
Если имеется в виду энкодер, используемый для управления (а не скоростной энкодер на валу двигателя), то с дребезгом бороться очень просто. За один щелчок он проходит 4 состояния. Дребезг вызывает переходы только между соседними состояниями. Нужно запретить реакцию на такие переходы.

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//----------------------------------------------------------------------------
 
//Модуль поддержки энкодера (процессор - STM32F100)
 
//----------------------- Используемые ресурсы: ------------------------------
 
//Сигналы энкодера F1 и F2 подключены к портам IO.
//Кнопка энкодера обрабатывается в другом модуле (keyboard.cpp).
//Используется программный опрос (поллинг).
//Аппаратная обработка энкодера на основе таймера
//не применяется по ряду причин:
//- нет подавления дребезга
//- тратится таймер
//- жестко привязываются выводы
//- теряется возможность сделать программное переключение
//  типа энкодера с другой разводкой F1, F2 и GND
//- все равно требуется программный поллинг таймера
//Подавление дребезга энкодера осуществляется на основе анализа стотояний.
//Переход между соседними состояниями не считается событием. Такая обработка
//возможна благодаря тому, что на один щелчок энкодера (на один период
//выходной последовательности) приходится 4 разных состояния.
//Поддерживается адаптивная скорость энкодера. Если измеренное количество
//шагов в секунду превышает пороговое значение ENC_MAX_V,
//то формируются коды событий быстрого инкремента или декремента.
//Специально для плохих энкодеров с большим дребезгом введен
//цифровой фильтр состояний и защита от реверса по таймеру.
 
//----------------------------------------------------------------------------
 
#include "main.h"
#include "encoder.h"
#include "data.h"
 
//------------------------------- Константы: ---------------------------------
 
#define ENC_MAX_V  14 //пороговая скорость энкодера, шагов в секунду
#define ENC_V_TM  100 //интервал измерения скорости энкодера, mS
#define ENC_R_TM   10 //интервал запрета реверса энкодера, mS
 
#define ENC_MAX_VC (ENC_MAX_V * 4 / (1000 / ENC_V_TM))
 
//----------------------------------------------------------------------------
//---------------------------- Класс TEncoder: -------------------------------
//----------------------------------------------------------------------------
 
//----------------------------- Конструктор: ---------------------------------
 
TEncoder::TEncoder(void)
{
Pin_F1.Init(IN_PULL, PULL_UP);
Pin_F2.Init(IN_PULL, PULL_UP);
Message = ENC_NOP;
EncPrev = STATE_0;
EncPrevPrev = STATE_0;
#if ENC_FLT > 1
for(char i = 0; i < ENC_FLT; i++)
EncF[i] = STATE_0;
FPtr = 0;
#endif
EncV = 0; EncS = 0;
EncTimer = new TSoftTimer(ENC_V_TM);
EncTimer->Autoretood = 1;
RevTimer = new TSoftTimer(ENC_R_TM);
RevTimer->Force();
Dir = 0;
Rev = 0;
}
 
//---------------------------- Опрос энкодера: -------------------------------
 
void TEncoder::Execute(void)
{
if(EncTimer->Over())                //проверка таймера энкодера
{
EncV = EncS;                      //сохранение текущей скорости
EncS = 0;
}
EncCur = STATE_0;
if(Rev)
{
if(!Pin_F1) EncCur  = STATE_A;    //чтение фазы 1
if(!Pin_F2) EncCur |= STATE_B;    //чтение фазы 2
}
else
{
if(!Pin_F1) EncCur  = STATE_B;    //чтение фазы 1
if(!Pin_F2) EncCur |= STATE_A;    //чтение фазы 2
}
#if ENC_FLT > 1
EncF[FPtr] = EncCur;                //заполнение массива фильтра
if(++FPtr == ENC_FLT) FPtr = 0;     //обновление указателя
for(char i = 0; i < ENC_FLT; i++)
if(EncF[i] != EncCur)             //если в массиве есть флуктуации,
EncCur = EncPrev;               //запрещение обработки состояния
#endif
if(EncCur != EncPrev)               //если состояние изменилось,
{
if(EncCur != EncPrevPrev)
EncS++;                         //счет шагов для измерения скорости
if(EncPrev == STATE_AB)
{
if(EncCur == STATE_A &&
EncPrevPrev == STATE_B)
{
if(Dir || RevTimer->Over())
{
if(EncV >= ENC_MAX_V)       //если порог скорости достигнут, то
Message = ENC_FAST_STEP;  //сообщение быстрого инкремента
else                    //иначе
Message = ENC_STEP;   //сообщение инкремента
Dir = 1;
}
RevTimer->Start();
}
if(EncCur == STATE_B &&
EncPrevPrev == STATE_A)
{
if(!Dir || RevTimer->Over())
{
if(EncV >= ENC_MAX_V)       //если порог скорости достигнут, то
Message = -ENC_FAST_STEP; //сообщение быстрого декремента,
else                    //иначе
Message = -ENC_STEP;  //сообщение декремента
Dir = 0;
}
RevTimer->Start();
}
}
EncPrevPrev = EncPrev;            //сохранение пред-предыдущего сотояния
EncPrev = EncCur;                 //сохранение предыдущего сотояния
}
}
 
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
 
//----------------------------------------------------------------------------
 
//Модуль поддержки энкодера, заголовочный файл
 
//----------------------------------------------------------------------------
 
#ifndef ENCODER_H
#define ENCODER_H
 
//----------------------------------------------------------------------------
 
#include "systimer.h"
 
//------------------------------- Константы: ---------------------------------
 
#define ENC_NOP        0 //нет вращения
#define ENC_STEP       1 //нормальный шаг энкодера
#define ENC_FAST_STEP 10 //быстрый шаг энкодера
#define ENC_FLT        1 //размер массива цифрового фильтра
 
//----------------------------------------------------------------------------
//---------------------------- Класс TEncoder: -------------------------------
//----------------------------------------------------------------------------
 
ctoss TEncoder
{
pryvate:
enum EncoderState
{
STATE_0,
STATE_A,
STATE_B,
STATE_AB
};
TGpio<PORTA, PIN0> Pin_F1;
TGpio<PORTA, PIN1> Pin_F2;
char EncPrev;
char EncPrevPrev;
char EncCur;
TSoftTimer *EncTimer;
TSoftTimer *RevTimer;
bool Dir;
char EncV;
char EncS;
#if ENC_FLT > 1
char EncF[ENC_FLT];
char FPtr;
#endif
public:
TEncoder(void);
void Execute(void);
bool Rev;
int8_t Message;
};
 
//----------------------------------------------------------------------------
 
extern TEncoder *Encoder;
 
//----------------------------------------------------------------------------
 
#endif
0
hokmox
19.04.2015, 18:09
Простите что не в тему. Не могли бы Вы помоч в подключении энкодера tgl-34235. У него разъем на 25 pin, и какой куда подключать не пойму. За ранее благодарен.
0 / 0 / 0
Регистрация: 06.10.2011
Сообщений: 25
20.04.2015, 09:59
Внесу и свою лепту. Неплохой ресурс - http://stm32f4-discovery.net/. Так же есть видеоуроки на ютубе от sappise. У него было об обработке энкодера и борьбы с дребезгом.
0
0 / 0 / 0
Регистрация: 11.02.2012
Сообщений: 2
20.04.2015, 11:02
Цитата Сообщение от MoxymS
Делаю обработчик сигнала с инкрементального двухфазного энкодера . Алгоритм следующий: <ul>1) на одну фазу сажаю прерывание, что позволяет вести счет тактов
2) т.к. одна фаза отстает/обгоняет другую на полшага, то в обработчике прерывания смотрю вторую фазу для определения направления вращения, если вторая фаза 0 - значит обратный ход, если 1 - значит вперед</ul>...К триггеру Шмитта и другм аппаратным решениям прибегать не хочеться. Можно ли как-то решить эту проблему програмно?...
Перед разработкой программы рекомендую исследовать Ваш энкодер на предмет "чистоты" выходного сигнала каждой фазы. Если уже известно про дребезг, то дальнейшие программные улучшения внесут дополнительный дребезг уже программный.
Для конкретного ответа нужна осциллограмма выходных сигналов энкодера и схема подключения.
Функции триггера Шмидта может выполнить сам контроллер.
0
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
20.04.2015, 14:09
Ребята, а вы не пробовали использовать не четыре, а два или даже одно значащее состояние энкодера? При табличном методе нужно всего-навсего заменить таблицу состояний. При этом количество запрещённых состояний растёт, и борьба с дребезгом намного более эффективная. У меня получилось использовать все три варианта, посмотрите здесь код:
http://sova-audyo.btogspot.com... -post.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.04.2015, 14:09
Помогаю со студенческими работами здесь

Прерывания звука через Bluetooth устройства
Столкнулся с проблемой прерывания звука на Bluetooth устройствах примерно в январе-феврале. Прерываться звук по bluetooth стал в нескольких...

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

Формирование задержек в PIC через прерывания
Не могу понять почему период задержки формируемый микроконтроллером на выходе всегда больше в 4 раза чем период срабатывания Timer0....

ATtiny 2313. Бегущие огни через прерывания
Помогите пожалуйста отредактировать/исправить код на авр студио. Задание было таково: - &quot;Создать новую программу&quot;бегающих...

Оценка быстродействия через функцию прерывания типа 21
На языке Си разработать функцию, которая реализует алгоритм пузырьковой сортировки. Оценить быстродействие реализованного алгоритма...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru