Rookie91
Rookie91

Reputation: 267

better usage of structures in embedded field

I'm bit new to c programming and i want to learn and use the structure facility in C programming. I'm working in the embedded programming field of 8bit controllers.

I have a situation in which

objective:

  1. To set time and date or more things.
  2. To get time and date or more things.

Problem: I have two source files main.c and set_get.c i have a struct varaible in main.

Aim : to set and get rtcc values from registers in pic18 series controllers and to create a test platform.

main()
{
    struct data
   {
     unsigned char hour=10;
     unsigned char date=20;
   } entry;


  entry=set_time_date(entry);

  entry=get_time_date();

 while(1);

}



and  in  set_get.c

i have two functions
//here struct parameter will be the input from main.c

    struct data
   {
     unsigned char hour=10;
     unsigned char date=20;
   }; 


  struct set_time_date(struct x)
 {
    struct data p1;

    p1.hour=x.hour;
    p1.date=x.date;
    //do set hour register with p.hour value
    //do set date register with p.date value       

   return(p1);
 }





   struct get_time_date(void)
     {
        struct data p1;

        p1.hour= do read from hour register;
        p1.date= do read from day register;    

       return(p1);
     }

I would like to have your inputs on this and correct me if i have made any mistakes in the following pattern.I have done in this method so as to reduce global structs.

And im keenly waiting your review on this piece of code.Correct me if im wrong

Regards

Arookie

Upvotes: 0

Views: 138

Answers (1)

ryyker
ryyker

Reputation: 23218

Note, there is a rich library of time functions included in C89, C99, etc.

time_t time (time_t *Current_Calendar_Time);  
clock_t clock (void);
char *ctime (const time_t *Calendar_Time);  

Just to name a few. But in keeping with the theme of what you have already done...

First, This code segment will not compile. Assignments cannot be made inside the struct definition:

   struct data
   {
     unsigned char hour=10;
     unsigned char date=20;
   };   

However, once the struct is defined, you can make assignments to each individual member (see examples in code example below) Or you can make a block assignment, like this:

//Note, I am using a typedef variation of your original for illustration:
typedef struct data{
   unsigned char hour;   
   unsigned char date;
} data;
//make block assignment here:
//               hour  date
struct data a = {0x34, 0xA5};

Next, passing a pointer to struct is sometimes better than passing the struct itself. i.e. when volume of data is large, passing address (~4bytes) is preferable to passing possibly hundreds of bytes. (For the size of your struct, it is really not a concern) My examples will use pointers:

For readability, create a type:

//you originally used unsigned char for member types.  I changed it to 
//accommodate puctuation,as often, timestrings and datestrings use 
//puncutation such as : or /
//The unsigned version is below this one...

#define TIME_LEN 20
#define DATE_LEN 20
     typedef struct    {
          char hour[TIME_LEN];
          char date[DATE_LEN];
    } DATA;

//use DATA to create the other instances you need:

DATA entry, *pEntry;  

//Your function prototypes become:  

void     set_time_date(DATA *x);  //no need to return time in set function
DATA * get_time_date(void);


//In main, initialize pointer to struct this way:  

    int main(void)
    {
        pEntry = &entry;//initialize pointer pEntry to address of entry

        sprintf(pEntry->date , "%s", "12/23/2014");
        sprintf(pEntry->hour , "%s", "10:12:13");
        set_time_date(pEntry); 
        pEntry = get_time_date();

        return 0;
    }

void set_time_date(DATA *x)
{

    sprintf(pEntry->date, "%s", x->date);   
    sprintf(pEntry->hour, "%s", x->hour);   
}


DATA * get_time_date(void)
{
    sprintf(pEntry->date, "%s", "01/23/2014");  
    sprintf(pEntry->hour, "%s", "10:10:00");
    return pEntry;
}

using unsigned char

In this section, changes have been made to accommodate minimization of global struct. By creating a typedef of the struct, say in a header file, you can then simply use DATA * where needed to create a local instance of the struct, and pass it as an argument...

//Your function prototypes become:  

void     set_time_date(DATA *x);  //no need to return time in set function
DATA * get_time_date(DATA *x); //Edited to include argument


//In main, initialize pointer to struct this way:  

int main(void)
{
    //Create local instance of DATA:
    DATA entry={0}, *pEntry;  
    pEntry = &entry;//initialize pointer pEntry to address of entry

    pEntry->date = 0x12;
    pEntry->hour = 0x23;

    set_time_date(pEntry);
    pEntry = get_time_date(pEntry);

    //print results showing values of both pEntry and entry
    printf("pEntry->date: 0x%x\n", pEntry->date);
    printf("entry.date:   0x%x\n", entry.date);
    printf("pEntry->hour: 0x%x\n", pEntry->hour);
    printf("entry.hour:   0x%x\n", entry.hour);

    //After the assignment: "pEntry = &entry;" (above)
    //pEntry is pointing to the the same location 
    //in memory as the start of entry. (this is the reason for that assignment)
    //Every subsequent assignment you make to pEntry, is also being
    //written to entry, without explicitly having to 
    //write:  entry.date = 0x23 etc. (indeed, it is the same location
    //in memory you are writing to)

    return 0;
}


void set_time_date(DATA *x)
{
    x->date = 0xBC; 
    x->hour = 0x45; 
}


DATA * get_time_date(DATA *pX)
{
    //Commented following two lines, passed in as argument:
    //DATA x, *pX;  //now passed in as argument
    //pX = &x;//initialize pointer pX to address of x

    pX->date = 0x23;    
    pX->hour = 0x34;
    return pX;
}  

Produces following output
enter image description here

Upvotes: 1

Related Questions