Если что - я никого ни к чему не призываю. Просто вспомнил и написал - как когда-то решил проблему быстородействия процедуры опроса энкодера и при этом еще получил эргономику, какую хотел. Давно дело было и было на avr.
и тут на тебе - контроллер считает импульсы - а должен один добавить и тут же по спаду убавить.
Значит, у тебя таймер неправильно настроен. Т.к. в такой ситуации он должен просто на ±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кГц, а в итоге флаг прерывания ловлю даже не досчитав
и это на 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);
да потому что дребезг я отфильтровать расчетным путем не смог
А посмотреть его осциллографом, измерить длительность и отфильтровать с помощью RC-фильтра и триггера Шмитта не пробовал? Глядя на структуру таймера, я не вижу там настоящего фильтра дребезга, поэтому, ИМХО, твои попытки отфильтровать дребезг были априори обречены на неудачу.
По этой SPL'ной мешанине вообще непонятно, что там происходит. Но что-то очень похоже, что таймер вообще не в режиме энкодера инициализирован, а в тупом режиме счета по одному каналу!
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
да потому что дребезг я отфильтровать расчетным путем не смог
А посмотреть его осциллографом, измерить длительность и отфильтровать с помощью RC-фильтра и триггера Шмитта не пробовал? Глядя на структуру таймера, я не вижу там настоящего фильтра дребезга, поэтому, ИМХО, твои попытки отфильтровать дребезг были априори обречены на неудачу.
Ну сейчас получилось, дребезг и так таймером обсчитывается, не могу только "быстрый" настолько, что не успеваю выйти из прерывания, потому и выставил верхнюю границу в 70кГц - ее хватает за глаза. Про осцил - если честно такие частоты надо задавать, а не ловить, осцил есть, а вот генератора нема, потому и шел расчетным путем. По поводу дребезга - и работы с RC и триггерами - все это конечно необходимо НО, если сигнал реально идет с частотой 70 кГц, зачем мне его гасить, система должна справляться, а вот то что не попало в диапазон, можно, но для надежности и программа тоже должна справляться.
По этой SPL'ной мешанине вообще непонятно, что там происходит. Но что-то очень похоже, что таймер вообще не в режиме энкодера инициализирован, а в тупом режиме счета по одному каналу!
не по одному, а по двум, на втором аналогичная настройка и это никакого отношений к настройке интерфейса энкодера не имеет - это настройка фильтра - она же по совместительству настройка capture. Настройка энкодера идет в битах SMS.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Странная логика. У тебя идёт дребезг с энкодера. Не зная параметров дребезга, ни программно, ни аппратно его не возможно подавить. Без подавления дребезга просто не понятно, что там насчитает таймер.
Добавлено after 2 minutes 23 seconds: Покажи осциллограмму сигналов с энкодера.
А у меня вопрос: что в битах 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 и т.д., и т.п.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Dimon456, и что, все равно не фильтрует? А если APB prescaler на 1/16?
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Ну как сказать, один тик плохо отрабатывает, особенно при навигации в меню жутко не удобно, может на два три пункта перескочить. У меня нет хорошего видео, что нашелСпойлерсмотреть на нижнюю строку, левые цифры, где 5008, это энкодерВсе таки аппаратная поддержка, не программная. Но так и хочется кондерчики поставить, думаю на 1nF сойдет.
Можно вообще по RC-фильтру килогерц на 10 воткнуть.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Зарегистрирован: Ср сен 25, 2019 17:46:33 Сообщений: 35
Рейтинг сообщения:0
Доброго дня. Если не против, вклинюсь со своим вопросом.
Энкодер обычный, алиэкспресс-китайский ЕС11, кажется 15 импульсов на оборот, на синей круглой плате. В его обвязке уже есть резисторы подтяжки к питанию и конденсаторы к земле.
Эксперимент проходит на STM32F103C8. Таймер настроен для работы с энкодером так:
Тут диапазон счетчика энкодера от 0 до 100, без перехода через 0 или через 100, с шагом 1. При достижении минимального или максимального значения счетчика, если продолжать вращение в ту же сторону дальше, счетчик начинает колебаться у своего достигнутого значения. Например, досчитали-докрутили до 0, продолжаем крутить в сторону уменьшения дальше, счетчик меняется в диапазоне 0-1-0-0-0-1-0 и т.п. Или досчитали до 100, крутим в сторону увеличения дальше, видим 100-99-100-99-98 и т.п. Скорость вращения вала при этом не важна. Если вал оставить в покое в любом своем положении и любом значении счетчика, то самопроизвольного плавания значения нет. Параметр Input Filter менять пробовал, результата не видно. При вращении не на границах счета, этого эффекта нет. Справочно - этот-же энкодер на ардуине ведет себя адекватно.
Есть-ли решение проблемы такого эффекта у энкодера?
U-M, как-то странно у вас настроен энкодер. Не должно такого быть: после 0 должно следовать 99, 98 и так далее; аналогично после 100 должно идти 0, 1, 2 и т.д. Каловскую портянку вряд ли кто читать будет. Дайте нормальный код инициализации! P.S. А таймер случаем не в center-aligned mode?
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Здрасти У меня иная проблема, опыта в СТМ пока не много поэтому сильно не пинайте.
Вопрос соединения таймеров, возможно ли такое: я подключил энкодер к таймеру Т4 всё работает, но как то нужно настроить прерывание(допустим через каждых 100 тиков этого таймера), полагаю что прерывание по переполнению делать не вариант, потеряем текущее абсолютное значение (0-0xffff), есть идея параллельно к счётному входу подключить второй таймер который бы и генерил прерывание по переполнению к примеру каждые 100 импульсов? Или это можно как то иначе реализовать? Но только не через прерывания, прерывание должно быть одно и только после делителя импульсов.
В чём собственно суть: на цепи лежит объект, цепь при этом перемещается, на цепи установлен инкрементальный энкодер, в зоне измерения установлен датчик и через допустим 1-5-10 см нужно считывать значения с датчика при этом запоминается значение счётчика в момент начала и конца объекта чтобы потом вычислить итоговую длину.
на цепи лежит объект, цепь при этом перемещается, на цепи установлен инкрементальный энкодер
У таймеров-счётчиков есть модуль сравнения. Берёшь текущее значение счётчика, добавляешь или вычитаешь из него нужное количество импульсов, разрешеаешь прерывание от этого канала сравнения- и в путь. Управлял конвейером. Энкодера не было, управлял шаговым двигателем, но суть таже самая.
Ну как вариант, если не получиться таймеры синхронизировать.
Зачем их синхронизировать? TIM2 и TIM5 имеют аж 32 бита. Впрочем, для большинства задач хватает 16 бит.
Ещё обрати внимание на флаги прерываний. Возможно, тебе понадобиться отключить флаг перехода счётчика через ноль, оставив только сигналы от модуля сравнений.
Мне нужно чтобы они работали синхронно, Т4 хранит значение текущего положения цепи(0-0xffff), в Т12 записываем максимальное значение при постижении которого(TIM12_ARR = 20-50-150) счётчик сбрасывается в ноль и формируется прерывание. Хочу сделать всё на аппаратном уровне без заморочки с регистрами сравнения.
счётчик сбрасывается в ноль и формируется прерывание. Хочу сделать всё на аппаратном уровне без заморочки с регистрами сравнения.
Так ведь если формируется прерывание, то что сложного в нём сбросить счётчик? Если уж так хочется, чтобы всё делалось автоматически, то можно задействовать DMA для записи нуля, хотя, ИМХО, зачем такой изврат?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 31
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения