cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 CPU loses external IO interrupt.

hoyoun lyu
Associate
Posted on March 28, 2017 at 08:26

Hi.

I am using the STM32F103VBT6 CPU and STM32F10x_StdPeriph_Driver.

I want to receive one external IO interrupt and operate 4 PWM channels at the same time.

I set the EXTI port as below and created the interrupt ISR function.

void EXTI4_init(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

/* Enable GPIOE clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 

GPIO_Init(GPIOE, &GPIO_InitStructure);

/* Enable AFIO clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

/* Connect EXTI3 Line to PE.00 pin */

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4); // 핀소스� 2번으로....

/* Configure EXTI1 line */

EXTI_InitStructure.EXTI_Line = EXTI_Line4;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

/* Enable and set EXTI1 Interrupt to the lowest priority */

NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; 

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void PWM_init(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_OCInitTypeDef TIM_OCInitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

/* System Clocks Configuration */

/* TIM3 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* GPIOA, GPIOB and GPIOE clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

//TIM3

TIM_TimeBaseStructure.TIM_Prescaler = 72; //PrescalerValue 72

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //up counting

TIM_TimeBaseStructure.TIM_Period = 9999; 

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

/* Enable the TIM3 global Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* PWM1 Mode configuration: Channel1 */

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC1Init(TIM3, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

//TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);

/* PWM1 Mode configuration: Channel2 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OC2Init(TIM3, &TIM_OCInitStructure);

TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

/* PWM1 Mode configuration: Channel3 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OC3Init(TIM3, &TIM_OCInitStructure);

TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

/* PWM1 Mode configuration: Channel4 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OC4Init(TIM3, &TIM_OCInitStructure);

TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

/* TIM3 enable counter */

TIM_Cmd(TIM3, ENABLE);

}

void EXTI4_IRQHandler(void) 

{

if(EXTI_GetITStatus(EXTI_Line4) != RESET)

{

TIM_SetCounter(TIM3, 9998);

TIM3->CCR1 = u16_PWM_On_Time[0][0]*u8_OnTime_Multiple;

TIM3->CCR2 = u16_PWM_On_Time[0][1]*u8_OnTime_Multiple;

TIM3->CCR3 = u16_PWM_On_Time[0][2]*u8_OnTime_Multiple;

TIM3->CCR4 = u16_PWM_On_Time[0][3]*u8_OnTime_Multiple;

}

/* Clear the EXTI line 2 pending bit */

EXTI_ClearITPendingBit(EXTI_Line4);

}

However, there is a problem of intermittently missing external IO interrupts.

Depending on the usage environment, the number of times is wrong, but it seems to miss about once every 100 times.

I wonder what the cause is.

Help.
1 REPLY 1
S.Ma
Principal
Posted on March 28, 2017 at 11:11

Clear the PR bit early so it can latch up another pending interrupt while in the ISR.

==> 

TIM_SetCounter(TIM3, 9998);

How long this would take? Would another way to manipulate the timer be possible?

Toggle a GPIO within the interrupt to probe on oscilloscope the timings.

Check at the beginning of the ISR if the GPIO is low. If low, an error is detected by SW, can do a breakpoint.