2012-04-11 11:46 AM
Hi,
I`m working with the STM32F103XC processor (lqfp144 package) and I want to use the input capture mode for the Timer1. At the moment I didn`t get any timer interrupt while the I/O PE13 has a lot of rising edges. Maybe there`s something wrong with the PE13 pin which has as alternative function TIM1_CH3. Here`s my init code.RCC->APB2ENR |= (
1
<<6
);// enable peripheral clock for GPIOE
/* INT input PE13 -> mit timer1 verwenden */
GPIOE->CRH &= ~0x00F00000
;// reset port-pin
GPIOE->CRH |=0x00400000
;// set input mode floating
RCC->APB2ENR |= RCC_APB2Periph_TIM1;/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0
; NVIC_InitStructure.NVIC_IRQChannelSubPriority =1
; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_TimeBaseStructure.TIM_Period =0xFFFF
; TIM_TimeBaseStructure.TIM_Prescaler =1
; TIM_TimeBaseStructure.TIM_ClockDivision =0
; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter =0
; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;//PE13
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;// Div:1, every edge
TIM_ICInitStructure.TIM_ICFilter =0x0
; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);/* TIMER interrupt routine: wird nie aufgerufen */
void
TIM1_CC_IRQHandler (void
) {if
(TIM1->SR & TIM_IT_CC3) {/* capture timer */
TIM1->SR = (unsigned
short
)~TIM_FLAG_CC3; } } best regards Hans2012-04-11 12:25 PM
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
I think you need to use DIRECT, to use PE13 you're going to need to REMAP TIM1 otherwise it expects PA10. INDIRECT would be using TIM1_CH4 as the source.RCC->APB2ENR |= RCC_APB2Periph_AFIO; GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);
2012-04-12 01:42 AM
2012-04-12 07:31 AM
Hi,
the input capture timer is now working but I didn`t get any input capture values (IC3ReadValue1, IC3ReadValue2) to measure the frequency (TIM3Freq) between two interrupts. IC3ReadValue1 and IC3ReadValue2 are always 0x00. I also took a look into the STM32 input capture example, but they use the same settings (only for the TIM_GetCapture2 instead of the TIM_GetCapture3. volatile unsigned short IC3ReadValue1 = 0, IC3ReadValue2 = 0; volatile unsigned short CaptureNumber = 0; volatile unsigned int Capture = 0; volatile unsigned int TIM3Freq = 0; void TIM1_CC_IRQHandler (void) { unsigned char state = 0x00;if (TIM1->SR & TIM_IT_CC3)
{ /* capture timer */ //clear pending bit TIM1->SR &= (unsigned short)~TIM_FLAG_CC3;if(CaptureNumber == 0)
{ /* Get the Input Capture value */ IC3ReadValue1 = TIM3->CCR3; //TIM_GetCapture2(TIM3); if(IC3ReadValue1) IC3ReadValue1 = IC3ReadValue1;CaptureNumber = 1;
} else if(CaptureNumber == 1) { /* Get the Input Capture value */ IC3ReadValue2 = TIM3->CCR3; //TIM_GetCapture2(TIM3); if(IC3ReadValue2) IC3ReadValue2 = IC3ReadValue2;/* Capture computation */
if (IC3ReadValue2 > IC3ReadValue1) { Capture = (IC3ReadValue2 - IC3ReadValue1); } else { Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2); } /* Frequency computation */ TIM3Freq = (unsigned int) 36000000 / Capture; CaptureNumber = 0;}
} best regards Hans2012-04-13 01:47 AM
I found my error: TIM3->CCR3 instead of TIM1->CCR3. Now I get some values in the CCRr3 register at the CCR3 interrupt, but I`m not sure how I have to calculate the frequency from the input-capture-signal.
For example: the input-capture-signal has a frequency of 24Hz I get a frequency of 240Hz. Here are my settings:unsigend
short
prescaler = (36000000
-1000
) -1
; 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(TIM1, &TIM_TimeBaseStructure); TIM_PrescalerConfig(TIM1,prescaler, TIM_PSCReloadMode_Immediate); And this is my interrupt routinevolatile
unsigned
char
counter =0x00
;volatile
unsigned
short
capture =0x00
;volatile
unsigned
short
frequency =0x00
;void
TIM1_CC_IRQHandler(void
) {if
(TIM_GetITStatus(TIM1, TIM_IT_CC3) !=RESET) {if
(!counter) {/* Get the Input Capture value */
IC1Value = TIM1->CCR3; counter++; }else
if
(counter) { counter =0x00
; IC2Value = TIM1->CCR3;if
(IC2Value > IC1Value) capture = IC2Value - IC1Value;else
capture = (0xFFFF
- IC1Value) + IC2Value;// -> the capture value is always 0x4B
//frequency of the signal
frequency =36000
/ (2 * capture); } TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); } } As I found out if the APB prescaler is not 1 the timer clock frequency is set to twice the frequency of the APB domain which is 36MHz. -> therefore I divided the frequency-value by 2 (frequency =36000
/ (2 * capture);). best regards Hans