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

Which site can I upload it? Stm32CubeIDE project file..

XooM
Associate III

I tried to upload it here. I hope you can see it. 
The file is attached. How do I fix the errors?


@XooM wrote:

I am a bit of a novice, I want to say that from the beginning.
I like your pin change control mechanism here.
As you can see in the table I gave you, there are 14 inputs and 8 outputs.
Can I add what I want to do to my outputs according to other situations that will come from the inputs to the structure you built?
I am asking to learn. Because it seems like this control structure will make my job easier.
Example:

When PA4 , PA2 , PA0 , PC13 are "0" PB13 will be "1".
When PA3 is "0";

PB13 becomes "0" and then
PB14 becomes "1" and then 500ms later becomes "0".


Should I completely break your code structure to add this addition?


I was basing everything on your previous post where you only had 3 inputs and 2 outputs.

 

Unfortunately GPIO interrupt won't work for ALL your current inputs from your truth table. Port pins can not share the same EXTI pin. So PA6 and PB6 uses pin position 6 so that won't work. Same goes for PB0 and PA0, PB1 and PA1.

 

If you can replace PB0, PB1 and PB6 with Px8,Px10 and Px11 then you can use GPIO interrupts. Otherwise, you'll have to poll for the pin status.

 

That is why i needed you to tell me which inputs were being used to control what outputs? So you need to fill out the truth table fully so a solution can be determined.

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.

@XooM wrote:

I tried to upload it here. I hope you can see it. 
The file is attached. How do I fix the errors?


Look at my main.h file. It has an extern for the timercallback and some includes

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.

I actually shared the table before sharing your code..
By the way, you helped me a lot no matter what.
I learned a lot.
The circuit is a ready-made PCB, so I can't change the pins.
In this case, I can't use your codes, right?

Yes you shared the table of 14 inputs. That comes out to over 16,000+ combinations. That's why you need to show only the inputs you're concerned with and the outputs it controls. Maybe some inputs are simple and don't need to be part of the data structure?

You can still use the code as is. The only thing you need to do is..

  • Change pb0, pb1 and pb6 as inputs only. Don't use EXTI for these pins.
  • You need a polling routine to read pb0, pb1 and pb6.
  • The other inputs can still use interrupts.

So if you want to use all 14 inputs, you'll have a data structure like this

typedef union
{
	struct
	{
		uint16_t data[2]; // byte 0 is current state, byte 1 is last state
	}Byte;
	struct
	{
		uint8_t pb6:1;
		uint8_t pc13:1;
		uint8_t pc14:1;
		uint8_t pc15:1;
		uint8_t pa0:1;
		uint8_t pa1:1;
		uint8_t pa2:1;
		uint8_t pa3:1;
		uint8_t pa4:1;
		uint8_t pa5:1;
		uint8_t pa6:1;
		uint8_t pa7:1;
		uint8_t pb0:1;
		uint8_t pb1:1;
		uint8_t :2;
	}Status;
}InputStatus_t;

 

In the PollingInit you add a timer callback for 1ms to poll for those 3 GPIO's

void PollingInit(void)
{
	HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_UCPD1_STROBE);

	PB12_On(); // init to 1
	PA10_Off(); // init to 0

	TimerCallbackRegisterOnly(&timerCallback, PA10_Off);

	TimerCallbackRegisterOnly(&timerCallback, InputPoll);
	TimerCallbackTimerStart(&timerCallback, InputPoll, 1, TIMER_REPEAT);
}

 

You just need to add a couple of functions and also a global variable inputReadDone

bool inputReadDone = false;

void InputPoll(void)
{
	InputRead(&inputs);
}

void InputRead(InputStatus_t *input)
{
	input->Status.pb0 = HAL_GPIO_ReadPin(PB0_GPIO_Port, PB0_Pin);
	input->Status.pb1 = HAL_GPIO_ReadPin(PB1_GPIO_Port, PB1_Pin);
	input->Status.pb6 = HAL_GPIO_ReadPin(PB6_GPIO_Port, PB6_Pin);
	inputReadDone = true;
}

 

So when you call GPIO_Check function, it checks inputReadDone to be sure you've polled for the 3 GPIO's first before comparing input->Byte.data

void GPIO_Check(InputStatus_t *input)
{
	if(inputReadDone)
	{
		inputReadDone = false;

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

Now that you're polling for the inputs, there can be a chance for an input to change state before you call GPIO_Check.  

 

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.

Ok you write "Please, I don't want your help." And i reply I want you stop try programming...

Learn from Karl is next disaster ... create union for duplicate HAL_Read states is absurd, use void func for set pin state is next, maybe Karl get money based on lines of code. 

MCU is designed control outputs based on inputs, then try write your code this way

unint32_t out_Start[8];  //delay storage

//first output handler
bool out1 = false;
out1 = ( all condition logic for set out high );
if(((GPIOA->ODR&GPIO_Pin_1)==0 && out1) || ((GPIOA->ODR&GPIO_Pin_1)!=0 && !out1) ) {
    HAL_GPIO_WritePin(GPIOA, GPIO_Pin_1, out1);
    if(out1) out_Start[0] = HAL_GetTick();
}
...
bool inputReadDone = false;

void InputPoll(void)
{
	InputRead(&inputs);
}

void InputRead(InputStatus_t *input)
{
	input->Status.pb0 = HAL_GPIO_ReadPin(PB0_GPIO_Port, PB0_Pin);
	input->Status.pb1 = HAL_GPIO_ReadPin(PB1_GPIO_Port, PB1_Pin);
	input->Status.pb6 = HAL_GPIO_ReadPin(PB6_GPIO_Port, PB6_Pin);
	inputReadDone = true;
}

where do I add this?
I want to try it today.
I took the PCB that I will program with me. I want to add your answer and check if it works.

Add it to the PollingRoutine.c file.

Don't forget to add the prototypes to the PollingRoutine.h

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.

I couldn't do it..
If I add the files TimerCallback.c TimerCallback.h to the Src and Inc folders.
TimerCallbackTimerStart(&timerCallback, PA10_Off, 500, TIMER_NO_REPEAT);
can I use this line in any project I want? can I wait 500ms wherever I want and call the function I specify?

Is there anything I need to do about the timer settings? Do I need to set the timer it will use? I couldn't understand exactly how it works.