cancel
Showing results for 
Search instead for 
Did you mean: 

GPIO Interrupt not working Properly.

Rohit007
Associate III

Hello,

I am using the stm32G0B1RE MCU board to detect the GPIO interrupts, after every 140ms, but MCU is not responding to these interrupts fully, like I need to detect the 30 interrupts in 4 seconds, but MCU is detecting only 20 to 21 interrupts, but as I try to detect these interrupts in more time like 30 seconds to 6 seconds in between I am getting all the interrupts. but, after  this giving less time like 4 seconds or 5 seconds , frequency of detecting those interrupt just gets reduced. 

i have also checked if I am getting all the signals on pin using CRO, it is able to detect the all the 30 signals, but MCU is not detecting those all signals.

please, help I anybody has any idea what wrong is happening.

Actually I am using a device which contains a gear with 30 tooths, which is connected to motor rotating at speed 1 RPM to 20 RPM, the gear is connected near to the IC that generates the sine and cosine waveforms according to the gear in between the two tooth and also generates the interrupt whenever the tooth is passed across it.

the device I am using is working on 2.7v and stm32 is working on 3v3, can this be the issue, I don't know. but the device is using the arduino MCU which is working perfectly . but I don't know why stm32 is not able to detect the same interrupts.

this is a part of code:

 
 

 

 

int main(void)

{

/* USER CODE BEGIN 1 */

 

/* USER CODE END 1 */

 

/* MCU Configuration--------------------------------------------------------*/

 

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

 

/* USER CODE BEGIN Init */

 

/* USER CODE END Init */

 

/* Configure the system clock */

SystemClock_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_USART2_UART_Init();

MX_ADC1_Init();

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

init_TMR_sensor(&hadc1, &TMR_info);

HAL_ADCEx_Calibration_Start(&hadc1);

 

 

while (1)

{

printf("%d\r\n",tooth);

HAL_Delay(100);

 

}

 

 

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

 

}

/* USER CODE END 3 */

}

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)

{

tooth++;

}

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOF_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

 

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);

 

/*Configure GPIO pin : TOOTH_GEAR_EXTI_Pin */

GPIO_InitStruct.Pin = TOOTH_GEAR_EXTI_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(TOOTH_GEAR_EXTI_GPIO_Port, &GPIO_InitStruct);

 

/*Configure GPIO pin : DIRECTION_GPIO_Pin */

GPIO_InitStruct.Pin = DIRECTION_GPIO_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLDOWN;

HAL_GPIO_Init(DIRECTION_GPIO_GPIO_Port, &GPIO_InitStruct);

 

/*Configure GPIO pin : LED_GREEN_Pin */

GPIO_InitStruct.Pin = LED_GREEN_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(LED_GREEN_GPIO_Port, &GPIO_InitStruct);

 

/*Configure GPIO pin : TMR_TOOTH_INTERRUPT_PIN_Pin */

GPIO_InitStruct.Pin = TMR_TOOTH_INTERRUPT_PIN_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull = GPIO_PULLDOWN;

HAL_GPIO_Init(TMR_TOOTH_INTERRUPT_PIN_GPIO_Port, &GPIO_InitStruct);

 

/* EXTI interrupt init*/

HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);

 

/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}

 

 

10 REPLIES 10

Please see How to insert source code for how to properly post source code.

See also How to write your question to maximize your chances to find a solution - you need to provide hardware details

SofLit
ST Employee

Hello,

How you did conclude that only 20 interrupts instead of 30 with this code are raised?

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
  tooth++;
}
while (1)
{
  printf("%d\r\n",tooth);
  HAL_Delay(100);
}

Better to tag the systick counter using HAL_GetTick() each time an interrupt occurs and do your analysis based on that. Diplaying the values with printf in while loop is not an efficient way for this kind of debug.

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.
TDK
Guru

If edges occur very close to one another, say within a few us, the callback will only trigger once. Could be what is happening.

How do you know there are 30 edges within that period? Can you show them on a multimeter?

If you feel a post has answered your question, please click "Accept as Solution".
Karl Yamashita
Lead III

I am using the stm32G0B1RE MCU board to detect the GPIO interrupts, after every 140ms, but MCU is not responding to these interrupts fully, like I need to detect the 30 interrupts in 4 seconds


Well basic math, 30 interrupts at 140ms is 4.2 Seconds. So how you expecting to get 30 interrupts in 4 seconds?

Also, have you checked the trigger with a scope to see if it goes below the minimum voltage to registers as a low trigger?

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

@SofLit i am just printing a global variable, after all the interrupts are served, this count should become 30, instead it remains randomly on lesser than it.

@TDK I have checked the edges on CRO, and I am using a setup that has 30 gear tooth that gives interrupt at every tooth is passed through the IC that reads the signals using a magnet connected to it. 

Difference between the each rising edge passed is 140ms which I believe is enough.

@Karl Yamashita i am just giving an approx. value for what I am getting, but is it necessary that the device I am using to generate these interrupts is working on 2.7v and the stm32 is working on 3.3v. can this be the issue that I am having boundary case.

 

You can in one reply @ more peaple...

And your code activate two GPIO IRQ , but only one ISR with priority. Maybe show too it file part for exti...

Next problem maybe is print every 100ms , how speed and method prints?

Try

if ((tooth%30)==0) printf("%d\r\n",tooth);
Techn
Senior III

You can generate pulses digitally at this rate and see if stm32 is able to detect or not.  Then calculate the frequency by timing with systick. When count reaches 30, divide the count by time.

FYI, if you need just count, use timer who's input comes from the pin connected to the sensor.

Please check the clock at which cpu operate.

If you feel a post has answered your question, please click "Accept as Solution".