I'm trying to print RTC date and time on Tera Term. But I'm getting errors mentioned in code. Also nothing is being printed on Tera term. I have used pointer as the declaration for Setdate and Getdate have mentioned. Also there are few warning such as 1)format '%d' expects a matching 'int' argument [-Wformat=] 2)passing argument 2 of 'HAL_RTC_GetDate' from incompatible pointer type [-Wincompatible-pointer-types] 3)passing argument 2 of 'HAL_RTC_SetDate' from incompatible pointer type [-Wincompatible-pointer-types]
#include "main.h"
#include "stdio.h"
//uint8_t Time[6]="HH:MM:SS";
//uint8_t Date[6]="DD/MM/YY";
int main(void)
{
/* USER CODE BEGIN 1 */
typedef struct
{
uint8_t Month = 0x03;
uint8_t Date = 0x24;
uint8_t Year = 0x21;
}Date_struct;
uint8_t *Date;
Date = &Date_struct; Error: Expected expression before Date_struct
HAL_RTC_SetDate(&hrtc, &Date, RTC_FORMAT_BCD);
while (1)
{
HAL_RTC_GetDate(&hrtc,&Date, RTC_FORMAT_BCD);
HAL_Delay(1000);
}
}
I frankly don't have experience with Tera Term in particular, but I've programmed Atmel MCUs before and there seem to be issues with your general C code, rather than the MCU functions. The C compiler errors can be often hard to read, but I can see you're mixing up the structure definition, declaration and initialization, as well as struggle with pointers.
Consider the following plain C code and let's go over the differences with yours.
#include <stdio.h>
#include <stdint.h>
int main(void)
{
struct date_struct
{
uint8_t month;
uint8_t date;
uint8_t year;
}; // Define a structure named date_struct
typedef struct date_struct date_struct_type; // make 'struct date_struct' into a new type
date_struct_type date; // Declare a variable of the new type
date.month = 0x03; // Initialize the fields of the variable
date.date = 0x24;
date.year = 0x21;
date_struct_type * date_ptr; // Create a new pointer to the struct
date_ptr = &date; // Assign the address of the variable to the pointer
// Use the pointer to adress the structure's values
printf("Month: %d\nDate: %d\nYear: %d\n", date_ptr->month, date_ptr->date, date_ptr->year);
// ... or pass the pointer into any hypothetical function
// func(date_ptr);
// ... or pass a reference to the structure, but never a reference to the pointer
// unless you know that you need it!
// func(&date);
return 0;
}
In your code, you first define an anonymous local structure and immediately typedef
it to create a new type. That means, from that point on, you work with the structure as if it was just a variable type.
In my code, I split up the structure definition and the typedef
into two individual statements. That code is identical to writing
typedef struct date_struct
{
uint8_t Month;
uint8_t Date;
uint8_t Year;
} date_struct_type; // Define and typedef a structure at the same time
... or we can even leave the structure's name out and leave it anonymous - like you did in your code - we don't need it named at all since we already have a new type made out of it that we can use.
typedef struct // <-- leave out the name
{
uint8_t Month;
uint8_t Date;
uint8_t Year;
} date_struct_type; // Define and typedef a structure at the same time
However, a structure definition is a "template" that tells the compiler how to allocate and access the structure in memory. The definition itself doesn't store any values and as such, we can't assign to it. We first need to declare a variable of that type*.
date_struct_type date;
* C is a very wild language, and you can do and use all sorts of shorthands, such as this. However, I strongly recommend against doing this when you're just starting out (and also in the future), as it's really not needed and is harder to read, maintain and debug.
With the variable in place, we can finally assign our values to the individual elements of the structure. When accessing members of a structure we use the member reference operator - .
.
date.month = 0x03;
date.date = 0x24;
date.year = 0x21;
Now we're moving to pointers and the two magical operators - *
and &
in C, that often cause a lot of headaches.
In your code, you've successfully declared a pointer with this: uint8_t *Date;
. Here, the *
is not an operator, it signifies the variable holds a pointer - in other words, the uint8_t *Date;
says "There is a variable named Date
and it will hold an address of a uint8_t
variable somewhere in the memory".
However, that is not what we intend - we want to point to our new structure, not the uint8_t
. Pointers all have the same size (in your case 32 bits on the smt32
platform), so it works, but that's what's setting off the "incompatible pointer type" warnings of your compiler.
Instead, we should declare a pointer of the same type as the variable we intend to "point at" using this pointer. We'll once again split up the declaration and assignment statements for clarity - we're doing two things, writing them as one statement is just a shorthand.
date_struct_type * date_ptr;
The assignment is where the &
operator comes into play. The &
operator takes any variable and returns an address to it - which is exactly the thing we want to store inside our pointer.
date_ptr = &date;
Now whenever we want to pass a pointer to our new structure, either we use the one we just created - date_ptr
, or directly pass a reference to the structure - &date
. Both are viable, but be sure to not mistakenly write this: &date_prt
. This gives you a pointer to a pointer, which is not something you usually want.
A few more things. When accessing member of a structure through a pointer to that structure, we have to use a structure dereference operator - ->
. That's why the printf
statement contains ->
operators instead of just .
.
I'm sure with this you can tweak your code to have it work. There shouldn't be any more issues in your function calls and the infinite while
loop, just pay attention which pointers are you passing into the HAL_RTC_SetDate
and HAL_RTC_GetDate
functions. Do ask in the comments if there's still anything unclear or not working!