Страница 1 из 4
Энкодер и STM32
Добавлено: Пн окт 04, 2021 20:46:12
auric
Тема изъезженная, но все же даже поиск по форуму не дал ответа...до этого все откладывал работу с энкодером, а теперь вот пришлось, давно с ними мучаюсь - самая главная проблема - дребезг, а если еще и частотник рядом фонит, вообще беда. Видел поведение даже на готовых приборах, когда например на дельтовских контролерах подаешь на один из входов "джиттер" (дребезг, меандр), а он берет и считает, а по идее интерфейс должен работать с самозащитой и не пропускать такое. По идее читая документацию на STM32 даже табличку такую видел, есть сигнал на входе измеряемом - считаем вверх при переднем фронте, и вниз при заднем, соответственно меняем направление счета только если между фронтами сменился сигнал на втором. Но вот то ли я не пойму, как настроить таймер, то ли чего, но вот считает он у меня по одному входу свободно вниз и все, а по идее должен "дрожжать" около одного значения, я ведь не с настоящим энкодером экспериментирую, один из входов меняю, второй нет. По идее режим, когда счет и по фронтам и по спадам да на обоих входах счетных не имеет защиты, хотя опять же читаю RM вижу волшебные графики типа Figure 93 и не особо верю, если конечно там не реализована защитная логика проверки прихода фронта с одного и только тогда зачитывается фронт на другом, а если спад пришел без смены на втором, значит не прибавляем а вычитаем, короче лишняя логика, которую должно что-то обрабатывать, а это сильно усложняет устройство. и сомневаюсь, что это реализовано. Еще не почему таймер загружает в CNT регистр ARR, по идее таймер без интерфейса энкодера считает с нуля и до ARR, а тут какая-то лажа, считает по одному входу и только вниз, хотя вроде как настройки UD/DOWN. Пробовал два варианта, может кто что подскажет?
вот код инициализации, сам код опроса прост как тапок - читаем TIM2->CNT:
Код: Выделить всё
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// Заполняем настройки по дефолту
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
// Clock prescaler 72M/1 Запускаем таймер на тактовой частоте 72 MHz
TIM_TimeBaseStructure.TIM_Prescaler= 1;
// Частоту дополнительно не делим TIM_CKD_DIV1=0
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
// Считаем вверх и вниз
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down | TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 65536;
// Инициализируем TIM3
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// Clear overflow interrupt flag
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ClearFlag(TIM3, TIM_FLAG_CC1);
// Disable interrupt for Update Event
TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);
TIM_ITConfig(TIM3,TIM_IT_CC1,DISABLE);
/* Считать будем все переходы лог. уровня с обоих каналов */
//TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge, TIM_ICPolarity_BothEdge);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI1, TIM_ICPolarity_BothEdge, TIM_ICPolarity_BothEdge);
TIM_Cmd(TIM3, ENABLE);
Интересует оба режима: двойной счет, когда как пишут в RM счет идет по одному сигналу и по фронтам и по спадам, и четверной, когда по обоим сигналам и по фронтам и спадам, интересует, как прошел опыт подачи меандра на один вход без изменения второго на обоих режимах (был ли счет или просто дребезг в районе одного значения, в оба ли направления счет).
Re: Энкодер и STM32
Добавлено: Пн окт 04, 2021 20:58:36
Andrey_B
auric, если у вас энкодер это элемент интерфейса с человеком, проще обойти все эти проблемы и сделать софтверно. При быстродействии STM32 ресурсов это практически не займёт. Если у вас быстродействующий датчик, тогда да, оправданно заморачиваться с аппаратной поддержкой. Добиться устойчивой работы не просто. Что касается вашего кода, то по моему в TIM_TimeBaseStructure.TIM_Period надо писать 65535, а не 65536.
Re: Энкодер и STM32
Добавлено: Пн окт 04, 2021 21:08:09
Eddy_Em
Работал и с оптическими, и с
дешевыми "реостатоподобными" энкодерами. Да, дребезг бывал, но не в такой же степени, чтобы влиять на счет более-менее весомо! Подумаешь, дрожит младший бит!
Re: Энкодер и STM32
Добавлено: Пн окт 04, 2021 21:13:46
auric
[uquote="Andrey_B",url="/forum/viewtopic.php?p=4100929#p4100929"]
auric, если у вас энкодер это элемент интерфейса с человеком, проще обойти все эти проблемы и сделать софтверно. При быстродействии STM32 ресурсов это практически не займёт. Если у вас быстродействующий датчик, тогда да, оправданно заморачиваться с аппаратной поддержкой. Добиться устойчивой работы не просто. Что касается вашего кода, то по моему в TIM_TimeBaseStructure.TIM_Period надо писать 65535, а не 65536.[/uquote]
Быстродействие нужно, а по поводу значения это я сам пока код вставлял ручками поправил, там была переменная, но суть одна писал туда 20000, с 20000 и начинался счет, писал 10, в CNT это же читал.
Добавлено after 3 minutes 55 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4100939#p4100939"]Работал и с оптическими, и с
дешевыми "реостатоподобными" энкодерами. Да, дребезг бывал, но не в такой же степени, чтобы влиять на счет более-менее весомо! Подумаешь, дрожит младший бит![/uquote]
Дребезг в чистом виде не приводит к ошибке счета, но если интерфейс неправильный - реально счет идет например по одному каналу, хотя второй не меняется, у меня по крайней мере так и с STM счас и как уже писал выше на готовых ПЛК от фирмы Delta видел которые SV2.
Re: Энкодер и STM32
Добавлено: Пн окт 04, 2021 21:19:21
Andrey_B
auric, вот мой код, счёт в обоих направлениях:
Код: Выделить всё
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // тактирование врубаем
TIM_DeInit(TIM3); // в состояние "по умолчанию"
TIM_TimeBaseInitStructure.TIM_Period = 65535; // до скольки крутим
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStructure.TIM_Prescaler = 0x0000; // Предделитель учитывается как TIM_Prescaler+1, поэтому отнимаем 1
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_PrescalerConfig(TIM3, 1, TIM_PSCReloadMode_Immediate);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI1, TIM_ICPolarity_Falling, TIM_ICPolarity_Rising);
TIM_Cmd(TIM3, ENABLE);
a = TIM3->CNT; // читаем значение энкодера
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 01:19:47
Eddy_Em
[uquote="auric",url="/forum/viewtopic.php?p=4100940#p4100940"]если интерфейс неправильный[/uquote]
, то энкодер поврежден → нужно заменить на нормальный.
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 10:23:06
auric
[uquote="Andrey_B",url="/forum/viewtopic.php?p=4100944#p4100944"]
auric, вот мой код, счёт в обоих направлениях:
Код: Выделить всё
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // тактирование врубаем
TIM_DeInit(TIM3); // в состояние "по умолчанию"
TIM_TimeBaseInitStructure.TIM_Period = 65535; // до скольки крутим
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStructure.TIM_Prescaler = 0x0000; // Предделитель учитывается как TIM_Prescaler+1, поэтому отнимаем 1
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_PrescalerConfig(TIM3, 1, TIM_PSCReloadMode_Immediate);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI1, TIM_ICPolarity_Falling, TIM_ICPolarity_Rising);
TIM_Cmd(TIM3, ENABLE);
a = TIM3->CNT; // читаем значение энкодера
[/uquote]
Код попробовал - все примерно то же - загрузка значения ARR, счет правда теперь идет в обоих направлениях (обратно если на второй вход дать "единицу"), но если дать на второй вход 0 а на первый подавать импульсы - идет счет - а не должен, это обычный джиттер, я даже проверил на других ПЛК, отрабатывается правильно, а тут нет.
Добавлено after 2 minutes 36 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4100988#p4100988"][uquote="auric",url="/forum/viewtopic.php?p=4100940#p4100940"]если интерфейс неправильный[/uquote]
, то энкодер поврежден → нужно заменить на нормальный.[/uquote]
Слушай, ну не тот случай - не надо мне про неисправные энкодеры - нет такого устройства, которое избавит от дребезга контактов, тк у оптопар гистерезис хоть и есть , но небольшой, никто не гарантирует, что помеха не превысит этот гистререзис, да и вообще чисто физически бывает, что перемещение будет тоже с дребезгом, и будет все равно оптопара давать на одном входе меандр, а другой оставит без изменений, и тут на тебе - контроллер считает импульсы - а должен один добавить и тут же по спаду убавить. Что я по сути и имитирую - так сказать стресс-тест, который законченные устройства проходят (правда тоже не все), а реализованный мной интерфейс нет, вот и пытаюсь понять это интерфейс такой или все-таки настройки не те.
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 12:29:39
Eddy_Em
[uquote="auric",url="/forum/viewtopic.php?p=4101050#p4101050"]и тут на тебе - контроллер считает импульсы - а должен один добавить и тут же по спаду убавить.[/uquote]
Значит, у тебя таймер неправильно настроен. Т.к. в такой ситуации он должен просто на ±1 дрожать!
Я в этих ваших калокубах не понимаю. Поэтому в код и не смотрю. Ну и да: кто сказал, что в самом калокубе нет ошибок?
Привожу код из сниппета:
Код: Выделить всё
static inline void timers_setup(){
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
/* (1) Configure TI1FP1 on TI1 (CC1S = 01)
configure TI1FP2 on TI2 (CC2S = 01) */
/* (2) Configure TI1FP1 and TI1FP2 non inverted (CC1P = CC2P = 0, reset value) */
/* (3) Configure both inputs are active on both rising and falling edges
(SMS = 011), set external trigger filter to f_DTS/8, N=6 (ETF=1000) */
/* (4) Enable the counter by writing CEN=1 in the TIMx_CR1 register. */
TIM3->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; /* (1)*/
/* (2) */
TIM3->SMCR = TIM_SMCR_ETF_3 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; /* (3) */
// enable update interrupt
TIM3->DIER = TIM_DIER_UIE;
// set ARR to 79 - generate interrupt each 80 counts (one revolution)
TIM3->ARR = 79;
// enable timer
TIM3->CR1 = TIM_CR1_CEN; /* (4) */
NVIC_EnableIRQ(TIM3_IRQn);
}
Фильтрация настроена?
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 13:25:54
auric
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4101099#p4101099"][uquote="auric",url="/forum/viewtopic.php?p=4101050#p4101050"]и тут на тебе - контроллер считает импульсы - а должен один добавить и тут же по спаду убавить.[/uquote]
Значит, у тебя таймер неправильно настроен. Т.к. в такой ситуации он должен просто на ±1 дрожать!
Я в этих ваших калокубах не понимаю. Поэтому в код и не смотрю. Ну и да: кто сказал, что в самом калокубе нет ошибок?
Привожу код из сниппета:
Код: Выделить всё
static inline void timers_setup(){
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
/* (1) Configure TI1FP1 on TI1 (CC1S = 01)
configure TI1FP2 on TI2 (CC2S = 01) */
/* (2) Configure TI1FP1 and TI1FP2 non inverted (CC1P = CC2P = 0, reset value) */
/* (3) Configure both inputs are active on both rising and falling edges
(SMS = 011), set external trigger filter to f_DTS/8, N=6 (ETF=1000) */
/* (4) Enable the counter by writing CEN=1 in the TIMx_CR1 register. */
TIM3->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; /* (1)*/
/* (2) */
TIM3->SMCR = TIM_SMCR_ETF_3 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; /* (3) */
// enable update interrupt
TIM3->DIER = TIM_DIER_UIE;
// set ARR to 79 - generate interrupt each 80 counts (one revolution)
TIM3->ARR = 79;
// enable timer
TIM3->CR1 = TIM_CR1_CEN; /* (4) */
NVIC_EnableIRQ(TIM3_IRQn);
}
Фильтрация настроена?[/uquote]
Ну код не из CUBE, но не суть, в принципе да я могу и без CMSIS сделать, главное цель - если поведение было другим, надо думать, что не так здесь. А входы какую настройку имеют? Если память не изменяет AF альтернативная функция только для выходов, для входов можно либо float либо подтяжку к питанию?
Добавлено after 28 minutes 58 seconds:
не...не работает как надо, пробовал
Код: Выделить всё
TIM3->SMCR = TIM_SMCR_ETF_3 | TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; /* (3) */
и
Код: Выделить всё
TIM3->SMCR = TIM_SMCR_ETF_3 | TIM_SMCR_SMS_0; /* (3) */
В первом случае считает первым входом без второго вверх, вторым без первого вниз.
Во втором случае считает только первым входом в зависимости от состояния второго, но тоже без проблем насчитывает себе лишнего без изменения состояния второго.
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 13:35:55
Eddy_Em
А входы какую настройку имеют?
Я ж в самом своем первом сообщении давал ссылку на код.
Вот:
Код: Выделить всё
GPIOA->MODER = GPIO_MODER_MODER4_O | GPIO_MODER_MODER6_AF | GPIO_MODER_MODER7_AF;
GPIOA->AFR[0] = (GPIOA->AFR[0] &~ (GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)) \
| (1 << (6 * 4)) | (1 << (7 * 4));
Просто альтернативные функции, никаких подтяжек там не нужно.
А что там на осциллограмме творится, хотелось бы посмотреть? Можно попробовать еще грубей фильтр сделать.
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 13:59:13
auric
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4101136#p4101136"]
А входы какую настройку имеют?
Я ж в самом своем первом сообщении давал ссылку на код.
Вот:
Код: Выделить всё
GPIOA->MODER = GPIO_MODER_MODER4_O | GPIO_MODER_MODER6_AF | GPIO_MODER_MODER7_AF;
GPIOA->AFR[0] = (GPIOA->AFR[0] &~ (GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)) \
| (1 << (6 * 4)) | (1 << (7 * 4));
Просто альтернативные функции, никаких подтяжек там не нужно.
А что там на осциллограмме творится, хотелось бы посмотреть? Можно попробовать еще грубей фильтр сделать.[/uquote]
нашел проблему, не настраивал фильтры совсем, а видимо это не формировало задние фронты (спады).
Код: Выделить всё
TIM_ICInitTypeDef TIM_ICInitStructure;
//Enter the content in the structure by default
TIM_ICStructInit(&TIM_ICInitStructure);
//filter value
TIM_ICInitStructure.TIM_ICFilter = 6;
//Initialize the specified parameters in TIM_ICInitStructure TIM3
TIM_ICInit(TIM3, &TIM_ICInitStructure);
а входы все-таки так:
Код: Выделить всё
/* Configure pin PA6, PA7*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//Каналы 1 и 2 таймера TIM3 - на вход, подтянуть к питанию
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //вход с подтяжкой к питанию
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 14:55:58
Eddy_Em
нашел проблему
Не нашел, потому что это эквивалентно:
Естественно, это не работало, если ты оставил все остальное по-кальски, как и было!
В общем, советую не тыкать все, что попало, наугад, а почитать таки документацию!
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 21:24:38
auric
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4101170#p4101170"]
нашел проблему
Не нашел, потому что это эквивалентно:
Естественно, это не работало, если ты оставил все остальное по-кальски, как и было!
В общем, советую не тыкать все, что попало, наугад, а почитать таки документацию![/uquote]
Возможно, но именно добавив указанные строки к коду система заработала как надо. Главное заработала.
У меня теперь новый вопрос созрел, допустим я хочу сделать прерывание, но для отслеживания мне недостаточно 16 бит. Допустим таймер генерирует прерывание по достижению arr, мы инкрементируюм в прерывании дополнительный счетчик. Но как быть с обратным счетом? Когда счетчик досчитает до нуля (и продолжит дальше) , использовать capture&compare? Ведь мне не нужно новое прерывание по update, я не могу определить каким направлением оно вызвано. Короче кто делал счетчики с большей разрядностью, как поступали идеологически?
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 21:34:58
Eddy_Em
Либо связать с этим таймером другой, либо в прерываниях вести счет.
Re: Энкодер и STM32
Добавлено: Вт окт 05, 2021 21:40:38
auric
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4101386#p4101386"]Либо связать с этим таймером другой, либо в прерываниях вести счет.[/uquote]
Со вторым таймером не очень хочется тк свободных мало, все заняты. С прерываниями волнует обратный счет, при переходе 0->ARR нужно тоже прерывание и со стопроцентной информацией о том, что это именно из нуля, а не (ARR-1) ->ARR. Пока затрудняюсь, что использовать.
Re: Энкодер и STM32
Добавлено: Ср окт 13, 2021 21:06:26
auric
на камне STM32F103 таймеров всего 4, а мне нужно будет по два таймера на канал, а еще ШИМ делать, так что вопрос актуальный, не пойму, как можно исхитриться, чтобы определить, в какую сторону было переполнение не каскадируя таймеры.
Я при переполнении вверх добавляю к каскадному регистру 65536, а при переполнении вниз вычитаю тоже 65536.
Бит DIR не помогает (TIM3->CR1 & TIM_CR1_DIR), пока в прерывание падает, может сигнал поменяться и бит тоже.
Пробовал контролировать на считывание вспомогательного значения, чтобы дважды не добавлял - помогает от двойного счета, но полностью нет (ну типа (cnt_dir != 1) если вперед или (cnt_dir != 2) если назад, сам их проставляю в соответствии с проверками и пока не пройдусь в обычной программе в диапазоне (TIM3->CNT > 16383)&&(TIM3->CNT < 49150) и не сброшу в 0, второй раз аналогичную операцию не проведу). Но это не дает возможность само направление определить.
Еще контролирую в прерывании значение счетчика, если (TIM3->CNT > 32767), получается переполнение назад и наоборот (TIM3->CNT < 32767) то вперед, если считать, что не успеет энкодер насчитать больше половины диапазона за прерывание. Но получается пока в прерывании кручусь, пока дойду до сравнения импульс может обратный прилететь, а значение счетчика поменяется например с 65535 на 0, хотя изначально прерывание было в минус, система не поймет и сделает счет каскада в плюс. Уже и старое значение запоминал и контролировал переход - все равно ошибку могу рукой набить, когда даю джиттер в районе переполнения вокруг нуля.
Код: Выделить всё
if ((CNT_TIM3_old==1)&&(cnt_dir != 1)&&(TIM3->CNT > 32767)) //CNT_TIM3_old 0 база, 1 - близкое к нулю, 65534 - близкое к переполнению вверх
CNT_Val_Reg = (s32)(CNT_Val_Reg - 65536), cnt_dir = 1; //0 прошли середину диапазона CNT, 1 назад, 2 вперед
if ((CNT_TIM3_old==65534)&&(cnt_dir != 2)&&(TIM3->CNT < 32767))
CNT_Val_Reg = (s32)(CNT_Val_Reg + 65536), cnt_dir = 2; //0 прошли середину диапазона CNT, 1 назад, 2 вперед
Re: Энкодер и STM32
Добавлено: Ср окт 13, 2021 21:37:16
Eddy_Em
[uquote="auric",url="/forum/viewtopic.php?p=4101392#p4101392"]Пока затрудняюсь, что использовать.[/uquote]
Флаг TIM_CR1_DIR покажет, в какую сторону было переполнение. Так что, считать несложно.
Вот если в районе полного оборота будут туда-сюда крутить энкодер, да, получится жопа… Надо подумать, как это решать. Единственная надежда, что человеку такое сделать физически невозможно: слишком шустро пришлось бы туда-сюда дергать энкодер.
Я в качестве пробы
вот такое наваял. А сейчас мне нужно постепенно разработать управлялку тремя шаговиками с оптическими энкодерами. Других дел полно, поэтому эта работа будет очень медленно продвигаться, иначе уже к выходным я мог бы пример показать.
Re: Энкодер и STM32
Добавлено: Чт окт 14, 2021 06:28:43
Dimon456
Хммм
Спойлер
Код: Выделить всё
// Посмотреть относительное перемещение по сравнению с прошлым вызовом
int16_t enc_Get(void)
{
// Для хранения предыдущего значения счетчика
static uint16_t CNT_last = 0;
// Текущее значение, чтоб только один раз было запрошено
uint16_t CNT_now = TIM3->CNT;
// Посчитаем перемещение
int16_t CNT_diff = (int16_t)(CNT_now - CNT_last);
// Сохраним текущее значение как предыдущее
CNT_last = CNT_now;
// Вернем перемещение
return CNT_diff;
}
Код: Выделить всё
temp = (int16_t )enc_Get();
if (temp < 0) {
x--;
}
if (temp > 0) {
x++;
}
Этому коду всё равно, было переполнение регистра-счётчика или же его не было, разница будет верной.
Правда, такое будет только если TIMx_ARR = 0xFFFF.
В ином случае придётся учитывать программно, что переход через ноль идёт в другое крайнее значение,
но это всего одна единичка, один тик таймера, можно считать просто сбоем.
Re: Энкодер и STM32
Добавлено: Чт окт 14, 2021 09:25:50
Eddy_Em
Dimon456, вот именно, что такой способ работает лишь если ARR=0xffff. В этом случае количество оборотов придется считать, деля текущее положение на количество отсчетов на оборот. Т.е. в случае STM32F0 это - дополнительные тормоза. Это хорошо, если повезет, и будет кратное двойке. Но обычно у энкодеров 20, 50, 100, 200, 1000 и т.п. число отсчетов на один оборот, т.е. для таймера это 80, 200, 400, 800, 4000 и т.п. отсчетов.
Re: Энкодер и STM32
Добавлено: Чт окт 14, 2021 09:59:44
Dimon456
Eddy_Em писал(а):т.е. для таймера это 80, 200, 400, 800, 4000 и т.п. отсчетов.
И что?
Спойлер
65535/4000 = это 16 оборотов.
определили направление вращенияКод: Выделить всё
// Вернем перемещение
temp = (int16_t )enc_Get();
if (temp < 0) {
x -= temp;
}
if (temp > 0) {
x += temp;
}