Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: Энкодер и STM32

Вс окт 17, 2021 08:25:54

Если что - я никого ни к чему не призываю. ;)
Просто вспомнил и написал - как когда-то решил проблему быстородействия процедуры опроса энкодера и при этом еще получил эргономику, какую хотел. Давно дело было и было на avr.

Re: Энкодер и STM32

Пн окт 18, 2021 19:26:06

и тут на тебе - контроллер считает импульсы - а должен один добавить и тут же по спаду убавить.

Значит, у тебя таймер неправильно настроен. Т.к. в такой ситуации он должен просто на ±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);
}

Фильтрация настроена?

хочу пообсуждать данный код в разрезе эффективности именно этого фильтра ETF для интерфейса энкодера, кто что думает, я лично считаю, что настройка регистра TIM3->SMCR привязана к External тактированию, собственно с этим сигналом фильтр и работает, а также прескалер на него действует. По идее с энкодерными входами должны работать регистры CCMR1(2) в режиме инпут пинов (каналов как входов). Затем после фильтрации получаться TI1FP1 и TI1FP2, которые и являются тактирующими. Вот только не пойму, как в данном случае должен работать прескалер судя по такой картинке
Изображение
первым работает фильтр выборок, но не совсем понятно, как здесь участвует прескалер, хорошо, если делит частоту таймера по шине и задает этот f_TDS на выборки, а может вообще не делит. Далее выбор фронта или спада (кстати в CIMSIS есть TIM_ICPolarity_BothEdge, который по сути у меня не работает в силу отсутствия аппаратной поддержки).
Почему задумался, да потому что дребезг я отфильтровать расчетным путем не смог, хотел ограничить частотой 70кГц, а в итоге флаг прерывания ловлю даже не досчитав
Код:
      if (CNT_EN){
         if ((CNT_TIM3_old==1)&&(cnt_dir!=1)&&(TIM3_CNT > 32767))
            CNT_Val_Reg = (s32)(CNT_Val_Reg - 65536), CNT_TIM3_old = 65534, cnt_dir = 1;
         if ((CNT_TIM3_old==65534)&&(cnt_dir!=2)&&(TIM3_CNT < 32767))
            CNT_Val_Reg = (s32)(CNT_Val_Reg + 65536), CNT_TIM3_old = 1, cnt_dir = 2;
      }

и это на 72 МГц частоте.
Хотя настройку на ETF тоже делаю из соображений гарантированности и обыкновенного маразма.
ПыСы: короче ICPrescaler вообще убрал от греха, CKD в регистре SR1 сделал свое дело.

Код:
          TIM_ICInitTypeDef TIM_ICInitStructure;

          //Enter the content in the structure by default
          TIM_ICStructInit(&TIM_ICInitStructure);
          //выбрать входной терминал IC1
          TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
          //Захват фронт
          TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
          //сопоставлен с TI1
          TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
          //Настроить входное частотное деление замеряемого сигнала, не делим чтоб не потерять
          TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
          //filter value fSAMPLING=fDTS/32, выборка N=8.
          TIM_ICInitStructure.TIM_ICFilter = 15;
          //Initialize the specified parameters in TIM_ICInitStructure TIM3
          TIM_ICInit(TIM3, &TIM_ICInitStructure);

Re: Энкодер и STM32

Вт окт 19, 2021 07:59:37

да потому что дребезг я отфильтровать расчетным путем не смог

А посмотреть его осциллографом, измерить длительность и отфильтровать с помощью RC-фильтра и триггера Шмитта не пробовал? Глядя на структуру таймера, я не вижу там настоящего фильтра дребезга, поэтому, ИМХО, твои попытки отфильтровать дребезг были априори обречены на неудачу.

Re: Энкодер и STM32

Вт окт 19, 2021 09:50:53

По этой SPL'ной мешанине вообще непонятно, что там происходит. Но что-то очень похоже, что таймер вообще не в режиме энкодера инициализирован, а в тупом режиме счета по одному каналу!

Re: Энкодер и STM32

Вт окт 19, 2021 10:50:25

да потому что дребезг я отфильтровать расчетным путем не смог

А посмотреть его осциллографом, измерить длительность и отфильтровать с помощью RC-фильтра и триггера Шмитта не пробовал? Глядя на структуру таймера, я не вижу там настоящего фильтра дребезга, поэтому, ИМХО, твои попытки отфильтровать дребезг были априори обречены на неудачу.

Ну сейчас получилось, дребезг и так таймером обсчитывается, не могу только "быстрый" настолько, что не успеваю выйти из прерывания, потому и выставил верхнюю границу в 70кГц - ее хватает за глаза. Про осцил - если честно такие частоты надо задавать, а не ловить, осцил есть, а вот генератора нема, потому и шел расчетным путем. По поводу дребезга - и работы с RC и триггерами - все это конечно необходимо НО, если сигнал реально идет с частотой 70 кГц, зачем мне его гасить, система должна справляться, а вот то что не попало в диапазон, можно, но для надежности и программа тоже должна справляться.

Добавлено after 8 minutes 22 seconds:
По этой SPL'ной мешанине вообще непонятно, что там происходит. Но что-то очень похоже, что таймер вообще не в режиме энкодера инициализирован, а в тупом режиме счета по одному каналу!

не по одному, а по двум, на втором аналогичная настройка и это никакого отношений к настройке интерфейса энкодера не имеет - это настройка фильтра - она же по совместительству настройка capture. Настройка энкодера идет в битах SMS.

Re: Энкодер и STM32

Вт окт 19, 2021 10:58:43

Странная логика. У тебя идёт дребезг с энкодера. Не зная параметров дребезга, ни программно, ни аппратно его не возможно подавить. Без подавления дребезга просто не понятно, что там насчитает таймер.

Добавлено after 2 minutes 23 seconds:
Покажи осциллограмму сигналов с энкодера.

Re: Энкодер и STM32

Вт окт 19, 2021 12:17:47

А у меня вопрос: что в битах CKD регистра TIM3->CR1? Если там по нулям, то fDTS = fCK_INT, т.е. фильтр просто может и не отработать... А вот если туда двоечку записать, то fDTS будет в четыре раза меньше fCK_INT… А это — уже не 48МГц, а 12МГц. Т.е. при фильтрации fDTS/32 N=8 получим, что таймер будет отсекать все шумы выше ~46.9кГц.
И еще: если на PCLK (APB) нет важной периферии, можно APB prescaler загнать в 1/16, в этом случае fCK_INT будет равна HCLK/8, т.е. 6МГц, если AHB шурует на 48 (только учесть это при конфигурации усартов и прочей периферии, сидящей на APB).
Ну и совсем уж в качестве экспериментов, можно AHB притормозить. Правда, при этом затормозится еще и обращение к памяти, DMA и т.д., и т.п.

Re: Энкодер и STM32

Вт окт 19, 2021 12:51:55

Eddy_Em, глянь мой код

Re: Энкодер и STM32

Вт окт 19, 2021 12:58:01

Dimon456, и что, все равно не фильтрует?
А если APB prescaler на 1/16?

Re: Энкодер и STM32

Вт окт 19, 2021 13:19:32

Eddy_Em писал(а):и что, все равно не фильтрует?
Ну как сказать, один тик плохо отрабатывает, особенно при навигации в меню жутко не удобно, может на два три пункта перескочить.
У меня нет хорошего видео, что нашел
Все таки аппаратная поддержка, не программная.
Но так и хочется кондерчики поставить, думаю на 1nF сойдет.
Eddy_Em писал(а):А если APB prescaler на 1/16?
не пробовал.

Re: Энкодер и STM32

Вт окт 19, 2021 13:36:00

Можно вообще по RC-фильтру килогерц на 10 воткнуть.

Re: Энкодер и STM32

Ср ноя 03, 2021 15:22:08

Доброго дня. Если не против, вклинюсь со своим вопросом.

Энкодер обычный, алиэкспресс-китайский ЕС11, кажется 15 импульсов на оборот, на синей круглой плате. В его обвязке уже есть резисторы подтяжки к питанию и конденсаторы к земле.

Эксперимент проходит на STM32F103C8.
Таймер настроен для работы с энкодером так:



Значение забирается так:


Тут диапазон счетчика энкодера от 0 до 100, без перехода через 0 или через 100, с шагом 1.
При достижении минимального или максимального значения счетчика, если продолжать вращение в ту же сторону дальше, счетчик начинает колебаться у своего достигнутого значения.
Например, досчитали-докрутили до 0, продолжаем крутить в сторону уменьшения дальше, счетчик меняется в диапазоне 0-1-0-0-0-1-0 и т.п.
Или досчитали до 100, крутим в сторону увеличения дальше, видим 100-99-100-99-98 и т.п.
Скорость вращения вала при этом не важна. Если вал оставить в покое в любом своем положении и любом значении счетчика, то самопроизвольного плавания значения нет.
Параметр Input Filter менять пробовал, результата не видно.
При вращении не на границах счета, этого эффекта нет.
Справочно - этот-же энкодер на ардуине ведет себя адекватно.

Есть-ли решение проблемы такого эффекта у энкодера?

Re: Энкодер и STM32

Ср ноя 03, 2021 16:04:22

U-M, как-то странно у вас настроен энкодер. Не должно такого быть: после 0 должно следовать 99, 98 и так далее; аналогично после 100 должно идти 0, 1, 2 и т.д.
Каловскую портянку вряд ли кто читать будет. Дайте нормальный код инициализации!
P.S. А таймер случаем не в center-aligned mode?

Re: Энкодер и STM32

Ср ноя 03, 2021 23:16:32

Да, таймер в aligned mode 3.

Re: Энкодер и STM32

Вт июн 20, 2023 10:20:55

Здрасти :))
У меня иная проблема, опыта в СТМ пока не много поэтому сильно не пинайте.

Вопрос соединения таймеров, возможно ли такое: я подключил энкодер к таймеру Т4 всё работает, но как то нужно настроить прерывание(допустим через каждых 100 тиков этого таймера), полагаю что прерывание по переполнению делать не вариант, потеряем текущее абсолютное значение (0-0xffff), есть идея параллельно к счётному входу подключить второй таймер который бы и генерил прерывание по переполнению к примеру каждые 100 импульсов?
Или это можно как то иначе реализовать? Но только не через прерывания, прерывание должно быть одно и только после делителя импульсов.

В чём собственно суть: на цепи лежит объект, цепь при этом перемещается, на цепи установлен инкрементальный энкодер, в зоне измерения установлен датчик и через допустим 1-5-10 см нужно считывать значения с датчика при этом запоминается значение счётчика в момент начала и конца объекта чтобы потом вычислить итоговую длину.

Re: Энкодер и STM32

Ср июн 21, 2023 06:03:32

alex_ писал(а):на цепи лежит объект, цепь при этом перемещается, на цепи установлен инкрементальный энкодер

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

Re: Энкодер и STM32

Ср июн 21, 2023 10:22:48

Ну как вариант, если не получиться таймеры синхронизировать. Пока пытаюсь T4 master->T12 save

Re: Энкодер и STM32

Ср июн 21, 2023 11:18:47

Ну как вариант, если не получиться таймеры синхронизировать.

Зачем их синхронизировать? TIM2 и TIM5 имеют аж 32 бита. Впрочем, для большинства задач хватает 16 бит.

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

Re: Энкодер и STM32

Ср июн 21, 2023 13:48:35

Мне нужно чтобы они работали синхронно, Т4 хранит значение текущего положения цепи(0-0xffff), в Т12 записываем максимальное значение при постижении которого(TIM12_ARR = 20-50-150) счётчик сбрасывается в ноль и формируется прерывание. Хочу сделать всё на аппаратном уровне без заморочки с регистрами сравнения.

Re: Энкодер и STM32

Ср июн 21, 2023 14:19:00

alex_ писал(а):счётчик сбрасывается в ноль и формируется прерывание. Хочу сделать всё на аппаратном уровне без заморочки с регистрами сравнения.

Так ведь если формируется прерывание, то что сложного в нём сбросить счётчик? :))
Если уж так хочется, чтобы всё делалось автоматически, то можно задействовать DMA для записи нуля, хотя, ИМХО, зачем такой изврат?
Ответить