2014-01-04 04:40 AM
Hello,
I am using STM32VLDISCOVERY and connected 4 tiny push buttons to Pins PB12, PB13, PB14 and PB I am using external pull-up resistors of 100K each (I guess 10K would be much better). Using the following code, I found out that pressing one button generates interrupt on the corresponding pin as well as others (I put multiple breakpoints in the interrupt handle and watched the behaviour using the debugger). I suspected something wrong with my buttons circuitry. So, I disconnected my external board that holds the buttons and pull-up resistors, and changed the code to use the internal pull-up resistors in the STM Just touching the PINs with my finger generates interrupts on these PINs. If the interrupt triggering is that sensitive to the 50Hz induced by touching the pin then how should I handle the circuitry around my buttons to ensure a stable operation. Thank you.#include ''stm32f10x.h''
void GPIO_In_Floating(void);
void Buttons_Config(void);
/**
**===========================================================================
**
** Abstract: main program
**
**===========================================================================
*/
int main(void)
{
/* Configure system clock to HSI @ 8MHz in the system_stm32f10x.c */
/* change all IOs into Analog INP to save power */
GPIO_In_Floating();
/* Configure EXTI on User push button */
Buttons_Config();
/* Infinite loop */
while (1)
{
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
}
}
void GPIO_In_Floating(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Configure all GPIO as analog to reduce current consumption on non used IOs */
/* Enable GPIOs clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_Init(GPIOC, &GPIO_InitStruct);
// Keep the STLink Pins alive.
GPIO_InitStruct.GPIO_Pin = ~(GPIO_Pin_13 | GPIO_Pin_14);
GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Disable GPIOs clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, DISABLE);
}
void Buttons_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PB0-PB3 pin as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // external pull-up 100K resistor
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Connect EXTI12-15 Line to PB.12-15 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource13);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource15);
/* Configure EXTI12-15 line initially for active low push button detection */
EXTI_InitStructure.EXTI_Line = EXTI_Line12 | EXTI_Line13 | EXTI_Line14 | EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI0 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12) != RESET)
{
/* Clear the EXTI line 12 pending bit */
EXTI_ClearITPendingBit(EXTI_Line12);
}
if(EXTI_GetITStatus(EXTI_Line13) != RESET)
{
/* Clear the EXTI line 13 pending bit */
EXTI_ClearITPendingBit(EXTI_Line13);
}
if(EXTI_GetITStatus(EXTI_Line14) != RESET)
{
/* Clear the EXTI line 14 pending bit */
EXTI_ClearITPendingBit(EXTI_Line14);
}
if(EXTI_GetITStatus(EXTI_Line15) != RESET)
{
/* Clear the EXTI line 15 pending bit */
EXTI_ClearITPendingBit(EXTI_Line15);
}
}
2014-01-06 03:00 AM
Hi
''I am using STM32VLDISCOVERY and connected 4 tiny push buttons'' ''I suspected something wrong with my buttons circuitry. So, I disconnected my external board that holds the buttons and pull-up resistors, and changed the code to use the internal pull-up resistors in the STM32. Just touching the PINs with my finger generates interrupts on these PINs'' What happens when you ground yourself and touch the pins? Could it be that the buttons are so small that you are touching the pins of the buttons? '' I am using external pull-up resistors of 100K each (I guess 10K would be much better).'' Yes, 100K is probably too large (Makes it subseptiable to noise as you have found) - 5K or even 2K will work as well. DO not forget you must debounce the push buttons!2014-01-12 08:27 AM
Hi,
Problem solved. I reduced the value of the pull-up resistor to 3.3K and de-bounced each of the buttons using an RC combination of 33kOhm and 100nf. No more unexpected triggering of interrupts.2014-10-28 12:06 PM
Hi,
This time, I changed to a 4x4 membrane keypad with 8 pin connector. 4 pins are connected to each row and the other 4 pins are connected to each column. I configured the STM32 to use PB12-15 as exti and connected to the 4 pins of the keypad columns. The PB12-15 are configured as well as input with internal pullup. Once again, pressing one key on the keypad, generates interrupt on all other 4 pins starting with the pin that I really pressed. It is kind of random. So, for example pressing a key that generates an interrupt on Pin 2 will sometime generate interrupts pending as well on pin 1 and 4 and sometimes pin 3 and 4 and so on. I was using msp430 before with buttons directly, and was not facing such issue. Can't I operate the keypad without hardware debouncing. That is really strange. I think the below post is describing something very similar but he did not get any answer.2014-10-29 02:48 AM
Hi
It is best to start a new thread for this but we will carry on with this existing thread. ''The PB12-15 are configured as well as input with internal pullup.'' ''Can't I operate the keypad without hardware debouncing.'' I do not believe the STM32 series has 'hardware debounce' ''Once again, pressing one key on the keypad, generates interrupt on all other 4 pins starting with the pin that I really pressed.'' Does the code just hold PB12-15 high? If all are high then it is likely that more than 1 IP will cause an EXTI irq. This is a matrix which will require matrix scanning. ie each of the row/column must be pull high one at a time, if a key is pressed then only the currently selected row and column will generate the EXTI irq.2014-10-29 04:29 AM
Hi,
Yes, what I do is the following:2014-10-29 05:28 AM
''
2014-10-30 03:38 AM
Hi,
I found a work around by masking the EXTI interrupt when first EXTI interrupt is received for the correct user action and activating it back once the SW debouncing is completed within the Timer service routine./*
* Enable the specific interrupt number
*/
void EnableButton_IRQ(void){
// Clear the EXTI line 12 pending bit
EXTI_ClearITPendingBit(EXTI_Line12 | EXTI_Line13 | EXTI_Line14 | EXTI_Line15);
EXTI->IMR = EXTI_IMR_MR12 | EXTI_IMR_MR13 | EXTI_IMR_MR14 | EXTI_IMR_MR15;
}
/*
* Disable the specific interrupt number
*/
void DisableButton_IRQ(void){
// Mask interrupt
EXTI->IMR &= ~(EXTI_IMR_MR12 | EXTI_IMR_MR13 | EXTI_IMR_MR14 | EXTI_IMR_MR15);
// Clear the EXTI line 12 pending bit
EXTI_ClearITPendingBit(EXTI_Line12 | EXTI_Line13 | EXTI_Line14 | EXTI_Line15);
}