2018-11-27 03:04 AM
Hi, I am using STM32F407ZGT6 with mikroe 1369 ( https://www.mikroe.com/mikromedia-4-stm32f4 )
I need to capture falling edge of external signal and read the time its took from starting the function till falling edge detected.
I read maual but some how i am not getting right and its not working properly, i am getting 28 and 30 mS time regardless of signal present or not. Can some one guide me please and tell me what is wrong with this my code.
void InitTimer3(){
// GPIO Input: TIME alternate function for CH1,PA6
GPIO_Alternate_Function_Enable(&_GPIO_MODULE_TIM3_CH1_PA6);
GPIO_Set_Pin_Mode(&GPIOA_BASE,_GPIO_PIN_6,_GPIO_CFG_MODE_INPUT);
//disableInterrupts(); // disable global interrupts
RCC_APB1ENR.TIM3EN = 1;
RCC_AHB1ENR |= 0x1 ; //clock enable to GPIOA
TIM3_CR1.CEN = 0;
TIM3_PSC = 1;
TIM3_ARR = 37499;
TIM3_CCER.CC1E=1;
TIM3_CCER.CC1P = 0;
TIM3_CCER.CC1NP = 1; // Falling edage
TIM3_CCMR1_Input =1; // INPUT CAPTURE CH1
TIM3_CCR1 =1; //page 641
NVIC_IntEnable(IVT_INT_TIM3);
TIM3_DIER.TIE = 1; // enable interupt
TIM3_DIER.CC1IE = 1;
TIM3_DIER.UIE = 1;
TIM3_CR1.CEN = 1;
TIM3_EGR.UG = 1; // Reinit the counter
TIM3_EGR = 1;
enableInterrupts();
}
int EdgeCounter = 0;
void Timer3_interrupt() iv IVT_INT_TIM3 {
TIM3_SR.UIF = 0; // reset counter
LED_B=1;
LED_G=0;
LED_R=0;
// if falling edage detected
if(TIM3_SR.CC1IF== 1)//falling edage detect
{
TIM3_CR1.CEN = 0; // timer off
Rly_D=0;
disableInterrupts(); // disable global interrupts
//TIM3_SRbits.CC1IF == 0; // clear flag
// Displya timer code here
LED_B=0;
LED_G=0;
LED_R=1;
}
}
void EL_TimeB() {
InitTimer3();
delay_ms(1000);
EnableInterrupts();
NVIC_IntEnable(IVT_INT_TIM3);
delay_ms(1000);
Rly_D=1;
while(( TIM3_SRbits.CC1IF == 0 ) || (EdgeCounter< 5000 )) {
NVIC_IntEnable(IVT_INT_TIM3);
EdgeCounter++;
}
LED_B=1;
LED_G=1;
LED_R=0;
j = TIM3_CNT; // copy counter
TIM3_CNT = 0; // reset counter
TIM3_EGR.UG = 1; // update TIM3 registers
TIM3_SRbits.CC1IF = 0 ; // Clear flag
strcpy(ELTIME_main.Caption," " );
DrawLabel(&ELTIME_main);
LongWordToStr(j, text3);
strcpy(ELTIME_main.Caption,text3 );
ELTIME_main.Font_Color = Cl_green;
DrawLabel(&ELTIME_main);
}
2018-11-27 03:32 AM
Clear the entire TIM3_SR before enabling interrupts.
---
Just a note, I don't use the mikroe compiler but check how does this
> TIM3_SR.UIF = 0; // reset counter
or this
> TIM3_SRbits.CC1IF = 0 ; // Clear flag
work. I suspect the former is a read-modify-write (RMW), and the latter is a bit-banding access, which from the point of view of the register is a RMW, too. Don't do RMW with TIMx_SR, always use a direct write to the whole register; otherwise you may clear flags which have just been set by hardware in the middle of the RMW process.
JW
2018-11-27 04:00 AM
Hi WJ,
Thanks for input,
I reset the counter but still i am getting fix 32mS as out put and this regardless of signal time.
I increase delay up to 1000mS but still showing 32mS.
Any thoughts?
2018-11-27 04:07 AM
What do you mean by "Don't do RMW with TIMx_SR, always use a direct write to the whole register"
2018-11-27 01:20 PM
> I reset the counter
I said, clear TIM3_SR.
> What do you mean by "Don't do RMW with TIMx_SR, always use a direct write to the whole register"
https://community.st.com/s/feed/0D50X00009bLSAZSA4
JW
2018-11-27 10:33 PM
Hi WJ,
It is good info regarding TIMx_SR.
I have update and clear flag but still some how its not capturing properly and clearing hardware flag.
When i restart the hardware and run the program i get 0 mS which is perfect without any signal but in
second and onward attempt its shows 25mS.
I don't understand where part of this program is not working.
void InitTimer3(){
// GPIO Input: TIME alternate function for CH1,PA6
GPIO_Alternate_Function_Enable(&_GPIO_MODULE_TIM3_CH1_PA6);
GPIO_Set_Pin_Mode(&GPIOA_BASE,_GPIO_PIN_6,_GPIO_CFG_MODE_INPUT);
//disableInterrupts(); // disable global interrupts
RCC_APB1ENR.TIM3EN = 1;
RCC_AHB1ENR |= 0x1 ; //clock enable to GPIOA
TIM3_CR1.CEN = 0;
TIM3_PSC = 1;
TIM3_ARR = 37499;
TIM3_CCER.CC1E=1;
TIM3_CCER.CC1P = 0;
TIM3_CCER.CC1NP = 1; // Falling edage
TIM3_CCMR1_Input =1; // INPUT CAPTURE CH1
TIM3_CCR1 =1; //page 641
TIM3_SR = 0; // reset counter
TIM3_SR.UIF = 0; // reset counter
TIM3_SRbits.CC1IF = 0 ; // Clear flag
j=0;
NVIC_IntEnable(IVT_INT_TIM3);
TIM3_DIER.TIE = 1; // enable interupt
TIM3_DIER.CC1IE = 1;
TIM3_DIER.UIE = 1;
TIM3_CR1.CEN = 1;
TIM3_EGR.UG = 1; // Reinit the counter
TIM3_EGR = 1;
enableInterrupts();
}
int EdgeCounter = 0;
void Timer3_interrupt() iv IVT_INT_TIM3 {
// TIM3_SR.UIF = 0; // reset counter
LED_B=1;
LED_G=0;
LED_R=0;
// if falling edage detected
if(TIM3_SR.CC1IF== 1)//falling edage detect
{
TIM3_CR1.CEN = 0; // timer off
Rly_D=0;
disableInterrupts(); // disable global interrupts
TIM3_SR.UIF = 0; // reset counter
LED_B=0;
LED_G=0;
LED_R=1;
}
}
// PB1- TIM3CH4,pin 19 PA6 - TIM3CH1, pin 13 PB14 - TIM12Ch1 , pin 14 PB15 - TIM12Ch2
//
//4-PB0 TIM3CH3 //Phase A
// 5 -PB1 TIM3CH4 // Phase B
// 19 - PA6 - TIM3CH1 // Phase C
//
// PC0,PC2,PC3 // No timer available
void EL_TimeB() {
InitTimer3();
delay_ms(1000);
EnableInterrupts();
NVIC_IntEnable(IVT_INT_TIM3);
delay_ms(1000);
Rly_D=1;
while(( TIM3_SRbits.CC1IF == 0 ) || (EdgeCounter< 5000 )) {
NVIC_IntEnable(IVT_INT_TIM3);
EdgeCounter++;
}
LED_B=1;
LED_G=1;
LED_R=0;
j = TIM3_CNT; // copy counter
TIM3_CNT = 0; // reset counter
// TIM3_EGR.UG = 1; // update TIM3 registers
TIM3_SRbits.CC1IF = 0 ; // Clear flag
strcpy(ELTIME_main.Caption," " );
DrawLabel(&ELTIME_main);
LongWordToStr(j, text3);
strcpy(ELTIME_main.Caption,text3 );
ELTIME_main.Font_Color = Cl_green;
DrawLabel(&ELTIME_main);
}
2018-12-01 04:49 AM
HI JW,
Is there any think you find in below code, which can help me to solve this puzzle.
I cant think of anything why this falling edge interrupt doent work.
JP
2018-12-01 02:30 PM
Try to read out the registers content and check whether they are set as you intended.
Also check (in disassembly) whether the interrupt service routine (ISR) address is in the vector table.
JW