2017-08-09 06:48 AM
Hello guys,
So I'mdoing simple timer capture inputpractice exercise. I have HC-SR 04 sensor and want to drive it with stm32f3 discovery board. If someone could check what is wrong with my code:
#include 'stm32f303xc.h'
long cnt1 = 0;
long cnt2 = 0;
short x = 0;
void Delay(uint32_t circles);
int main(void){
RCC->AHBENR = RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN; //clock for A and E ports
RCC->APB1ENR = RCC_APB1ENR_TIM3EN; //clock for timer
GPIOE->MODER |= GPIO_MODER_MODER11_0 // Green
| GPIO_MODER_MODER10_0 // Orange
| GPIO_MODER_MODER9_0 // Red LED output mode
| GPIO_MODER_MODER2_0; // PE02 - TRIGG PIN outputmode
TIM3->CCMR1 = TIM_CCMR1_CC1S_0; //CC AS INPUT, MAP TI1 (PE03)
TIM3->CCER = TIM_CCER_CC1NP_Msk | TIM_CCER_CC1P_Msk; // EVENT ON RISING AND FALLING EDGE
TIM3->CCMR1 = TIM_CCMR1_IC1PSC; // NO PSC - CAPTURE EACH EVENT
TIM3->CCER = TIM_CCER_CC1E; // ENABLE INPUT CAPTURE COMPARE MODE
TIM3->DIER = TIM_DIER_CC1IE; // ENABLE CC INTERRUPT
TIM3->CR1 = TIM_CR1_CEN; // ENABLE TIM3
NVIC_EnableIRQ(TIM3_IRQn); // ENABLE NVIC INTERRUPT FOR TIM3
Delay(800000); // Wait some time
GPIOE->ODR |= GPIO_ODR_2; // Set PE02
Delay(8000); // Wait 10us
GPIOE->ODR &= ~(GPIO_ODR_2); // Reset PE02
while(1){}
}
void TIM3_IRQHandler(void)
{
if(x==0)
{
cnt1 = TIM3->CCR1; // GET VALUE
x++; // REMEMBER THAT NEXT IS FALLING EDGE
GPIOE->ODR |= GPIO_ODR_10; // SET LED TO CONFIRM
}
else if(x==1)
{
cnt2 = TIM3->CCR1; // GET VALUE
x--; // NEXT IS RISING EDGE
GPIOE->ODR |= GPIO_ODR_11; // SET LED TO CONFIRM
}
}
// SysTick clock = 8MHz so you get 1sec delay afret 8000000 circles
//
void Delay(uint32_t circles)
{
SysTick->LOAD = circles - 1;
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk;
while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Problem is that CCR1 value is always zero, so the cnt1 and cnt2 won't get value, however, both LEDs lights.
#discovery #stm32 #input-capture #timer-interrupt2017-08-09 08:43 AM
TIM3->CCMR1 = TIM_CCMR1_CC1S_0; //CC AS INPUT, MAP TI1 (PE03)
TIM3->CCER = TIM_CCER_CC1NP_Msk | TIM_CCER_CC1P_Msk; // EVENT ON RISING AND FALLING EDGE
TIM3->CCMR1 = TIM_CCMR1_IC1PSC; // NO PSC - CAPTURE EACH EVENT
i.e. you overwrite
TIM3->CCMR1 by the new value which is probably not what you want.
JW
2017-08-09 08:55 AM
I can't see the timer's base configuration (period, prescaler, counter mode, etc.).
2017-08-09 12:24 PM
Quick update:
Configuration part
TIM3->SR = 0;// RESET FLAGS
TIM3->PSC = 0; // PRESCALLER
TIM3->ARR = 0xFFFFFF; // AUTORELOAD
TIM3->CCMR1 = TIM_CCMR1_CC1S_0; //CC AS INPUT, MAP TI1 (PE03)
TIM3->CCER = TIM_CCER_CC1NP | TIM_CCER_CC1P// ENABLE EVENT ON RISING AND FALLING EDGE
| TIM_CCER_CC1E; // ENABLE INPUT CAPTURE COMPARE MODE
TIM3->DIER = TIM_DIER_CC1IE;// ENABLE CC INTERRUPT
TIM3->CR1 = TIM_CR1_CEN; // ENABLE TIM3
NVIC_EnableIRQ(TIM3_IRQn);// ENABLE NVIC INTERRUPT FOR TIM3
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
The interesting part is that LEDsaren't switching on now. I find out that they do when I comment 4th line which is weird, because it is declaring this channel as an input mode, in a reset state, it's declared as an output.
Additionally, I take TIM3->CNT on watch when debugging and it's counting properly.
Big thanks for answers,I appreciate it very much.
2017-08-10 04:15 AM
Most of the times when you assign a value to a register in your code (example: TIM3->CR1 = TIM_CR1_CEN;) you really should use read-write approach to change only the bits you mean to (example: TIM3->CR1 |= TIM_CR1_CEN;).
If you are determined to use direct register programming approach instead of using HAL or LL then you can download one of the
packages and see the Timer examples there. STM32Snippets currently exists only for STM32F0 and STM32L0 families which are different than STM32F3 in many things, but the Timers are very much the same, so the TIMERS/03_InputCaptureOnTI1 example project should help you.