[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]
хочу пообсуждать данный код в разрезе эффективности именно этого фильтра 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);