2024-05-08 02:53 PM
Hello, first of all, thanks for all the previous help to everyone. I want to debounce my input, using registers, but I'm running into the issue of it "not working" I am surely missing something in the logic I am overlooking.
here is my interrupt
void Interrupt_Init(void){
EXTI15_10_Init();
NVIC->IP[EXTI15_10_IRQn] = (1 << 4);
NVIC->ISER[40 >> 5] |= (1 << (40 % 32));
}
union InterruptFlag {
struct {
volatile bool flag: 1; // Just one bit for our flag
volatile bool press: 1;
} bits_access;
uint32_t reg; // We'll use this for byte access
};
volatile union InterruptFlag flag = { .bits_access.flag = 0 }; // Initialize to 0
volatile uint16_t pressTime;
volatile bool lastButtonPress=0;
volatile bool buttonPress=1;
void EXTI15_10_IRQHandler(void){
flag.bits_access.flag = !flag.bits_access.flag;
EXTI->PR |= (1<<13); // Clear PR to re-enable EXTI interrupt
}
bool debounceButton(){
TIM3->CR1 |= TIM_CR1_CEN;
if((GPIOC->IDR & GPIO_IDR_ID13)!=lastButtonPress){
if(GPIOC->IDR & GPIO_IDR_ID13){
pressTime=TIM3->CNT;
}else{
if(pressTime>10){
flag.bits_access.press=1;
return 1;
}
}
lastButtonPress=GPIOC->IDR & GPIO_IDR_ID13;
}
return 0;
}
and above is the debouncing function
and this is what happens in the main function;
while (1)
{
int x;
for(x=0; x<500; x++)
{
if(debounceButton()== 1){
x=x-1;
TIM2->CCR1=x;
}
else{
TIM2->CCR1=x;
delayTRIP(1);
}}
for(x=500; x>0; x--)
{
if(debounceButton()== 1){
x=x+1;
TIM2->CCR1=x;
}
else{
TIM2->CCR1=x;
delayTRIP(1);
}
}
}}
]
the button should stop when I press the button for x amount of milliseconds, but whatever I put into the debounce functin doesnt work
2024-05-09 06:39 AM
Hello @Petrarka,
I think that the ISR should only flag that a button press event has occurred. It should not toggle the flag by using
flag.bits_access.flag = !flag.bits_access.flag;
So instead:
void EXTI15_10_IRQHandler(void){
if(EXTI->PR & (1<<13)){ // Check if the interrupt is from the correct pin
flag.bits_access.flag = 1; // Set the flag to indicate button press event
EXTI->PR |= (1<<13); // Clear PR to re-enable EXTI interrupt
}
}
In the debounce function, I suggest the following code ( after defining DEBOUNCE_TIME_MS and BUTTON_PRESSED_STATE)
bool debounceButton(){
if(flag.bits_access.flag){ // Check if an interrupt has occurred
flag.bits_access.flag = 0; // Clear the interrupt flag
if((GPIOC->IDR & GPIO_IDR_ID13) != lastButtonPress){ // Check if the button state has changed
lastButtonPress = GPIOC->IDR & GPIO_IDR_ID13; // Update the last button state
pressTime = TIM3->CNT; // Reset the timer count
} else {
if((TIM3->CNT - pressTime) > DEBOUNCE_TIME_MS){ // Check if the button has been stable for the debounce time
if(lastButtonPress == BUTTON_PRESSED_STATE){ // Check if the button is pressed
flag.bits_access.press = 1; // Set the press flag
return true;
}
}
}
}
return false;
}
Also, to control the PWM value independently of the for-loop counter, use a seperate variable to track the PWM value and only update TIM2->CCR1 with this variable
Make sure delayTRIP(1) is not a blocking delay
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.