cancel
Showing results for 
Search instead for 
Did you mean: 

Delay, multi milliseconds, on the STM32F0, again..

XooM
Associate III

where I wrote it among the codes.. // Here I have to wait 500ms.
Can you help me to prevent the timers from being affected by this wait?
Can you give me the codes that I will add. Because I am very confused..

I tried many things but they all stopped the interrupts..

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

	if(htim->Instance==TIM1)
	{
		
	if(input1==0) 
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_SET);
		// Here I have to wait 500ms.
		HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_RESET);
	}

}

 

 

 

 

 

70 REPLIES 70

@XooM wrote:

Short code outputs like the ones you gave me now speed up my understanding. Thank you very much.


@XooM I've accepted the solution provided by @Tesla DeLorean according to your comment.

 

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.

It didn't work..I have an idea why it didn't work but I'm not sure. Timer1 is set to 250us.. Could it be because of that?

No, time is here irelevant problem is here

   if(input1==0)
    {
      HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, GPIO_PIN_SET); // Turn ON PA1
      Tick_PA1_On = HAL_GetTick();

and still as i write how and where you set/get input1. 

Simply if always is 0 , 500ms is always delayed and GPIOA1 is always set ... every 250us or any time

XooM
Associate III

Even if input1 is always "0", it does not turn on/off at 500 ms intervals.

There is no other code in the real circuit, I just run this block.

??? WTF is input1

Your code now set pin high when input1 is 0 and reset pin 500ms after input1 go to non zero and stay for 500ms.

250 us / 4 KHz the MCU should be able to handle interrupting at this rate. Several hundred KHz into MHz, NO, you can't interrupt at those rates and have the processor do anything else.

I do think you're going to need to up your debugging/diagnostic game. Perhaps output flow and dynamic information via a serial port so you can visualize what's happening in real-time.

Does the LED light at all? How does input1 get set?

I just tried to mimic the syntax of your code, so I have no idea how the rest of it works or interacts. Tried to illustrate how you'd move from the blocking delay mindset, to the deferred action mindset.

If you've got a lot of this stuff going on you'd build an array or table to manage it, so you don't end up with 100's of individual global variables.

Do you work with someone more experience who can give you more direction, or look at how the last person implemented the board firmware?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
volatile uint32_t Tick_PA2_On;  // Time it was turned ON
volatile int PA2_On = 0; // Flag that is is ON
uint8_t input1 =1;
uint8_t input2 =1;
uint8_t m =0;
uint16_t currentVal=0;
uint16_t led1=0;



/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim16;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM16_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#define SER_PIN GPIO_PIN_4 //  SER_PIN
#define SER_PORT GPIOB

#define SRCLK_PIN GPIO_PIN_12 // SRCLK_PIN
#define SRCLK_PORT GPIOA

#define RCLK_PIN GPIO_PIN_5 // RCLK_PIN
#define RCLK_PORT GPIOB



void HC4094write()
{
	 HAL_GPIO_WritePin(RCLK_PORT, RCLK_PIN, GPIO_PIN_RESET);

    for(int i=0; i<16; i++)
    {
        if(currentVal & (1<<i))
        {
            HAL_GPIO_WritePin(SER_PORT, SER_PIN, GPIO_PIN_SET);
        }
        else
        {
            HAL_GPIO_WritePin(SER_PORT, SER_PIN, GPIO_PIN_RESET);
        }
        HAL_GPIO_WritePin(SRCLK_PORT, SRCLK_PIN, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(SRCLK_PORT, SRCLK_PIN, GPIO_PIN_SET);
    }
    //HAL_GPIO_WritePin(RCLK_PORT, RCLK_PIN, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(RCLK_PORT, RCLK_PIN, GPIO_PIN_SET);
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM16_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim1);
  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_Base_Start_IT(&htim16);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

	  if (PA2_On)
	   {
	     if ((HAL_GetTick() - Tick_PA2_On) >= 500) // On for 500ms, turn it off now
	     {
	    	 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
	       PA2_On = 0;
	     }
	   }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief TIM1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 1199;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 5;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */

}

/**
  * @brief TIM2 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 11999;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

/**
  * @brief TIM16 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_TIM16_Init(void)
{

  /* USER CODE BEGIN TIM16_Init 0 */

  /* USER CODE END TIM16_Init 0 */

  /* USER CODE BEGIN TIM16_Init 1 */

  /* USER CODE END TIM16_Init 1 */
  htim16.Instance = TIM16;
  htim16.Init.Prescaler = 11999;
  htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim16.Init.Period = 1;
  htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim16.Init.RepetitionCounter = 0;
  htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim16) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM16_Init 2 */

  /* USER CODE END TIM16_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @PAram None
  * @retval None
  */
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_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, Q1_Pin|Q2_Pin|Q3_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(Q5_GPIO_Port, Q5_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : input2_Pin */
  GPIO_InitStruct.Pin = input2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(input2_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : input1_Pin */
  GPIO_InitStruct.Pin = input1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(input1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : Q1_Pin Q2_Pin Q3_Pin */
  GPIO_InitStruct.Pin = Q1_Pin|Q2_Pin|Q3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : Q5_Pin */
  GPIO_InitStruct.Pin = Q5_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(Q5_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	//I turn on/off 24 LEDs according to the inputs.
	if(htim->Instance==TIM1) // Timer2 Update Event'i 250us
	  {

	    if(input2==0) //Acil Stop
	    {
	    	led1=0b0000100000100000;
	    	currentVal=led1;
	    	HC4094write();
	    	m=0;

	    }

	    else
	    {
	    	m++;
	        if(m==1)
	        {
	        	led1=0b0000000000000000;
	        	currentVal=led1;
	        	HC4094write();
	        	m=2;
	        }


	    }



	  }

//I manage the outputs according to the incoming inputs.
  if(htim->Instance==TIM16) // Timer16 Update Event'i 1 ms
  {
		if(input2==0)
		  {
			  if(input1==0)
					 {

						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_RESET);
						HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
						Tick_PA2_On = HAL_GetTick();
						PA2_On = 1;

				   	}
				else
					  {

						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_SET);
					  }

		  }
		  else
		  {
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_RESET);
		  }





  }


  // I use it to assign inputs and outputs to variables.
  if(htim->Instance==TIM2) // Timer2 Update Event'i 1 ms
  		{
	  	  input1 =HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2);
	  	  input2 =HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13);
  		}







}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @PAram  file: pointer to the source file name
  * @PAram  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

I wrote a short code to try the information I learned from you.

Result: As long as input1 continues to come, no interrupt occurs at 500ms intervals.
PINA10 goes to SET Position and stays there.

Change code to 

	  if(input1==0 && PA2_On==0)
			 {
				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_RESET);
				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
				Tick_PA2_On = HAL_GetTick();
				PA2_On = 1;
		   	}
		else
			  {
				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,GPIO_PIN_SET);
			  }

and place break point on line 10. Debug your code... 

And ask self how long is input1 == 1 ???

You put the turn-off code in somewhere that gets executed and is not blocked.

So in the SysTick_Handler(), if you're not blocking the interrupts, or in your main() loop if it gets back there.

You're trying not to jam up the MCU in delay loops. You're trying to give the MCU a time-line, and placing activity along that.

You NEED to LEAVE the IRQHandlers, and related callback functions.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..