Skip to main content
Associate III
November 12, 2024
Solved

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

  • November 12, 2024
  • 70 replies
  • 9440 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

 

 

 

 

70 replies

Karl Yamashita
Principal
November 18, 2024

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

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
XooMAuthor
Associate III
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.

 

Karl Yamashita
Principal
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

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
XooMAuthor
Associate III
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.