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

Sorry - you did say that earlier.

I just noticed that you have the "timer_flag =0" line commented out after you increment j. By NOT clearing timer_flag, that loop will run over and over until J finally reaches 20000. But that doesn't explain (I presume) j always equal 1 when the interrupt fires.

Also, what frequency are you expecting from the timer? I'm guessing maybe every 250us based on your prescaler and ARR values (and guessing the SYSCLK freq is 80 MHz). You have 30 SPI transactions at the top of the while() loop. Is it possible those are taking much longer than the timer interrupt period?

AE104
Senior

No worries...

You're right, I fixed it.

Yes, 250 us is my interrupt timer period. I am not sure about the time duration of that. I call the 30 SPI commands to setup the registers of the ADC chip. Th really strange point is that why j is not increasing. Other than that everything is normal.

AE104
Senior

J gets 0 and 1 then it stops.

Karl Yamashita
Lead III

See if declaring j as static or declare it global outside of main works.

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

It is also a global variable.

AE104
Senior

I have also another idea to set a delay with the timer and for loop. I will first create a macro to control us delay. Then call it in a for loop. Does it work like statement, for(int i = 0; i<20000; i=i+delay_us(250)){

SPI function}

?

Karl Yamashita
Lead III

You declared j inside main so j is a local variable

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.
Bob S
Principal

You have a 100ms delay in the loop that writes the calibration data (the i=0 to 30 loop). In that 100ms you will get 400 timer interrupts. Maybe THAT is why it appears that J is stuck at 1?

Do you really have to write the (same) data every time before you read the resulting data? You don't say what device you are talking to, but that sounds..... odd.

How long does it take to send those 30 SPI transactions? Longer than 250us? If so, and if your goal is to take a sample every 250us, that obviously won't work.

To help diagnose what is going on, set a breakpoint in the callback where you set timer_flag. When you hit that breakpoint, set another breakpoint in your main loop where you test timer_flag. Hit "run" and see what happens

> I have also another idea to set a delay with the timer and for loop

NO NO NO - don't change other parts of the code until you have found/fixed/explained what is happening.

Wait... I just re-read this:

> It is also a global variable.

Do you mean you have "j" declared as both a global variable AND a local (in main) variable?

If "j" is NOT also a global variable, then ignore the rest of this post.

That won't necessarily break your code, but it WILL confuse things (if not today, then down the road). The code in main() will always read/write to the local variable, as that "hides" the global variable. But the debugger may show you the global variable, depending on the context when you viewed that variable. There is a compiler flag to warn you of this, cause it is really horrible programming practice. I don't recall the specific flag, but setting "-Wall" should enable it, and is a good idea in general.

AE104
Senior

"You have a 100ms delay in the loop that writes the calibration data (the i=0 to 30 loop). In that 100ms you will get 400 timer interrupts. Maybe THAT is why it appears that J is stuck at 1?"

I disabled the 100ms delay but the j variable didn't increase.

The datasheet of the chip said that it is a calibration data because of that I call it. This is the chip that I try to control it, https://intantech.com/files/Intan_RHD2000_series_datasheet.pdf

Should I move the SPI tx/rx codes in the callback function?

I placed the breakpoints at the callback function and timer_flag line. In the debug session, the arrow next to the line jumps to the call back function and the arrow stays at htim == him10 line every run button hit. I captured the screenshot. I don't know how many times I pressed the run button but the arrow stayed at htim == him10 line.

j is a local variable. I double checked it. Thank you @bob S​ and @Community member​ 


_legacyfs_online_stmicro_images_0693W00000bhtMaQAI.png