Skip to main content
Graduate II
November 12, 2024
Solved

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

  • November 12, 2024
  • 12 replies
  • 9193 views

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);
	}

}

 

 

 

 

 

    This topic has been closed for replies.
    Best answer by Karl Yamashita

    Let's assume you're only looking a 3 inputs and controlling 2 outputs. 

    Create a data structure to represent the look-up table

    typedef union
    {
    	struct
    	{
    		uint8_t data[2]; // byte 0 is current state, byte 1 is last state
    	}Byte;
    	struct
    	{
    		uint8_t pa1:1;
    		uint8_t pa2:1;
    		uint8_t pc13:1;
    		uint8_t :5;
    	}Status;
    }InputStatus_t;

     

    Using EXTI for the input pins, we can use the HAL GPIO callbacks to set the input pin states. I've tested on a Nucleo-G071RB which uses a Rising and Falling callback where some STM's use 1 callback, but concept is the same.  

    /*
     * Description: Update pin status for specific input.
     * Input: pin data structure, pin to update, the pin state
     */
    void GPIO_UpdatePinStatus(InputStatus_t *input, uint8_t pin, GPIO_PinState pinStatus)
    {
    	switch(pin)
    	{
    	case 0:
    		input->Status.pa1 = pinStatus;
    		break;
    	case 1:
    		input->Status.pa2 = pinStatus;
    		break;
    	case 2:
    		input->Status.pc13 = pinStatus;
    		break;
    	default:
    		// invalid pin
    		break;
    	}
    }
    
    /*
     * Description: Functions as a HAL GPIO callback.
     * Note: no sw debounce incorporated.
     * See YouTube video to learn how to debounce push buttons that use EXTI
     * https://www.youtube.com/watch?v=o0qhmXR5LD0
     */
    void GPIO_Callback(uint16_t GPIO_Pin)
    {
    	if(GPIO_Pin == PA1_Pin)
    	{
    		GPIO_UpdatePinStatus(&inputs, 0, HAL_GPIO_ReadPin(PA1_GPIO_Port, PA1_Pin));
    	}
    	else if(GPIO_Pin == PA2_Pin)
    	{
    		GPIO_UpdatePinStatus(&inputs, 1, HAL_GPIO_ReadPin(PA2_GPIO_Port, PA2_Pin));
    	}
    	else if(GPIO_Pin == PC13_Pin)
    	{
    		GPIO_UpdatePinStatus(&inputs, 2, HAL_GPIO_ReadPin(PC13_GPIO_Port, PC13_Pin));
    	}
    }
    
    /*
     * STM32G071 HAL driver uses Rising and Falling callbacks where other STM32's use 1 callback.
     */
    void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
    {
    	GPIO_Callback(GPIO_Pin);
    }
    
    void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
    {
    	GPIO_Callback(GPIO_Pin);
    }

     

    By using a data structure to represent the look-up table, we can use switch-case to determine what state the input pins are. By checking for current pin state versus the last pin state, you can avoid having case 0 being called again. For case 0, PB12 is low, and PA10 is high. A timer callback is started and after 500ms, it turns Off PA10.

    void GPIO_Check(InputStatus_t *input)
    {
    	if(input->Byte.data[1] != input->Byte.data[0]) // check for change, else do nothing.
    	{
    		input->Byte.data[1] = input->Byte.data[0]; // copy current state to last state
    
    		switch(input->Byte.data[0]) // index of truth table
    		{
    		case 0:
    			PB12_Off(); // pin is low
    			PA10_On(); // pin is high
    			TimerCallbackTimerStart(&timerCallback, PA10_Off, 500, TIMER_NO_REPEAT); // start timer to turn off PA10
    			break;
    		case 1: // all other case, PA12 is On (high state)
    		case 2:
    		case 3:
    		case 4:
    		case 5:
    		case 6:
    		case 7:
    		default:
    			PB12_On(); // pin is high
    			break;
    		}
    	}
    }

     

    And the code for the GPIO outputs

    void PA10_On(void)
    {
    	HAL_GPIO_WritePin(PA10_GPIO_Port, PA10_Pin, GPIO_PIN_SET);
    }
    
    void PA10_Off(void)
    {
    	HAL_GPIO_WritePin(PA10_GPIO_Port, PA10_Pin, GPIO_PIN_RESET);
    }
    
    void PB12_On(void)
    {
    	HAL_GPIO_WritePin(PB12_GPIO_Port, PB12_Pin, GPIO_PIN_SET);
    }
    
    void PB12_Off(void)
    {
    	HAL_GPIO_WritePin(PB12_GPIO_Port, PB12_Pin, GPIO_PIN_RESET);
    }

     

    The working code is on Github https://github.com/karlyamashita/Nucleo-G071RB_GPIO_Delay500/wiki

     

     

     

     

    12 replies

    Graduate II
    November 18, 2024

    I've attached a project that uses your STM32F030C6 that compiles with no errors.

    XooMAuthor
    Graduate II
    November 18, 2024

     

    XooM_0-1731920812674.png

    PA10_off does not work after 1sec. PA10 "1" is always
    It should be "0" after 1sec but timercallback does not work.

     

    Graduate II
    November 18, 2024

    @XooM wrote:

     

    XooM_0-1731920812674.png

    PA10_off does not work after 1sec. PA10 "1" is always
    It should be "0" after 1sec but timercallback does not work.

     


    It's because you keep calling it in a while loop. Each time you call it, it resets the callback timer.

    Look at my signature and watch the video

    XooMAuthor
    Graduate II
    November 18, 2024

    XooM_0-1731922612410.png

    If the PA10_off function was used after 1 second, it would be something to look for..

    My aim was to make a PAx? that was active anywhere in my project passive after a period of 100 200 500ms... but it doesn't work.