Hallo, ich verwnede ein STM32VL Discovery Board. Ich versuche gerade die Frequenz eines Eingangssingnales zu messen. Signal liegt auf Port PA2 an und hat eine Frequenz zwischen 0Hz und 500 Hz. Ich verwende zum messen der Zeit zwischen Rising Edge und Falling Edge den Timer15 CH1. Das Funktioniert auch soweit. Sobald eine Flanke auf dem Signal erkannt wird, wird das Capture Event ausgelöst und die ISR ausgeführt. Mein Problem: Die Werte haben überhaupt nichts mit der gemessenen Frequenz zu tun. Gemessene Frequenzen leigen zwischen 366Hz und 280KHz!!! Meine Vermutung ist, dass es sich um nicht abgefangene Timer Überläufe des Registers handelt. Wenn ich das in der Initialisierung richtig verstanden habe, dann läuft der Timer mit dem vollen 24Mhz. Register geht bis 65535 => 2,73062ms bis zum Überlauf => 366Hz, woher vermutlich auch die Untergrenze der gemessenen Frequenz herkommt. Meine Frage: Wie kann ich Timerüberläufe Abfangen? Kann ich den Timer auch auf eine andere Frequenz einstellen, mit der er den Register wert hochzählt, dass es gar nicht zu einem Timer überlauf kommt? Anbei mein Code: Initialisierung:
1 | // Timer 15 Channel_1 PA2
|
2 | // TIM15 clock enable
|
3 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE); |
4 | |
5 | // GPIOA clock enable
|
6 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); |
7 | |
8 | // TIM15 channel 1 pin (PA.02) configuration
|
9 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; |
10 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
11 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
12 | GPIO_Init(GPIOA, &GPIO_InitStructure); |
13 | |
14 | // Enable the TIM15 global Interrupt
|
15 | NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_TIM15_IRQn; |
16 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; |
17 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; |
18 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
19 | NVIC_Init(&NVIC_InitStructure); |
20 | |
21 | TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; |
22 | TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; |
23 | TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; |
24 | TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; |
25 | TIM_ICInitStructure.TIM_ICFilter = 0x0; |
26 | |
27 | TIM_ICInit(TIM15, &TIM_ICInitStructure); |
28 | |
29 | // TIM enable counter
|
30 | TIM_Cmd(TIM15, ENABLE); |
31 | |
32 | // Enable the CC2 Interrupt Request
|
33 | TIM_ITConfig(TIM15, TIM_IT_CC1, ENABLE); |
ISR:
1 | void TIM1_BRK_TIM15_IRQHandler(void) |
2 | {
|
3 | if(TIM_GetITStatus(TIM15, TIM_IT_CC1) == SET) |
4 | {
|
5 | /* Clear TIM15 Capture compare interrupt pending bit */
|
6 | TIM_ClearITPendingBit(TIM15, TIM_IT_CC1); |
7 | if(CaptureNumber == 0) |
8 | {
|
9 | /* Get the Input Capture value */
|
10 | IC3ReadValue1 = TIM_GetCapture1(TIM15); |
11 | CaptureNumber = 1; |
12 | }
|
13 | else if(CaptureNumber == 1) |
14 | {
|
15 | /* Get the Input Capture value */
|
16 | IC3ReadValue2 = TIM_GetCapture1(TIM15); |
17 | |
18 | /* Capture computation */
|
19 | if (IC3ReadValue2 > IC3ReadValue1) |
20 | {
|
21 | Capture = (IC3ReadValue2 - IC3ReadValue1); |
22 | }
|
23 | else
|
24 | {
|
25 | Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2); |
26 | |
27 | }
|
28 | /* Frequency computation */
|
29 | TIM3Freq = (uint32_t) SystemCoreClock / Capture; |
30 | CaptureNumber = 0; |
31 | }
|
32 | }
|
Danke für eure Tipps und Anregungen