2021-09-23 08:04 AM
Hello everybody,
how can I count which pin triggers an interrupt, but not multiple times? I have written the following ISR.
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4)
{
data = (uint8_t)GPIOB->IDR& 0xF;
if((GPIO_PIN_0 & data )== GPIO_PIN_0) {
counter_Pin0++;
}
if((GPIO_PIN_1 & data )== GPIO_PIN_1) {
counter_Pin1++;
}
}
I first store the first four bits from GPIOB port in data and then I mask the bit form the pin. But as you can see in the picture, it is also counted when Pin 1 triggers an interrupt. The sensors have a small delay to each other, but are LOW for a certain time. I actually have 4 sensors, each of which are sometimes LOW at the same time, but trigger an interrupt at different times. Then I do not count 4 interrupts at Pin0 but 11 for example.Best Regards
Michael
2021-11-15 06:44 AM
I'm sorry I didn't see the question sooner. Is the problem solved or do you still need help?
Regards
/Peter
2021-11-16 12:16 AM
I have helped myself with this function. Since the interrupts are never triggered at the same time in my application, but only one after the other, I helped myself with an XOR and saving the old value. But I still had sometimes not correct results.
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
hall1 = (uint8_t)GPIOB->IDR& 0xF;
switch(hall1^hall_alt) //
{
case 0x1: h1_counter++; break; // Pin0
case 0x2: h2_counter++; break; // Pin1
case 0x4: h3_counter++; break; // Pin2
case 0x8: h4_counter++; break; // Pin3
default: break;
}
counter_IT++; // ISR Counter nur zu Testzwecken
hall_alt = hall1; // alter Wert wird gespeichert
}
Maybe you have a better solution? To be honest, it is not relevant anymore, but good to know how to do it for the future.
Best Regards
Michael Koza
2021-11-16 06:58 AM
There could be several reasons for the problem, but it seems to me that the interrupts are arriving faster than they can be processed?
Without more detailed information on the clock frequency, interrupt priorities and the settings of the interrupt controller, as well as other interrupt sources, it will be difficult to find a better answer than your workaround you've already found.
Regards
/Peter
2021-11-17 07:01 AM
I have built a kind of encoder with Hall sensors as you can see in the picture in the attachment. But the interrupts from the Hall sensors do not trigger simultaneously as you may see in the picture.
The MCU runs with 16 MHz and I have added the interrupt vector with the priorities. I have modify the lin_slave_app from the ST LIN example 5.1.
void clk_setup()
{
CLK_CCO |= 0x08; /* select fcpu for CCO output */
CLK_CKDIV = 0x00; /* HSI = 16MHz*/
CLK_ICKC = 0x01;
while(!(CLK_ICKC&0x02)); /**Wait until HSI is Ready**/
}
The GPIOSs from port B are initialized as follow:
GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_IN_PU_IT); //HALL M1_1
GPIO_Init(GPIOB, GPIO_PIN_1, GPIO_MODE_IN_PU_IT); //HALL M1_2
GPIO_Init(GPIOB, GPIO_PIN_2, GPIO_MODE_IN_PU_IT); //HALL M1_3
GPIO_Init(GPIOB, GPIO_PIN_3, GPIO_MODE_IN_PU_IT); //HALL M2_4
GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_IN_PU_IT); //HALL M2_1
GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_IN_PU_IT); //HALL M2_2
GPIO_Init(GPIOB, GPIO_PIN_6, GPIO_MODE_IN_PU_IT); //HALL M2_3
GPIO_Init(GPIOB, GPIO_PIN_7, GPIO_MODE_IN_PU_IT); //HALL M2_4
//-------------------------------------------------------------------//
EXTI_DeInit();
EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_FALL_ONLY);
enableInterrupts();
But as I said, it's not that important anymore and I don't want to bother you with trivial problems ;)
Best Regards
Michael Koza
2021-11-17 07:20 AM
Well, that is indeed interesting, but I have currently no suggestion to completely avoid the problem.
But I would like to point out one more thing: it looks like you are using the STM8A?
I do not want to neglect to point out that all STM8A (automotive variants) have been set to NRND (Not Recommended for New Design), are guaranteed to be available for another 10 years, but will be delivered for the last time at the beginning of 2031. You should therefore look around early for alternatives, although you can definitely find something within the STM32 family, which, however, can not be operated with 5V.
Regards
/Peter
2021-12-04 12:15 PM
Hi Mkoza,
I think your function with xor-ing the current value with the old one is not really correct. You can still have more than1 bit change it's level until you read the new values, so I would do the following:
change = hall1 ^ hall_alt;
if (change & 0x01) {
// pin0 toggle
}
if (change & 0x02) {
// pin1 toggle
}
if (change & 0x04) {
// pin2 toggle
}
if (change & 0x08) {
// pin3 toggle
}
This way you catch changes on multiple pins.