2020-07-13 11:25 PM
So I am trying to use the encoder mode that's built into the timer to get accurate encoder step count, which have worked flawlessly. I tried to use PA0 as the external interrupt that detects the rising edge to the index pulse. However, when I set the Timer value inside the interrupt, the timer count gets stuck to the value I have set and doesn't count up or down anymore. If anyone have any idea what I have missed that would be amazing ( I have made sure to clear the interrupt before exiting)
interrupt:
void EXTI0_IRQHandler(void)
{
USART1_write_string("here\n",5);
if(TIM4->CR1 &= 0x10)
{
TIM4->CNT = 7200;
}
else
{
TIM4->CNT = 0;
}
EXTI->PR = 0x1; //clear interrupt
}
Timer 4 setup for encoder:
void init_encoder(void)
{
/* timer 4 channel 1 and channel 2 (PB6, PB7) for encoder */
RCC->AHB1ENR |= 0x2; // enable port B
RCC->APB1ENR |= 0x4; // enable timer 4
GPIOB->MODER |= 0xA000; // set to alternate function for pin6 amd 7
GPIOB->PUPDR |= 0x5000; // set to pull up resistor for pin 6 and 7
GPIOB->AFR[0] |= 0x22000000; // set AFR to tim2-tim5
TIM4->ARR = 0xFFFF; // set max value
TIM4->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
TIM4->SMCR |= 0x3; // set to count both rising and falling edge of AB channels, with reset mode enabled
TIM4->CR1 |= 0x1; // enable counter
/* external interrupt, call encoder_reset() on rising edges */
// PA0 //
__disable_irq(); // disable iterrupt before configuring
RCC->AHB1ENR |= 0x1; // enable port A
RCC->APB2ENR |= 0x4000; // enable systemconfig clock
GPIOA->PUPDR |= 0x1; // pull up for pin A0
SYSCFG->EXTICR[0] |= 0x0; // EXIT0, Port A
EXTI->IMR |= 0x1; // mask exti 0
EXTI->RTSR |= 0x1; // set to rising edge
NVIC_EnableIRQ(EXTI0_IRQn); // renaable exti0
__enable_irq(); // renable interupt
}
while loop in main:
while(1)
{
if (TIM4->CNT >= 7200)
{
TIM4->CNT = 0;
}
rotary_raw = TIM4->CNT;
sprintf(send, "%d\n", rotary_raw);
//get_dec_str (send, distance);
USART1_write_string(send,7);
delayms(10);
}
PS: Solved it, I disabled the timer before changing the value and reeenable it afterward, that seems to prevent the values being stuck
PS2: If anyone have any other advice or suggestions for a more efficient encoder tracking I'm all ears, but this seems to work well enough for my use case.
2020-07-14 12:11 AM
> if(TIM4->CR1 &= 0x10)
You surely meant
if(TIM4->CR1 & 0x10)
JW
2020-07-14 10:34 AM
oh wow totally missed that, yup that was the actual culprit.