2013-04-10 04:57 AM
Hi,
I am using the STM32L151VB on a custom board. The MCU is clocked by HSI. I have two rising edge interrupts on port E pin 9 and port E pin I capture the timer counter for timer 4 in both the interrupts. The problem is that for each rising edge I am getting multiple interrupts and hence wrong values of timer 4 are captured. If I can ensure that only one interrupt per rising edge is generated it will solve my problem. Also my pulses have varying widths so using delay is not possible. Please advise. I have pasted my code below:void WS_Init_Wind_Sensors_Input()
{
GPIO_InitTypeDef gpio_init_structure;
EXTI_InitTypeDef exti_init ;
/* Enable GPIO clocks */
RCC_AHBPeriphClockCmd(WIND_SPEED_SENSOR_RCC_AHBPeriph | WIND_DIRECTION_SENSOR_RCC_AHBPeriph, ENABLE);
gpio_init_structure.GPIO_Pin = WIND_SPEED_SENSOR_GPIO_PIN;
gpio_init_structure.GPIO_Mode = GPIO_Mode_IN;
gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_init_structure.GPIO_Speed = GPIO_Speed_40MHz;
gpio_init_structure.GPIO_OType = GPIO_OType_PP;
/* Initialise the GPIO accordingly */
GPIO_Init(WIND_SPEED_SENSOR_GPIO_PORT, &gpio_init_structure);
gpio_init_structure.GPIO_Pin = WIND_DIRECTION_SENSOR_GPIO_PIN;
/* Initialise the GPIO accordingly */
GPIO_Init(WIND_DIRECTION_SENSOR_GPIO_PORT, &gpio_init_structure);
/* The syscfg module is clocked */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* The EXTI mux is on exti line RG_EXTI_PINSOURCE for this GPIO pin */
SYSCFG_EXTILineConfig(WIND_SPEED_SENSOR_EXTI_PortSource,WIND_SPEED_SENSOR_EXTI_PinSource);
/* The EXTI mux is on exti line RG_EXTI_PINSOURCE for this GPIO pin */
SYSCFG_EXTILineConfig(WIND_DIRECTION_SENSOR_EXTI_PortSource,WIND_DIRECTION_SENSOR_EXTI_PinSource);
EXTI_StructInit(&exti_init);
exti_init.EXTI_Line = WIND_SPEED_SENSOR_EXTI_LINEx;
exti_init.EXTI_LineCmd = ENABLE;
exti_init.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&exti_init);
/*Enable the interrupt in the NVIC */
INIT_NVIC_Enable_Peripheral_Interrupt(WIND_SPEED_SENSOR_EXTIx_IRQn,0,0);
exti_init.EXTI_Line = WIND_DIRECTION_SENSOR_EXTI_LINEx;
exti_init.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&exti_init);
/*Enable the interrupt in the NVIC */
INIT_NVIC_Enable_Peripheral_Interrupt(WIND_DIRECTION_SENSOR_EXTIx_IRQn,2,2);
}
int td1x, ts1x, ts2x ;
/*!
Interrupt handler for pulse 1
*/
void EXTI9_5_IRQHandler(void)
{
INIT_NVIC_Disable_Peripheral_Interrupt(WIND_DIRECTION_SENSOR_EXTIx_IRQn,0,0);
EXTI->PR = EXTI_Line9 ;
/* This is being set multiple times for each rising edge since the interrupt is being re-entrant */
td1x = TIM4->CNT;
INIT_NVIC_Enable_Peripheral_Interrupt(WIND_DIRECTION_SENSOR_EXTIx_IRQn,0,0);
}
/*!
Interrupt handler for pulse 2
*/
void EXTI15_10_IRQHandler()
{
static int x = 1;
INIT_NVIC_Disable_Peripheral_Interrupt(WIND_SPEED_SENSOR_EXTIx_IRQn,0,0);
EXTI->PR = EXTI_Line10;
/* This is being set multiple times for each rising edge since the interrupt is being re-entrant */
x ^= 1;
if(x)
{
ts2x = TIM4->CNT;
}
else
{
ts1x = TIM4->CNT;
}
INIT_NVIC_Enable_Peripheral_Interrupt(WIND_SPEED_SENSOR_EXTIx_IRQn,0,0);
}
#stm32l151 #interrupt-problem
2013-04-10 06:54 AM
Are you sure you don't have some issues with bounce or noise on the signal lines? Do you need pull ups? Can you sample with a fast scope/analyzer? How about toggling GPIO pins to confirm the diagnosis?
I don't care much for your interrupt routines.void EXTI9_5_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line9) != RESET)
{
/* Clear the EXTI line 9 pending bit */
EXTI_ClearITPendingBit(EXTI_Line9);
td1x = TIM4->CNT;
}
}
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line10) != RESET)
{
static int x = 1;
/* Clear the EXTI line 10 pending bit */
EXTI_ClearITPendingBit(EXTI_Line10);
x ^= 1;
if(x)
{
ts2x = TIM4->CNT;
}
else
{
ts1x = TIM4->CNT;
}
}
}
2015-04-29 01:19 AM
Hi, I have a problem with RTC alarm interrupt when clocking by HSI. Program just stopped and don't go further. With HSE all work fine, but when I remove external quartz, it stop. Here my code, pls help.
P.S. for clock I use LSE#include ''stm32l1xx.h''
#define K1 GPIO_SetBits(GPIOC,GPIO_Pin_8)
#define K2 GPIO_SetBits(GPIOC,GPIO_Pin_7)
#define K3 GPIO_SetBits(GPIOC,GPIO_Pin_6)
#define K4 GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define K5 GPIO_SetBits(GPIOB,GPIO_Pin_14)
#define K6 GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define K7 GPIO_SetBits(GPIOB,GPIO_Pin_12)
#define K8 GPIO_SetBits(GPIOB,GPIO_Pin_11)
#define STATUS_LED GPIO_ToggleBits(GPIOC,GPIO_Pin_9);
void RTC_Config(void);
void RTC_TimeRegulate(void);
void init(void);
void sleep(void);
GPIO_InitTypeDef GPIO_InitStructure;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_InitTypeDef RTC_InitStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
__IO uint32_t AsynchPrediv = 0, SynchPrediv = 0;
uint32_t hour=8,minute=0,second=00;
uint32_t alarm_hour=8,alarm_minute=0,alarm_second=01;
uint8_t k_led=0;
void RTC_Config(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_RTCAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
}
void sleep(void)
{
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
PWR_UltraLowPowerCmd(ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
}
void RTC_TimeRegulate(void)
{
RTC_TimeStructure.RTC_Hours = hour;
RTC_TimeStructure.RTC_Minutes = minute;
RTC_TimeStructure.RTC_Seconds = second;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);
RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = alarm_hour;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = alarm_minute;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = alarm_second;
RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x31;
RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
}
void RTC_Alarm_IRQHandler (void)
{
RCC_ClearITPendingBit(RCC_IT_CSS);
EXTI_ClearITPendingBit(EXTI_Line17);
alarm_second++;
if (alarm_second==60)
{
alarm_second=0;
alarm_minute++;
if (alarm_minute==60)
{
alarm_minute=0;
alarm_hour++;
if (alarm_hour==24) alarm_hour=0;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = alarm_hour;
}
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = alarm_minute;
}
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = alarm_second;
k_led++;if(k_led==9)k_led=0;
RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
RTC_ClearFlag(RTC_FLAG_ALRAF);
RCC_DeInit();
RCC_ClockSecuritySystemCmd(DISABLE);
// RCC_ClearITPendingBit(RCC_IT_CSS);
// RCC_PLLConfig(RCC_PLLSource_HSI,RCC_PLLMul_3,RCC_PLLDiv_2);
RCC_HSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
{}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
RCC_HCLKConfig(RCC_SYSCLK_Div2);
// RCC_MSICmd(DISABLE);
// RCC_HSEConfig(RCC_HSE_OFF);
// RTC_Config();
// RCC_HSEConfig(RCC_HSE_ON);
// while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)
// {}
switch (k_led){
case (0):
{GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
GPIO_ResetBits(GPIOC,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);break;}
case (1): {K1;break;}
case (2): {K2;break;}
case (3): {K3;break;}
case (4): {K4;break;}
case (5): {K5;break;}
case (6): {K6;break;}
case (7): {K7;break;}
case (8): {K8;break;}
}
STATUS_LED;
}
void init(void)
{
RCC_ClearITPendingBit(RCC_IT_CSS);
RCC_DeInit();
RCC_ClockSecuritySystemCmd(DISABLE);
// RCC_PLLConfig(RCC_PLLSource_HSI,RCC_PLLMul_3,RCC_PLLDiv_2);
RCC_HSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
{}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
RCC_HCLKConfig(RCC_SYSCLK_Div2);
// RCC_MSICmd(DISABLE);
// RCC_HSEConfig(RCC_HSE_OFF);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_9);
EXTI_DeInit();
PWR_RTCAccessCmd(ENABLE);
RTC_WaitForSynchro();
RTC_ClearFlag(RTC_FLAG_ALRAF);
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)
{
RTC_Config();
RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
}
RTC_TimeRegulate();
}
int main(void)
{
// uint32_t i=0;
init();
while(1)
{
sleep();
// STATUS_LED;
// for(i=0;i<0xFFFF;i++);
}
}
2015-04-29 02:00 AM
Please don't hijack other's thread, start your own.
JW2016-08-20 02:53 AM
Hi all;
I'm trying to count pulses using an external timer interrupt with stm32f103, and the code is to some extent the same.
for 10ms pulses I get 50 to 60 cycles left behind, butfor lower frequencies the result is quite accurate
I can't figure out what the problem is
please help
void Configure_PA(void) {
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_9 | GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource11);
EXTI_InitStruct.EXTI_Line = EXTI_Line11; // EXTI15_10_IRQn
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Set sub priority */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource10);
EXTI_InitStruct.EXTI_Line = EXTI_Line10;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource9);
EXTI_InitStruct.EXTI_Line = EXTI_Line9;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA , GPIO_PinSource8);
EXTI_InitStruct.EXTI_Line = EXTI_Line8;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
}
/* Handle Digital Input interrupts */
void EXTI15_10_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line11) != RESET) {
CounterCh[1]++;
EXTI_ClearITPendingBit(EXTI_Line11);
}
if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
CounterCh[2]++;
EXTI_ClearITPendingBit(EXTI_Line10);
}
}
void EXTI9_5_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line9) != RESET) {
CounterCh[3]++;
EXTI_ClearITPendingBit(EXTI_Line9);
}
if (EXTI_GetITStatus(EXTI_Line8) != RESET) {
CounterCh[4]++;
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
2016-08-20 06:08 AM
This could have been in it's own thread.
So what frequencies are we talking about here? What speed is the F1 running at? Please post complete examples, it is hard to review code missing variables and defines, and I don't build/test code that doesn't compile. The code looks like it should be viable at speeds well over 100 Hz (per 10ms pulse width)2016-08-20 11:19 PM
Thanks for your answer Clive
The stm32f103 is running at its maximum speed of 72MHz and the GPIO frequency is 50MHz. In order to test the code I've taken use of two separate boards, one for generating the pulses and the other for receiving them. both send the pulse numbers on usart so thatI can compare the generated pulses and the received ones. I've configured timers on both ucs equally, sending the results every 10ms. after 10-15 seconds the receiving end gets about 50 cycles left behind. The code I've used for the receiving end is attached. Please help Thanks ________________ Attachments : EXTI_Code.txt : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0gO&d=%2Fa%2F0X0000000bcP%2FM8gkaI8F2Bs8VZLM5H1ceMJmN12KqDpbYln89jp_bKs&asPdf=false2016-08-21 05:58 AM
You want the array volatile as you're changing values under interrupt.
volatile int CounterCh[1] = { 0 }; The first element is CounterCh[0] not 1 You should generate test pulse train on the same chip (common clock domain). Don't do printf or USART output in the IRQ, it would copy the count to a snap-shot variable and zero the current count. In the main while loop I'd look for a non-zero in the snap-shot variable and then output that to the USART before clearing it again. The 50MHz GPIO setting is an output slew-rate control, doesn't relate to inputs. Using a TIM in External Clock mode would be a way to cross-check measurements, I'd use that to confirm if the counts were coherent.