cancel
Showing results for 
Search instead for 
Did you mean: 

Counter Problem in Timer Interrupt

AE104
Senior

Hello,

I set a timer timer in global interrupt mode. I monitored successfully a GPIO toggling with desired interrupt frequency. But a counter didn't increase in every timer interrupt cycle it was stuck at 1. Do you have any suggestions about the problem?

Thank you,

if (timer_flag){
	  				txConvertData = ReadCommandMask | (255 << 8);
	  				HAL_GPIO_WritePin(IN_SPI2_CS_GPIO_Port, IN_SPI2_CS_Pin, GPIO_PIN_RESET);
	  				hal_status = HAL_SPI_TransmitReceive(&hspi2, (uint8_t*) &txInConvertData, (uint8_t*) &rxInConvertData[j], 1, 100);
	  				HAL_GPIO_WritePin(IN_SPI2_CS_GPIO_Port, IN_SPI2_CS_Pin, GPIO_PIN_SET);
	  				HAL_Delay(100);
	  					if (hal_status != HAL_OK) {
	  						printf("HAL SPI TransmitReceive error: %d\r\n", (int) hal_status);
	  					}
	  			j = j + 1;
	  			//timer_flag = 0;
 
	  		}
	  		if (j == 20000){
	  			HAL_TIM_Base_Stop_IT(&htim10);
	  			j = 0;
	  			timer_flag = 0;
	  		}
 
 
/* USER CODE BEGIN 4 */
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
	if (htim == &htim10){
		timer_flag = 1;
		HAL_GPIO_TogglePin(EV_CH1_GPIO_Port, EV_CH1_Pin);
	}
}
 
/* USER CODE END 4 */

27 REPLIES 27
Bob S
Principal

What exactly do you mean by "But a counter didn't increase in every timer interrupt cycle it was stuck at 1"? What counter? The timer's CNT register? Your main code "j" variable?

If you are trying to read the CNT register inside the callback function, I would EXPECT it to be something like "1" every time. I presume the timer is set to interrupt on update (i.e. CNT == ARR), which means the CNT resets to zero and starts counting again. And by the time the HAL code calls your callback, it has incremented to 1.

BTW - make sure you have "timer_flag" declared as "volatile".

AE104
Senior

I mean j variable.

The current setting of the timer is like that,


_legacyfs_online_stmicro_images_0693W00000bhjTbQAI.png

gbm
Lead III

That's probably because of HAL_Delay() call blocking the dtetection of flag set by timer interrupt.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Karl Yamashita
Lead III

@AE104​ ,

From what I see that is possibly the problem that you're facing is the timer_flag variable. Even though in HAL_TIM_PeriodElapsedCallback interrupt you are setting timer_flag = 1, in you main loop your if(timer_flag) will be false, so it won't run that part of the code to increment j variable.

So just like @Bob S​ said, be sure to have timer_flag declared as volatile so it isn't optimized, like...

volatile uint32_t timer_flag = 0;

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.
AE104
Senior

Right, the j value is not increasing even I set the timer_flag as volatile.

Karl Yamashita
Lead III

Post the function that the if statement is in. I suspect the variable j is declared local

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.
AE104
Senior

Sure.. Yes the j is local.

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_DMA_Init();
  MX_ADC1_Init();
  MX_DAC_Init();
  MX_SPI2_Init();
  MX_SPI3_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_I2C2_Init();
  MX_TIM10_Init();
  MX_TIM11_Init();
  MX_TIM13_Init();
  MX_TIM14_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
 
  HAL_TIM_Base_Start(&htim10);  //initializes Timer 10
  HAL_TIM_Base_Start_IT(&htim10);  //initializes Timer 10
  HAL_StatusTypeDef hal_status;
 
 
  uint16_t j = 0;
 
 
   uint16_t rxInCalibrateData[30];
   uint16_t txInCalibrateData[30];
   uint16_t txInConvertData;
   uint16_t rxInConvertData[20002];
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
		  		  for (int i = 0; i < 30; i++) {
	  				 HAL_GPIO_WritePin(IN_SPI2_CS_GPIO_Port, IN_SPI2_CS_Pin, GPIO_PIN_RESET);
	  				 hal_status = HAL_SPI_TransmitReceive(&hspi2, (uint8_t*) &txInCalibrateData[i], (uint8_t*) &rxInCalibrateData[i], 1, 100);
	  				 HAL_GPIO_WritePin(IN_SPI2_CS_GPIO_Port, IN_SPI2_CS_Pin, GPIO_PIN_SET);
	  				 HAL_Delay(100);
	  				   if (hal_status != HAL_OK) {
	  				 	  printf("HAL SPI TransmitReceive error: %d\r\n", (int) hal_status);
	  				   }
	  		  }
 
 
	  	    // Send read command
 
	  		if (timer_flag){
	  				txInConvertData = ReadCommandMask | (255 << 8);
	  				//txInConvertData = ConvertCommandMask | (0 << 8); // Converts Channel
	  				HAL_GPIO_WritePin(IN_SPI2_CS_GPIO_Port, IN_SPI2_CS_Pin, GPIO_PIN_RESET);
	  				hal_status = HAL_SPI_TransmitReceive(&hspi2, (uint8_t*) &txInConvertData, (uint8_t*) &rxInConvertData[j], 1, 100);
	  				HAL_GPIO_WritePin(IN_SPI2_CS_GPIO_Port, IN_SPI2_CS_Pin, GPIO_PIN_SET);
	  				//HAL_Delay(100);
	  					if (hal_status != HAL_OK) {
	  						printf("HAL SPI TransmitReceive error: %d\r\n", (int) hal_status);
	  					}
	  			j = j + 1;
	  			//timer_flag = 0;
	  		}
 
	  		if (j == 20000){
	  			HAL_TIM_Base_Stop_IT(&htim10);
	  			j = 0;
	  			timer_flag = 0;
	  		}

Bob S
Principal

Do you have the TIM10 interrupt enabled in the "NVIC" tab of the timer config dialog in CubeMX?

Does your callback ever get called? Set a breakpoint and see.

AE104
Senior

Yes, it was enabled.

Yes, I placed a toggling command for a GPIO pin and it worked.