time.h

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is there any library or function to get current time in AVR STUDIO 6?

I've seen many codes using "include " but AVR studio does not recognize that lib.

I need to get seconds since 1970 to current date..

thanks for any help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to get from where? Do you have some RTC in circuit?

Computers don't make errors - What they do they do on purpose.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The time.h taken from any POSIX compliant operating system should be easily reusable for AVR.

AVR-LibC itself doesn't have one as the AVR has no built in RTC to act as a source to use it with.

However you are not the first to ask about this and you should be able to find the prior threads where solutions/links were given.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm get datas from a device, it provides some datas, including date, and I hold all informations in my code, what I need to do is convert the current date in seconds with reference 01/01/1970...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK so here's some source:

http://glibc.sourcearchive.com/d...

That is the source for Glibc which is what you will use if you run gcc on a Linux system (for example). The function to take d/m/y values and convert to "unixtime" is mktime so take a look at:

http://glibc.sourcearchive.com/d...

in particular.

Here's a program that demonstrates usage in both directions - it's the latter mktime() you'd be interested in:

#include 
#include 

int main(void) {
	time_t unixtime;
	struct tm * timeinfo;

	unixtime = time(NULL);
	timeinfo = localtime( &unixtime );
	printf("unixtime %u is year=%d, month=%d, day=%d, wday=%d, hour=%d, min=%d, sec=%d\n",
		(unsigned int)unixtime,
		timeinfo->tm_year + 1900,
		timeinfo->tm_mon,
		timeinfo->tm_mday,
		timeinfo->tm_wday,
		timeinfo->tm_hour,
		timeinfo->tm_min,
		timeinfo->tm_sec);

	timeinfo->tm_year = 2012-1900;
	timeinfo->tm_mon = 3;
	timeinfo->tm_mday = 23;
	timeinfo->tm_hour = 12;
	timeinfo->tm_min = 37;
	timeinfo->tm_sec = 53;
	unixtime = mktime(timeinfo);
	printf("that is %u seconds since 1st Jan 1970\n", (unsigned int)unixtime);
}

When run that program shows:

root@ws-czc1138h0b:/windows# gcc time.c -o time -Wl,-Map,time.map
root@ws-czc1138h0b:/windows# ./time
unixtime 1340806766 is year=2012, month=5, day=27, wday=3, hour=15, min=19, sec=26
that is 1335181073 seconds since 1st Jan 1970

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, you can compute the number of seconds since 01/01/current_year at 0h,0mn,0s? (sorry, I have this only in Fortran77 ; the only trick is with leap years : the length of the month is in a 12 integer array, and the length of February should not be modified -I saw in glibc they used two arrays, one for ordinary years, one for leap years)

You can compute the number of leap years since 1970 (lets call it N_leap_70) up to -and excluding- current_year?

(

N_leap_70= ( current_year-1 -68   )/4

is likely to work before 2100, "/" being an integer division ...

Then, the number of seconds from the unix epoch to 01/01/current_year might be

3600 * 24* ((current_year - 1970) * 365 + N_leap_70)

Else, google search "time unix epoch" and you will find online calculators to verify you were right in your computations...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Else, google search "time unix epoch" and you will find online calculators to verify you were right in your computations...

I have a current app that is fairly complex by AVR8 standards. DS1305 RTC, SD card, and log files created on the SD card that are processed into reports using a PC app.

SD card wants a DOS time for file timestamping. I decided on Unix time format for my log files. And on the PC side there is a feature to create CSV files that can be imported into Microsoft Excel or similar.

-- Timestamp fetched from DS1305, in BCD format.
-- BCD format converted to binary format for s/m/h/m/d/y.
-- Binary format converted to Unix time. Constant used for the start of 2009 when app was commissioned. Routine below. Lookup table for each month.
-- Another routine for binary format to DOS timestamp.

-- In the PC app, there is a conversion routine for Unix => Excel.

//	RTC and TimeStamp Handling
//	==========================
//
#define	RTC_SEC_PER_HOUR	(60l * 60l)
#define	RTC_SEC_PER_DAY		(RTC_SEC_PER_HOUR * 24l)
#define	RTC_SEC_PER_YEAR	(RTC_SEC_PER_DAY * 365l)

// Seconds from Jan.1, 1970 through Dec. 31, 2008.
//	-- 39 years
//	-- Leap years: 72, 76, 80, 84, 88, 92, 96, 00, 04, 08
//
//	According to Excel, there are 14245 days between those two dates.
//		365 * 39 = 14235 so that would be 10 leap years.
//
#define	RTC_SEC_TILL_2009	(RTC_SEC_PER_DAY * 14245L)

#define	RTC_YEAR_MIN	9	// 2009, as an 8-bit binary year
#define	RTC_YEAR_MAX	25	// 2025, as an 8-bit binary year

// Elapsed days at the end of each month shown (ignoring leap years)
flash unsigned int		rtc_days[13] =
{
0,
31,		// J
59,		// F
90,		// M
120,	// A
151,	// M
181,	// J
212,	// J
243,	// A
273,	// S
304,	// O
334,	// N
365		// D
};

...

//
// **************************************************************************
// *
// *	B I N T I M E 2 U N I X T I M E
// *
// **************************************************************************
//
utime_t 				bintime2unixtime	(struct bintime * btimeptr)
{
// Convert the BCD time From DS1305/6 to an unsigned long UNIX timestamp
//	of seconds since the epoch-- Jan. 1, 1970.
//
// As this app never needs to go back in time or specify arbitrary dates,
//	simplifications can be done by simply calculating the whole-year
//	seconds through an arbitrary year such as 2000, 2007, or 2008.
//
// Do a quick window check on the year.  It must be > 2008, and must be less than
//	an arbitrary year--2020?
utime_t			work;	// accumulator of seconds
signed int		mult;	// working

// Base seconds, 1970 through 2008
	work = RTC_SEC_TILL_2009;

// How many years since?
	mult = btimeptr->year - RTC_YEAR_MIN;
	if ((mult < 0) || (mult > (RTC_YEAR_MAX - RTC_YEAR_MIN + 1)))
		{
		mult = 0;
		}
// Add the whole years since start of 2009
	work += (unsigned long)mult * RTC_SEC_PER_YEAR;

// Add a day for each leap year in the prior years
	work += ((unsigned long)mult/4) * RTC_SEC_PER_DAY;

// Add a day for this year, if leap year and past Feb.
	if ((mult+1) % 4 == 0)
		{
		// Leap year
		if (btimeptr->month > 2)
			{
			// Past February
			work += RTC_SEC_PER_DAY;
			}
		}

// Add the days up to this month.  Use a table
	mult = btimeptr->month;
	if ((mult < 1) || (mult > 12))
		{
		mult = 1;
		}

	work += ((unsigned long)rtc_days[mult-1]) * RTC_SEC_PER_DAY;

// Add the days this month, up to today
	mult = btimeptr->date;
	if ((mult < 1) || (mult > 31))
		{
		mult = 1;
		}

	work += ((unsigned long)(mult-1)) * RTC_SEC_PER_DAY;

// Add the seconds up to this hour
	mult = btimeptr->hours;
	if ((mult < 0) || (mult > 23))
		{
		mult = 1;
		}

	work += ((unsigned long)(mult)) * RTC_SEC_PER_HOUR;

// Add the seconds this hour
	mult = (unsigned int)60 * (unsigned int)btimeptr->minutes + (unsigned int)btimeptr->seconds;

	work += mult;

	return work;
}

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I would like to thank Monsieur Theusch for his function (it seems to work well on a PC -it is more convenient for trials- , and before I had it compiled, I did not find anything controversial -perhaps I should wait 80 years ...).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi ,

 

i have question related to same topic :

i use the atmga8 and include time.h.

 

Can I simulate  the elapsed seconds using AVRStudio7 simulator without connection  to  target avr  as the below simple code :

but iam sure that has fatal mistakes because

1. delay doesnot   take 3 Secs but  aprox 20Secs. 

2. diff result is Unkown

 

Please advice .

 

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <time.h>
#include <stdio.h>
   
int main(){
int diff;	
 time_t seconds1;
 time_t seconds2;
 struct tm * ts;
 seconds1 = time(NULL);
 _delay_ms(3000);
 seconds2 = time(NULL);
   diff= difftime(seconds1,seconds2);
return(0);

}

 

  

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You must have a very fast PC. I would expect the Simulator to take far longer than 205 seconds.
But it should give you the correct answer in diff.
.
The Simulator is excellent for counting cycles or stepping through short sequences of fast code.
If you want to investigate seconds, minutes, hours, ... you will have a LONG wait.
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yeah be warned that the simulator always operates as if it were an AVR at about 50kHz. So if you really want that to elapse 3 seconds you probably want to try something like:

#define F_CPU 50000UL

If you continue to use:

#define F_CPU 1000000UL

on an "AVR" that is running at 50kHz then:

_delay_ms(3000);

will be 20 times too long so 3 seconds will be 1 minute.

 

Anyway:

seconds1 = time(NULL);

How is that going to work? I see nothing there that is programming an RTC or other timer to actually "tick" elapsed time?

 

See system_tick() on this page in the manual:

 

http://www.nongnu.org/avr-libc/u...

 

As it says there the function has to be called at 1Hz.

 

An alternative method (if using something like an RTC is to feed its value into set_system_time().

 

as you've written your code it seems like you believ the AVr has some kind of operating system with it's own timers maintaining system time? It doesn't. It's your job to write that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for you replay

 

i have another issue regard to timer interrupt iam using avrstudio7 simaltor no conection to actual hard ware and i tried to simulate the Timer0 over flow Interrupt as the following Code  

but unfortunately the braking point (red markup code)in the interrupt code is never hit. I don't Why (Is Interupt can not simulated using avr simulator)

 

Please advice 

 

#include <util/delay.h>
#include <avr/io.h>
#include <time.h>
#include <stdio.h>
#include <avr/interrupt.h>
unsigned int input_delay;
 //Function prototypes
void delay();
void init_timer0_ovf_interrupt(void);
void timerInt(void);

//void timer0_interrupt_isr(void);
int main(){
	init_timer0_ovf_interrupt();
	delay();
}

void init_timer0_ovf_interrupt(void)
{
TCCR0 = 0x04; //divide timer0 timebase by 1024, overflow occurs
TCNT0 = 0x00; //reset timer0
//every 6.55ms
TIMSK = 0x01; //enable timer0 overflow interrupt
asm("SEI"); //enable global interrupt
//sei();

}
#pragma interrupt_handler timerInt:9
void timerInt(void)
{
PORTC=0xFF;	
input_delay++; //input delay processing
}
void delay(void)
{
TCNT0 = 0x00; //reset timer0
 input_delay = 0;
while(1)
{
;
}
}

 

Last Edited: Sun. Apr 2, 2017 - 03:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The headers suggest you are using avr-gcc but your #pragma interrupt looks like the syntax for an entirely different C compiler. Which compiler is it that you are using? In avr-gcc the syntax for an interrupt handler is ISR() 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ooh, Thanks so much is  solved as my compiler is gcc