cancel
Showing results for 
Search instead for 
Did you mean: 

I need help with trying to figure out how to set my time using a push button and the RTC peripheral on the STM32G031K8 board. I can't seem to figure out how to get it to increment instead it just keeps getting reset to 00:00:00.

JWire.1
Associate III

What do I need to do to be able to be able to set the time through the use of a push button.

Is there a way to set the hours and min separately or does the RTC need to be set all at once?

Here is my call back function where I am trying to set just the hours for the time being.

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
 
	RTC_TimeTypeDef sTime;
	if (GPIO_Pin == B1_Pin ) {
		HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
		 sTime.Hours++;
	}
 
	if (GPIO_Pin == B2_Pin) {
		  HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
	}
 
 
 
}

Thanks

Jacamo

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

You need to initialize your structure. You're calling HAL_RTC_SetTime with uninitialized data. Perhaps you meant to call HAL_RTC_GetTime first. However, incrementing the hours like this won't work if it rolls over to a new day.

You can increment or decrement by 1 hour using the SUB1H/DEC1H bits in the RTC_CR register. Unsure if that's available in HAL or not.

Conceptually, it doesn't make a lot of sense to only set the hours while leaving minutes, days, etc the same.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
TDK
Guru

You need to initialize your structure. You're calling HAL_RTC_SetTime with uninitialized data. Perhaps you meant to call HAL_RTC_GetTime first. However, incrementing the hours like this won't work if it rolls over to a new day.

You can increment or decrement by 1 hour using the SUB1H/DEC1H bits in the RTC_CR register. Unsure if that's available in HAL or not.

Conceptually, it doesn't make a lot of sense to only set the hours while leaving minutes, days, etc the same.

If you feel a post has answered your question, please click "Accept as Solution".
JWire.1
Associate III

Thank you for your reply, correct me if I am wrong but what your saying is I could first call HAL_RTC_Gettime and then incrementing it with the HAL_RTC_Settime?

Or it looks like I will have to dig deeper in to the users guide and all the other documentation on the RTC to see if I can get this to work using the RTC_CR register you had mentioned.

That being said:

I know conceptually it doesn't make sense but I am very new to programming and the embedded world. Everything I have ever written in C (which is my first programming language) so far has been just to learn more. So to learn I have been seeing if I can implement any random ideas I have with the hardware I have on hand. Eventually I was also planning on trying to be able to have 4 push buttons that would be able to set the time. Two for moving left and right to select between mins/hours/date and the other two for incrementing and de-incrementing the value of what is selected at the time. I was just trying to start with the easiest thing I could think of which was seeing if I could get the hours to increment by them selves first and that's how I ended up here.

If you have any tips on what I should focus on not having much experience I would be more than happy to hear them but I understand if that is out of the scope of this thread.

Thank you

Jacamo

TDK
Guru

Using HAL_RTC_GetTime/HAL_RTC_SetTime to modify portions of the time seems like it will work fine. If this is meant for an application where the user is setting the correct time with buttons, I would store the date/time in memory during the operation and set all values at the same time at the end. Otherwise things can roll over and cause issues.

The way I recommend learning is by having ideas and creating projects, which is what you're doing. Setting the RTC seems like a good first project. Start simple and develop over time. Blink some LEDs, send out data over UART, etc, then move on to other things.

If you feel a post has answered your question, please click "Accept as Solution".
JWire.1
Associate III

I appreciate the recommendations. I have already done all of the things you had mentioned and I can follow a tutorial on YouTube and get things to work even if its not the same board/peripherals they are using and I can modify the code to adapt things but when It comes to starting from scratch I get overwhelmed pretty fast. I know I just need to break things down but it seems like every time I try to get something simple done I end up 3 hours later down some rabbit hole because I am trying to understand what is going on.

I will go ahead and see if I can get it to work. My end goal in all of this is to make a nixie tube clock. I am planning on having a battery back up so if it ever lost power it should keep the time. I was wondering if to just make it super simple I could just set the time once in software and then not really have to worry about it again. Or when I get a bit more experience just add in a feature where it could check itself for accuracy via bluetooth or something like that.

Thanks again

Jacamo

JWire.1
Associate III

I was able to get the time to update using both methods you mentioned and thought I would post my results incase someone else is looking for this.

The ADD1HR is available with HAL but from what I have read it was made for incrementing or decrementing the hour for daylight savings not really meant for setting the time per say. This leads to it lacking any feature in HAL to increment the mins so I went ahead and used the HAL_RTC_GetTime/HAL_RTC_SetTime

to increment the mins and I didn't seem to have any issues with doing it that way.

I am still a bit confused as to how I would store the values in to memory as you had mentioned. Would I just assign the users input to the typedef struct associated with the Time? In this case RTC_TimeTypeDef stimeset; And once I get all the values Hour/Min then I call the HAL_RTC_SetTime?

I should also note that I am denouncing the switches with some caps and resistors as for me that was easier than doing it in software as I have been building and fixing electronics for years now but have just only started with programming.

Thanks again for your help TKD! And any criticism is welcomed.

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) {
 
	if (GPIO_Pin == B1_Pin) {
 
		HAL_RTC_DST_Add1Hour(&hrtc);
 
	}
 
	if (GPIO_Pin == B2_Pin) {
 
		RTC_DateTypeDef sdateset;
		RTC_TimeTypeDef stimeset;
 
		/* Get the RTC current Time */
		if (HAL_RTC_GetTime(&hrtc, &stimeset, RTC_FORMAT_BIN) != HAL_OK) {
			/* HAL Error */
			Error_Handler();
		}
 
		/* Get the RTC current Date */
		if (HAL_RTC_GetDate(&hrtc, &sdateset, RTC_FORMAT_BIN) != HAL_OK) {
			/* HAL Error */
			Error_Handler();
		}
 
		stimeset.Minutes++;
 
		HAL_RTC_SetTime(&hrtc, &stimeset, RTC_FORMAT_BIN);
	}
 
}

> Would I just assign the users input to the typedef struct associated with the Time? In this case RTC_TimeTypeDef stimeset; And once I get all the values Hour/Min then I call the HAL_RTC_SetTime?

Yes, that is what I mean.

> stimeset.Minutes++;

Think about what happens if minutes were 59 before, and now you increase them to 60. The code will fail here as 60 isn't a valid value for minutes.

https://github.com/STMicroelectronics/STM32CubeG0/blob/c6c0046d9278a7107261c6bf38327345df4c3efd/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rtc.c#L775

You could either set them to 0 instead, or you could set it to zero and increment the hour by one. But then you need to do the same for hours, days, months, years, which is a nontrivial problem given the complexity of our calendar.

If you feel a post has answered your question, please click "Accept as Solution".