2013-08-28 03:46 AM
Hi,
I set an interruption handler for a timer. Each time it calls the handler I change the state of a IO. But I'm getting problems for frequency above 80kHz. If I set the period to:TIM_TimeBaseStructure.
TIM_Period
= SystemCoreClock/160000
-1
; I got an 80kHz in the channel output and in the IO that is changed by the interruption: Channel-0: PA2 - Timer 2 Chanel 2 Channel-1: PC9 - IO But if I set the period to:TIM_TimeBaseStructure.
TIM_Period
= SystemCoreClock/160000
-1
;It will create a 85kHz on OC2 but the IO drive by the interruption can't handle it. Am I in the limit of normal io speed? The measured frequency for the IO is 42kHz.
The code:
#include <stm32f10x.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_tim.h>
#include <misc.h>
#define STPDRV_TIMFREQ 100000
static
__IO uint8_t ledval;
static
__IO uint8_t change;
int
main(
void
)
{
ledval=0;
change=0;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//Configure Clocks
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//Configure GPIO PC9
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//Configure GPIO PA1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//configure NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//configure timer
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock/170000 - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
//configure channel TIM2 C2
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
/* TIM2 TRGO selection */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
while
(1){
if
(change){
GPIO_WriteBit(GPIOC, GPIO_Pin_9, (ledval)? Bit_SET : Bit_RESET);
ledval = 1 - ledval;
change=0;
}
};
return
0;
}
void
TIM2_IRQHandler(
void
){
change=1;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
#ifdef USE_FULL_ASSERT
void
assert_failed(uint8_t* file, uint32_t line)
{
while
(1);
}
#endif
Thanks for your help :)
#stm32 #timer #interrupt #exti
2013-08-28 04:38 AM
Interrupting the processor at several hundred KHz, is probably getting close to saturating a 24 MHz processor. Limited by the number of instructions per interrupt.
You'd definitely want to change your interrupt so it doesn't re-enter (M3/NVIC pipeline hazard), by doing the clearing early.void TIM2_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
change=1;
}