The code below allows your PIC to log into a network timeserver and it (eventually) writes the time to a Dallas RTC (code not supplied).
The PIC checks the NET TIME every power-up and thereafter every 4 hours. If it doesn't make connection, it tries an alternate time server. If THAT doesn't work (after retries) it gives up and tries again 4 hours later. A Lantronix XPort handles the connection to the net.
The PIC normally reads the time from the Dallas RTC. The clock is self-setting and self-correcting, as long as you have a network connection.
And all of you using 16F chips, time to upgrade! This sub requires LONGS.
Net Time' is the number of seconds since Jan 1 1900 This sub accomodates for leap years, GMT offsets and Daylight Savings Time. The sub assumes you are in the present century, so it takes a shortcut by pre-subtracting the number of seconds from Jan 1 1900 to Jan 1 2009. It should be self-explanatory. |
Hoffset is the hours offset from GMT Sign = "1" or "2" depending on whether you are earlier or later than GMT DST = 1 if you are in Daylight Savings Time (Another part of the PGM changes that value when appropriate). GETNETTIME: NETRETRYCOUNT = 0 GETNETTIME2: HSEROUT [13,10,"TIMESERVER ",#TSIP1,".",#TSIP2,".",#TSIP3,".",#TSIP4,13,10] PAUSE 100 THEADER[0] = $2 ' STX THEADER[1] = TSIP1 ' DESTINATION IP THEADER[2] = TSIP2 THEADER[3] = TSIP3 THEADER[4] = TSIP4 THEADER[5] = 0 ; DESTINATION PORT HIGHBYTE THEADER[6] = 123 ; DESTINATION PORT LOWBYTE LRC1 = 0 LRC2 = 0 For X = 1 to 6 LRC1 = LRC1 ^ THeader[x] next X THEADER[7] = LRC1 THEADER[8] = 0 THEADER[9] = 48 'Data Length lowbyte ;Send the header HSEROUT [13,10] For X = 0 to 9 HSEROUT2 [THeader[X]] Next X LRC2 = LRC2 ^ THeader[8] LRC2 = LRC2 ^ THeader[9] ;Send the data HSEROUT2 [$1B] LRC2 = LRC2 ^ $1B For X = 0 To 46 HSEROUT2 [0] LRC2 = LRC2 ^ 0 NEXT X ;Send the Checksum (LRC) HSEROUT2 [LRC2] getresponse: HSERIN2 1000,NoResponse,[Wait($2)] hserin2 200,NoResponse,[SKIP 41,TimeNow.Byte3,TimeNow.Byte2,TimeNow.Byte1,TimeNow.Byte0] READ 851,HOFFSET IF sign = "1" then if DST = 1 and HOffset = 0 THEN Sign = "2" GOTO OtherSide ENDIF TimeNow = Timenow - ((HOffset - DST) * 3600) ENDIF OtherSide: IF Sign = "2" THEN TimeNow = TimeNow + ((Hoffset + DST) * 3600) ENDIF SINCEJAN2009 = TIMENOW - 3439756800 ; 3439756800 is the #of sec from Jan1 1900 to Jan1 2009 RUNNINGSECONDS = SINCEjAN2009 YR = 2009 GETYEAR: LEAP = (YR//4) ; = 0 if leap year if LEAP = 0 then SecondsInYear = 31622400 ;366*60*60**24 ELSE SecondsInYear = 31536000 ;365*60*60*24 endif If RunningSeconds > SecondsInYear Then RunningSeconds = RunningSeconds - SecondsInyear YR = YR + 1 GOTO GetYear ENDIF Mo = 1 ; Start with Month = 1 GETMONTH: IF LEAP > 0 THEN lookup2 MO,[0,2678400,2419200,2678400,2592000,2678400,2592000,2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth ELSE LOOKUP2 MO,[0,2678400,2505600,2678400,2592000,2678400,2592000,2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth ENDIF If RunningSeconds >= SecondsInMonth THEN RunningSeconds = RunningSeconds - SecondsInMonth MO = MO + 1 GOTO GETMONTH ENDIF FINDDAYS: DA = RUNNINGSECONDS/86400 RUNNINGSECONDS = RUNNINGSECONDS//86400 HR = RUNNINGSECONDS/3600 RUNNINGSECONDS = RUNNINGSECONDS//3600 MN = RUNNINGSECONDS/60 RUNNINGSECONDS = RUNNINGSECONDS//60 SC = RUNNINGSECONDS Da = Da + 1 HSEROUT [13,10,13,10,DEC2 HR,":",DEC2 MN,":",DEC2 SC," ",DEC2 MO,"/",DEC2 DA,"/",#YR,13,10] Return
Re: PBP3 Optimization & Peripheral Control Techniques on PIC16F/18F Devices
Yes, all the time and most times in conjuction with DT-Ints for PBP context save/restore. For periodic/cyclic interrupts using TMR2 (or one of the same type) is nice because you set it up once and...
HenrikOlsson Yesterday, 15:27