|
|
View previous topic :: View next topic |
Author |
Message |
dezso
Joined: 04 Mar 2010 Posts: 102
|
Setting time and date for RTC |
Posted: Sun Mar 07, 2010 8:59 pm |
|
|
Please look at the posted code.
I'm not a experienced programmer, specially not a "C" guru.
There is a few function added to GLCD, like I can set my layer from 1-3, now the text57 erase the character location before write a new one, and some more....
This segment for changing the time only, planning to create the same structure to change the date.
Is there a better/easier way to set the time and date ?
Code: | /////////////////////////////////////////////////////////////////////////
void sub_menu_set_datetime()
{
glcd_fillScreen(0, 1); //clear the layer 1
glcd_text57(20,5,Menu_datetime,2,on,1); //dispaly the sub menu title
glcd_line(0,1,223,1,1,1); // DRAW some fancy lines
glcd_line(0,3,223,3,1,1); // =
glcd_line(0,21,223,21,1,1); // =
glcd_line(0,23,223,23,1,1); // ends here.
glcd_layer(on,2); // this layer has the time and date
glcd_text57(1,30 , set_hrtxt, 1, 1, 1); // display aprompt to change the hrs
sprintf(CTime, "\%02u", hrs); // convert it to string
glcd_text57(5,60 , CTime, 1, 0, 2);
do{
keys = scan_keys(); // get the key values 1-enter,2-cance,3-down,4-up
if (keys == 3 && hrs >1) // if down and hrs more than 1
--hrs; // go down one to min "00" = 24 hr
else if (keys == 3) // if less than "00"
hrs = 23; // got to max "23"
if (keys == 4 && hrs < 23) // same idea for up
++ hrs; //
else if (keys == 4) //
hrs = 0; // we hit 23 than go to 24 aka "00"
if ( hrs != oldhrs) //
{ // if no change made in the time
oldhrs = hrs; // set the time state for the new hr
sprintf(CTime, "\%02u", hrs); // convert it to string
glcd_text57(5,60 , CTime, 1, 0, 2); // display it on glcd
}
} while (keys != 1); // if enter pressed
sprintf(CTime, "\%02u", hrs); // convert it to string
glcd_text57(5,60 , CTime, 1, 1, 2); // display it on glcd
glcd_text57(1,30 , set_mintxt, 1, 1, 1); // yes= change the prompt to change the minutes
//////////////////////////////////////////////////
sprintf(CTime, "\%02u", min); // convert it to string
glcd_text57(23,60 , CTime, 1, 0, 2); // display it on glcd
do{ //
keys = scan_keys(); // get the key values 1-enter,2-cance,3-down,4-up
if (keys == 3 && min > 0) // if down and minutes more than 1
--min; // go down one to min "00" = 60 min
else if (keys == 3) // if less than "00"
min = 59; // got to max "59"
if (keys == 4 && min < 59) // same idea for up
++ min; //
else if (keys == 4) //
min = 0; // we hit 59 than go to 60 aka "00"
if (min != oldmin)
{ // if no change made in the time
oldmin = min; // set the time state for the new minute
sprintf(CTime, "\%02u", min); // convert it to string
glcd_text57(23,60 , CTime, 1, 0, 2); // display it on glcd
}
} while (keys !=1); // if enter pressed
sec = 0; // change the second to "00"
sprintf(CTime, "\%02u", min); // convert it to string
glcd_text57(23,60 , CTime, 1, 1, 2); // display it on glcd
ds1307_set_date_time(day,month,yr,dow,hrs,min,sec);// than send the new time to RTC
menuselected = 0; // set the menu back to 0, go back to main menu
}
/////////////////////////////////////////////////////////////////////
|
Last edited by dezso on Fri Mar 12, 2010 9:27 am; edited 3 times in total |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Wed Mar 10, 2010 9:38 pm |
|
|
Any input on this subject ?
Also want to create 12 independent alarm/timer to turn on/off devices. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 10, 2010 10:18 pm |
|
|
The reason you didn't get any input is likely because of the formatting
of your post. The indentation is random. The forum software doesn't
work very well with tabs. Can you edit your post and fix the indentation ?
Use the Preview button repeatedly until it looks good. Also pull the
comments in closer to the code (but still, align them). Then I think
you will get some responses. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Thu Mar 11, 2010 8:45 am |
|
|
I only have MPLAB, on my screen looks perfect.
Noted!! |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Thu Mar 11, 2010 11:01 pm |
|
|
deleted
Last edited by dezso on Sat Mar 13, 2010 7:34 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 11, 2010 11:20 pm |
|
|
You're using a tab width of 2 and the forum uses 4. That's why it
comes out misaligned. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 12, 2010 1:54 pm |
|
|
I'm not sure what you want. Do you want another example ?
Here's some code that I once did, to allow the user to enter the
date and time for an RTC. I don't regard this as finished code.
I don't think it's completely tested. It may not be the best way
to do it. I was just trying to quickly throw something together
for a test program. I'm just posting this to make you happy.
The pcf8583.c file is in the CCS code library forum. I've cut out
the parts that call the routines to write the date-time to the
pcf8583. Here is the output of this code on a terminal window:
Quote: |
Enter the date and time: MM/DD/YY HH:MM:SS
Or just press Enter to skip:
01/09/10 11:45:00
Sunday: 0
Monday: 1
Tuesday: 2
Wednesday: 3
Thursday: 4
Friday: 5
Saturday: 6
Enter the day of the week (0 to 6):
Updating PCF8583 with new date/time:
Friday, 1/9/10, 11:45:00
|
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <input.c>
#include <string.h>
#include <ctype.h>
#include <PCF8583.c>
// Function Prototypes
int8 get_date_time_from_user(date_time_t *dt);
int8 parse_date_time_string(char *buffer, date_time_t *dt);
int8 validate_date_time(date_time_t *dt);
char *strtoU8(char *ptr, int8 &result, int8 &count);
//=================================
void main()
{
char c;
int8 result;
char weekday[10];
date_time_t dt;
//PCF8583_init();
dt = 0; // Zero fill the date and time structure.
// Allow the user to type in a new date and time.
result = get_date_time_from_user(&dt);
// If the new date/time is valid, then write it
// to the PCF8583.
if(result == TRUE)
{
strcpy(weekday, weekday_names[dt.weekday]);
printf("Updating PCF8583 with new date/time:\n\r");
printf("%s, %u/%u/%02u, %u:%02u:%02u\n\r",
weekday, dt.month, dt.day, dt.year,
dt.hours, dt.minutes, dt.seconds);
}
else
printf("Invalid date-time \n\r");
while(1);
}
//============================================
// FUNCTIONS
//
//------------------------------------------
// Function -- get_date_time_from_user()
//
// Purpose --
// Allows the user to type in the date and time
// from a serial terminal window on their PC.
//
// Entry --
// A pointer to a date_time_t data structure must
// be passed to the function. The structure doesn't
// have to be initialized.
//
// Passed back to caller --
// The Date and time structure is filled with data.
// The data should only be considered valid by the
// caller if TRUE is returned.
//
// Returns --
// TRUE if got a valid date and time.
// FALSE if not.
int8 get_date_time_from_user(date_time_t *dt)
{
char c;
int8 num_values;
int8 result;
char input_string[30]; // Enough space for date & time
result = FALSE;
input_string[0] = 0; // Init as zero-length string
while(1)
{
printf("Enter the date and time: MM/DD/YY HH:MM:SS\n\r");
printf("Or just press Enter to skip:\n\r");
// Wait for user to type in the date and time.
get_string(input_string, sizeof(input_string));
printf("\n\r");
// Parse up to 6 values from the date/time string.
num_values = parse_date_time_string(input_string, dt);
// Exit the loop if nothing was entered.
if(num_values == 0)
{
result = FALSE;
break;
}
printf("Sunday: 0\n\r");
printf("Monday: 1\n\r");
printf("Tuesday: 2\n\r");
printf("Wednesday: 3\n\r");
printf("Thursday: 4\n\r");
printf("Friday: 5\n\r");
printf("Saturday: 6\n\r");
printf("Enter the day of the week (0 to 6): ");
// Wait for the user to enter the Day of the Week.
c = getc(); // Expect 0 to 6
printf("\n\r");
dt->weekday = c - '0'; // Remove ASCII bias
// Check if the date, time, and weekday are valid.
result = validate_date_time(dt);
if(result == TRUE) // Were the values OK ?
break; // Exit loop if so
else
printf("Try again:\n\r");
}
// Return TRUE if got a valid date and time from user.
return(result);
}
//--------------------------------------------
// Function -- validate_date_time()
//
// Purpose --
// Does an approximate validation of the date/time
// values that were entered. This routine doesn't
// check if you accidently entered February 31,
// but it does perform a basic check of the values.
//
// Entry --
// dt: date/time structure to be validated.
//
// Returns --
// TRUE if all 6 date/time values are basically OK.
// FALSE if one or more are out of range.
int8 validate_date_time(date_time_t *dt)
{
int8 retval;
retval = TRUE;
if((dt->month == 0) || (dt->month > 12)) // 1 to 12
{
printf("The month is %u, but should be 1 to 12\n\r", dt->month);
retval = FALSE;
}
if((dt->day == 0) || (dt->day > 31)) // 1 to 31
{
printf("The day is %u, but should be 1 to 31.\n\r", dt->day);
retval = FALSE;
}
if(dt->year > 99) // 00 to 99
{
printf("The year is %u, but should be 00 to 99.\n\r", dt->year);
retval = FALSE;
}
if(dt->weekday > 6) // 0 to 6
{
printf("The weekday is %u, but should be 0 to 6.\n\r", dt->weekday);
retval = FALSE;
}
if(dt->hours > 23) // 0 to 23
{
printf("The hour is %u, but should be 0 to 23.\n\r", dt->hours);
retval = FALSE;
}
if(dt->minutes > 59) // 0 to 59
{
printf("The minutes are %u, but should be 0 to 59.\n\r", dt->minutes);
retval = FALSE;
}
if(dt->seconds > 59) // 00 to 59
{
printf("The seconds are %u, but should be 0 to 59.\n\r", dt->seconds);
retval = FALSE;
}
return(retval);
}
//---------------------------------------------
// Function -- strtoU8
//
// Purpose --
// Converts a string of up to 3 ascii decimal digits
// to an 8-bit unsigned integer.
//
// Entry --
// ptr: Pointer to the string to be scanned. Leading
// and trailing alpha or whitespace chars are allowed.
//
// Passed back to caller --
// result: The 8-bit integer result.
// count: Number of ascii digits converted.
//
// Returns --
// Pointer to the next byte after the ASCII digits
// that were converted.
char *strtoU8(char *ptr, int8 &result, int8 &count)
{
char c;
int8 i;
result = 0;
count = 0;
// Skip non-numeric characters.
while(1)
{
c = *ptr;
if(c == 0) // If at end of string, then return
return(ptr);
if(isdigit(c)) // Break if found a number
break;
ptr++;
}
// Convert up to 3 ascii numbers to an 8-bit
// unsigned integer.
for(i = 0; i < 3; i++)
{
c = *ptr++;
if(!isdigit(c))
break;
// value * 10 + (c - '0') with doing multiplication:
result = (result << 3) + (result << 1) + (c - '0');
count++;
}
return(ptr);
}
//---------------------------------------------------
// Function -- parse_date_time_string()
//
// Purpose --
// Parses the date and time from a string in this format:
// MM/DD/YY HH:MM:SS (24-hour time)
// Note: This function doesn't handle the day of the week.
//
// Entry --
// string: A pointer to the input string.
// dt: A pointer to a structure of type date_time_t.
// The structure doesn't have to be initialized.
//
// Passed back to caller --
// dt: The date_time_t structure which holds the parsed
// values. These are integer numbers for the month
// day, year, hours, minutes, and seconds.
//
// Returns --
// The number of values that were parsed is returned.
// There should be 6, for the month, day, year, hours,
// minutes, and seconds. (weekday isn't handled here).
int8 parse_date_time_string(char *string, date_time_t *dt)
{
int8 i;
char *ptr;
char *endptr;
int8 result;
int8 count;
int8 output[6];
ptr = string;
// Zero the output array.
memset(output, 0, sizeof(output));
// Parse up to 6 tokens from the input string.
// The string should be in this format: MM/DD/YY HH:MM:SS
for(i = 0; i < sizeof(output); i++)
{
endptr = strtoU8(ptr, result, count);
// If we ran out of tokens to convert, then
// we're done.
if(count == 0)
break;
// If we got a value, then save it.
output[i] = result;
// Continue scanning from where we left off.
ptr = endptr;
}
// Copy the output array to the date/time structure.
// If we didn't get 6 good values from the string, then
// some of these structure members will be set to 0.
dt->month = output[0];
dt->day = output[1];
dt->year = output[2];
dt->hours = output[3];
dt->minutes = output[4];
dt->seconds = output[5];
// Return the number of items we found.
return(i);
}
// End of file |
|
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Fri Mar 12, 2010 7:19 pm |
|
|
I had not much time to look at your code, thanks anyway will check it later. BTW only have 4 button to change time/ Up/Down/Cancel/Enter, and GLCD only.
Q:
I'm trying to replace this code with a function to save code space.
Code: | set_digit(0,24,hrs); // min value, max value, digit to change
set_digit(0,60,mins)
set_digit(1,31,date)
set_digit(1,12,month)
set_digit(1,12,year) |
Code: | /////////////////////////////////////////////////////////////////////////
void set_digit(int8 mind, int8 maxd,*digit)
{
keys = scan_keys();
if (keys == Down && *digit > mind+1)
--*digit;
else if (keys == Down)
*digit = maxd-1;
if (keys == Up && *digit < maxd-1)
++*digit;
else if (keys == Up)
*digit = 0;
}
///////////////////////////////////////////////////////////////////////// |
Code: |
//original
keys = scan_keys(); // get the key values 1-enter,2-cance,3-down,4-up
if (keys == 3 && min > 0) // if down and minutes more than 1
--min; // go down one to min "00" = 60 min
else if (keys == 3) // if less than "00"
min = 59; // got to max "59"
if (keys == 4 && min < 59) // same idea for up
++ min; //
else if (keys == 4) //
min = 0; |
I don't have a lot of experience in C, how can I pass the address of the var what I want to change ?
Thanks |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sat Mar 13, 2010 12:08 pm |
|
|
Come-on everybody.....
How can I pass/give/show/point the address of the var what I want to change ?
Code: |
//variable hrs = xx any number
set_digit(0,24,hrs);
|
Code: |
void set_digit(int8 mind, int8 maxd,*digit)
{
digit = 0xff;
}
|
now variable hrs = 0xff |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sat Mar 13, 2010 3:44 pm |
|
|
Code: | set_digit(0,24,hrs);
//this only pass the current value hrs variable
//I want to send the address of hrs |
|
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sat Mar 13, 2010 6:47 pm |
|
|
ok
I got it working....
Code: | /////////////////////////////////////////////////////////////////////////
int set_digit(int8 mind, int8 maxd,*digit )
{
keys = scan_keys();
if (keys == 3 && *digit > mind+1)
--*digit;
else if (keys == 3)
*digit = maxd-1;
if (keys == 4 && *digit < maxd-1)
++*digit;
else if (keys == 4)
*digit = 0;
}
///////////////////////////////////////////////////////////////////////// |
and to call
Code: |
set_digit(0,24,&hrs);
set_digit(0,60,&min);
|
http://www.youtube.com/watch?v=hKaTyEQkvgU |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|