cancel
Showing results for 
Search instead for 
Did you mean: 

capture compare problem, interrupt time capture question

schulzm-free
Associate II
Posted on January 26, 2012 at 10:28

I need a delay in a timer 4 interrupt. To realize this I wrote the the follow lines:

if

(TIM_GetITStatus(TIM4, TIM_IT_CC1) == SET) { TIM_ClearITPendingBit(TIM4, TIM_IT_CC1); TIM_ClearFlag(TIM4, TIM_FLAG_CC3);

while

(TIM_GetFlagStatus(TIM4, TIM_FLAG_CC3) == RESET); . . . .

but instead a delay I sometimes get a lose of some actions behind

this lines. I also tryed to give a delay direct befor the while with

a very little timedelay. But I alwas have the same problem. The same

line with an other timer in an other part of the program workes good.

What is wrong?

.

The second question I have is: I use timer 2 to set a CC flag by an

external Signal on the ports (I did not use the ISR). To get the

value of timer2 during this signal I use ''GetCounter''. But if my

signal on the port is a bounced signal which value do i get? The

value from the last valid potencial level or is the first value

locked and the value can change first if i reset the CC-Flag?

.

Thank you for helping me.
6 REPLIES 6
Posted on January 26, 2012 at 14:13

Please repost this question without formatting, the screen width is broken.

Please provide more context about how the timer is set up, and the goal.

I would not spin on a while() like this in an interrupt, why wouldn't you just wait for the CC3 interrupt?

I believe that timer latches the last value, earlier ones being lost. But this could be easily confirmed with some tests.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
schulzm-free
Associate II
Posted on January 26, 2012 at 14:28

Posted on January 26, 2012 at 17:29

The forum is kind of broken, it is best not to click on any of the format options, text input normally will wrap, however it sometimes gets some invalid line width if you format data.

Ok, I'm still not sure what it is you are trying to measure. If you are trying to measure the time/delta between two edges you are better to read the CC values at the last edge and subtract the two. For period measurements you can record subsequent CC measurements and determine the timer ticks between them.

There will be issues if interrupt events occur too rapidly, or if you have glitchy/bouncy edges.

Please diagram the signal and pin connectivity. Be specific.

Please supply the timer initialization, and system characteristics (bus, cpu freq, etc).

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
schulzm-free
Associate II
Posted on January 27, 2012 at 10:41

I measure a PWM-testsignal with has courrently 2 differen voltage level and i want to

 reconstruct the Signal after a delay of some µs. The level a free adjustable. Thats why I use

 an external DAC with SPI. Currently I have signals with a max. of 3000 Hz.

The reconstructed signal has a jitter of 2µs and I thougth the reasons could be the

 measurement or the SPI interrupt I used to reconstruct the signal. Maybe the STM is in a

 process wich has to be finished before the interrupt can be executed. So I want a little delay

 in the interrupt to synchronize the SPI start.

I hope its ok to post the code here. Is there a way to give a better format like [c] code format

 [/c]?

// Timer_2

  Config

TIM_TimeBaseStructure.

TIM_Period

= 0xFFFF;

TIM_TimeBaseStructure.

TIM_Prescaler

= 0;

TIM_TimeBaseStructure.

TIM_ClockDivision

= 0;

TIM_TimeBaseStructure.

TIM_CounterMode

= TIM_CounterMode_Up;

TIM_TimeBaseStructure.

TIM_RepetitionCounter

= 0;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

// Timer_2

Interrupt

TIM_ICInitStructure.

TIM_Channel

= TIM_Channel_3;

TIM_ICInitStructure.

TIM_ICPolarity

= TIM_ICPolarity_Rising;

TIM_ICInitStructure.

TIM_ICSelection

= TIM_ICSelection_DirectTI;

TIM_ICInitStructure.

TIM_ICPrescaler

= TIM_ICPSC_DIV1;

TIM_ICInitStructure.

TIM_ICFilter

= 0x0;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

TIM_ICInitStructure.

TIM_Channel

= TIM_Channel_4;

TIM_ICInitStructure.

TIM_ICPolarity

= TIM_ICPolarity_Rising;

TIM_ICInitStructure.

TIM_ICSelection

= TIM_ICSelection_DirectTI;

TIM_ICInitStructure.

TIM_ICPrescaler

= TIM_ICPSC_DIV1;

TIM_ICInitStructure.

TIM_ICFilter

= 0x0;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

//

Tim4 Config

// Timer_4

base

TIM_TimeBaseStructure.

TIM_Period

= 0xFFFF;

TIM_TimeBaseStructure.

TIM_Prescaler

= 0;

TIM_TimeBaseStructure.

TIM_ClockDivision

= 0;

TIM_TimeBaseStructure.

TIM_CounterMode

= TIM_CounterMode_Up;

TIM_TimeBaseStructure.

TIM_RepetitionCounter

= 0;

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

// Timer_4

Interrupt

TIM_ICInitStructure.

TIM_Channel

= TIM_Channel_3;

TIM_ICInitStructure.

TIM_ICPolarity

= TIM_ICPolarity_Rising;

TIM_ICInitStructure.

TIM_ICSelection

= TIM_ICSelection_DirectTI;

TIM_ICInitStructure.

TIM_ICPrescaler

= TIM_ICPSC_DIV1;

TIM_ICInitStructure.

TIM_ICFilter

= 0x0;

TIM_ICInit(TIM4, &TIM_ICInitStructure);

TIM_ICInitStructure.

TIM_Channel

= TIM_Channel_4;

TIM_ICInitStructure.

TIM_ICPolarity

= TIM_ICPolarity_Rising;

TIM_ICInitStructure.

TIM_ICSelection

= TIM_ICSelection_DirectTI;

TIM_ICInitStructure.

TIM_ICPrescaler

= TIM_ICPSC_DIV1;

TIM_ICInitStructure.

TIM_ICFilter

= 0x0;

TIM_ICInit(TIM4, &TIM_ICInitStructure);

----------------------------

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC |

                                                RCC_APB1Periph_TIM2 |

                                                RCC_APB1Periph_TIM4 |

                                                RCC_APB1Periph_SPI2,

ENABLE

);

 /*

Clock enable

*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 |

                                                RCC_APB2Periph_GPIOA |

                                                RCC_APB2Periph_GPIOB |

                                                RCC_APB2Periph_GPIOC,

ENABLE

);

------------------------------------------

if

(TIM_GetITStatus(TIM4, TIM_IT_CC1) ==

SET

)

{

TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);

if

(n_Anz_OF_T4 < 1)

{

//here should be the Flag reset

//here should be the while

 

Value16Bitu = 0b0001000000000000 | I_H_Pegel;

GPIO_ResetBits(GPIOB, GPIO_Pin_12); //NSS LOW

SPI_I2S_SendData(SPI2, Value16Bitu);

while

(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) ==

RESET

);

while

(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) ==

RESET

);

GPIO_SetBits(GPIOB, GPIO_Pin_12);

//NSS HIGH

}

n_Anz_OF_T4--;

}

I hope thats all.

Posted on January 27, 2012 at 16:53

The code window is pulled up using the paint brush icon in the upper right of the ''Word in a box'' editor. I don't know why it's a paint brush, or why it's so criminally broken, by it's from Microsoft. May be they can add some more tool bars, and crush the edit window even more.

I don't see it measuring anything, or how CC1 is being triggered.

If you want to add some arbitrary delay after the interrupt and are comfortable with spinning in a while() loop, you could use the core cycle counter ticking at 13.89 ns (@ 72 MHz), which would permit placement within a few 100 ns.

I'm not sure of the code flow, but you want to enable clocks before programming the peripherals.

The PWM Input example STM32F10xFWLib\Examples\TIM\PWM_Input\main.c (V2.x library included in Keil, and perhaps IAR installs), provide a complete example showing the measurement of duty cycle and frequency for a PWM signal.

I'm not sure why you would have an SPI interrupt, there also might be some latency in the SPI clocking out data at slower speeds, but it's not something I've experimented with. The SPI DAC presumably outputs after the final bit is clocked out to it.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
schulzm-free
Associate II
Posted on January 29, 2012 at 12:59

Maybe i can send you a short project which contrains the problem. I use the free Atollic Studio. If you want or if this is a problem in this forum you can post this code later. Is it possible to send you an email? And where are you from. Maybe we are from the same country and i havent to write in english. My english is very bad as u can see.