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

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

Goodness gracious NO!!!!!!

Does the "calibration" need to be sent EVERY TIME before you read data? I would think that it would be a one-time thing at startup, then just read data in the loop. But I'm not going to read the data sheet - that is your job.

What was that image of the first line of your callback supposed to show? I guess it shows that the callback is called for TIM10. OK. That was the first part of the debug test. Once you get there, single-step until you pass the "timer_flag=1" line, then verify that timer_flag actually contain "1". Now disable the breakpiont in the callback and set/enable a breakpoint on the "if ( timer_flag)" line in main() and hit "run". If/when you get to that breakpoint, see what timer_flag contains.

Please post the ENTIRE contents of your current main() and HAL_TIM_PeriodElapsedCallback() functions, along with any related global variable declarations, NOT USING SCREEN IMAGES but posting the actual code/text into the forum post using the "</>" (Code Snippet) button.

AE104
Senior

Sorry I just offered to escape the 30 SPI delays with moving the codes in the callback function.

Actually it is not only calibration, some certain registers set based in the 30 SPI run.

There is timer_flag=1; and a toggling GPIO pin code to see verify the timer period.

Yes, timer_flag gets 1.

OK, here is the code,

volatile uint32_t timer_flag = 0;
 
int main(void)
{
 
/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI2_Init();
  MX_TIM10_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;
 
 while (1)
  {
    ...
if (timer_flag){
	  		  //for (int m = 0; m < 20000; m = m + delay_us(250)){
	  			 	txIntanConvertData = ReadCommandMask | (0 << 8);
	  				//txIntanConvertData = ConvertCommandMask | (0 << 8); // Converts Channel
	  				HAL_GPIO_WritePin(INTAN_SPI2_CS_GPIO_Port, INTAN_SPI2_CS_Pin, GPIO_PIN_RESET);
	  				hal_status = HAL_SPI_TransmitReceive(&hspi2, (uint8_t*) &txIntanConvertData, (uint8_t*) &rxIntanConvertData[j], 1, 100);
	  				HAL_GPIO_WritePin(INTAN_SPI2_CS_GPIO_Port, INTAN_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  += 1;
	  			if (j == 20000){
	  				HAL_TIM_Base_Stop_IT(&htim10);
	  			    timer_flag = 0;
	  			    CountIntanTx  = 0;
	  			}
 
	  		  //}
	  		}
}
 
/* USER CODE BEGIN 4 */
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
	if (htim == &htim10){
		timer_flag = 1;
		HAL_GPIO_TogglePin(EVOKED_CH1_GPIO_Port, EVOKED_CH1_Pin);
	}
}
 
/* USER CODE END 4 */

Karl Yamashita
Lead III

Declare j outside of main or make it static. Even though the stack should save the value of j when you call HAL_SPI_TransmitReceive, the value in j may not be stay persistent when it returns from that call. There is nothing else that explains why j doesn't increment other than it isn't keeping it's value when calling another function and returning.

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.
gbm
Lead III

Put all your vector/array declarations outside of main() function - at external level. Declaring a 20k-element vector as stack (auto section) object is definitely not a good idea cause the linker is not able to detect and report memory overflow when it occurs. This may lead to overwriting a random variable.

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

> Even though the stack should save the value of j when you call

> HAL_SPI_TransmitReceive, the value in j may not be stay persistent\

> when it returns from that call.

That is complete nonsense. Unless the stack is getting corrupted as @gbm​ suggested below. But in that case, declaring it as static would then just mask the real problem.

And that is why I say to declare it global or static to see if calling the function does corrupt the variable because it is local. Unless you think software is just perfect? If so, you should rewrite the Windows OS for Microsoft.

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.
AE104
Senior

Thank you all for your response! I solved the counter increments problem. Initially, I enabled different timer which is TIM6 in interrupt mode. Then I defined all variables in global and declared j as volatile. After that instead of calling the timer_flag in while loop, I placed the SPI call in callback function. At the end, I monitored the j value increments.

Now my another problem is that the rxIntanConvertData gets 0 every time. Maybe I would create another threat.

Karl Yamashita
Lead III

You should not process or call another function from inside an interrupt. Setting a flag and processing in main while loop is best.

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.