2024-04-29 05:30 PM
So here's the code ; The issue with it is that whenever I press the button, weird things occur, such as my output resetting completely-going to the maximum, at my output I have a variable PWM signal
void PB_Init(void){
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
GPIOC->MODER |= ( 0x0 << GPIO_MODER_MODE13_Pos);
GPIOC->PUPDR |= ( 0x1 << GPIO_PUPDR_PUPD13_Pos);
}
void EXTI15_10_Init(void){
PB_Init(); // Initialize PC13 as input.
RCC->APB2ENR |= (1<<14); // Enable System configuration controller
SYSCFG->EXTICR[3] &= ~(1<<7); // Select Port C as source, EXTIx = 0b0010
SYSCFG->EXTICR[3] &= ~(1<<6); // Select Port C as source, EXTIx = 0b0010
SYSCFG->EXTICR[3] |= (1<<5); // Select Port C as source, EXTIx = 0b0010
SYSCFG->EXTICR[3] &= ~(1<<4); // Select Port C as source, EXTIx = 0b0010
EXTI->IMR |= (1<<13); // Disable interrupt request mask on EXTI line 13
EXTI->FTSR |= (1<<13); // Enable EXTI on Falling edge
EXTI->RTSR &= ~(1<<13); // Disable EXTI on Rising edge
RCC->APB2ENR &= ~(1<<14); // Disable System configuration controller
}
volatile bool flag=0;
void EXTI15_10_IRQHandler(void){
if(flag==0){
TIM2->CR1|=TIM_CR1_CEN;
flag=!flag;
EXTI->PR |= (1<<13); // Clear PR to re-enable EXTI interrupt
}else{
TIM2->CR1&=~TIM_CR1_CEN;
flag=!flag;
EXTI->PR |= (1<<13); // Clear PR to re-enable EXTI interrupt
}
}
void Interrupt_Init(void){
EXTI15_10_Init(); // Step 1, this is defined elsewhere
NVIC->IP[EXTI15_10_IRQn] = (1 << 4); // Step 3: Set priority to 1
NVIC->ISER[40 >> 5] |= (1 << (40 % 32)); // Step 4: Enable interrupt
}
, can anyone point me in the right direction?
Solved! Go to Solution.
2024-05-08 01:56 PM
Hello, I have fixed the issue and will mark it as a solution when I can
here's the code
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
}
//main
while (1)
{
int x;
for(x=0; x<500; x++)
{
if(flag.bits_access.flag== 1){
x=x-1;
TIM2->CCR1=x;
}
else{
TIM2->CCR1=x;
delayTRIP(1);
}}
for(x=500; x>0; x--)
{
if(flag.bits_access.flag== 1){
x=x+1;
TIM2->CCR1=x;
}
else{
TIM2->CCR1=x;
delayTRIP(1);
}
}
}}
the issue was that I wasnt checking for the flag at the right time and used the wrong registers for the stopping of the PWM
2024-04-29 06:23 PM
Does your button jitter?
2024-05-03 03:52 AM
Hello @Petrarka,
You should ensure that the interrupt flag is cleared only after you've handled the interrupt:
void EXTI15_10_IRQHandler(void){
if(EXTI->PR & EXTI_PR_PR13){ // Check if the interrupt is for EXTI line 13
if(flag == 0){
TIM2->CR1 |= TIM_CR1_CEN; // Enable TIM2
flag = 1;
} else {
TIM2->CR1 &= ~TIM_CR1_CEN; // Disable TIM2
flag = 0;
}
EXTI->PR |= EXTI_PR_PR13; // Clear the pending bit for EXTI line 13
}
}
Also when clearing the mode bits for pin 13 to set it as an input, I think it should be an AND instead of an OR which won't clear the bits if they are already set to 1
GPIOC->MODER &= ~(0x0 << GPIO_MODER_MODE13_Pos);
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.
2024-05-08 01:56 PM
Hello, I have fixed the issue and will mark it as a solution when I can
here's the code
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
}
//main
while (1)
{
int x;
for(x=0; x<500; x++)
{
if(flag.bits_access.flag== 1){
x=x-1;
TIM2->CCR1=x;
}
else{
TIM2->CCR1=x;
delayTRIP(1);
}}
for(x=500; x>0; x--)
{
if(flag.bits_access.flag== 1){
x=x+1;
TIM2->CCR1=x;
}
else{
TIM2->CCR1=x;
delayTRIP(1);
}
}
}}
the issue was that I wasnt checking for the flag at the right time and used the wrong registers for the stopping of the PWM