NE pokušavajte da shvatite kako procedura GetDayOfWeek u potpunosti radi. Prilično je optimizovana. Važno je da radi. Mogla bi se napisati i kraća, ako bi vršili kalkulaciju samo za godine 2000-2099.
Date su tri procedure na raspolaganju:
GetDayOfWeek - nalazi dan u nedelji (ponedeljak..nedelja) za zadat datum (1.1.1984. ...31.12.2099.) : 43 reči
CheckDate - proverava da li je datum validan ili ne (1.1.1984. ...31.12.2099) :50 reči
GetNextDate - izračunava datum sutrašnjeg dana (1.1.1984. ...30.12.2099.) : 16 reči
Pitate se: gde bi se mogle upotrebiti ove procedure? Ove procedure bi se mogle upotrebiti kod proizvoda zasnovanih na PIC mikrokontrolerima, npr. kod električnih časovnika, alarmnih uređaja, kod raznih vrsta data logger-a, kod uređaja za praćenje kvaliteta transporta itd..sl.. Naravno, postoje gotova integrisana kola koja objedinjuju sve, časovnik, datum, alarm. Međutim, ova kola (proizovdi ih Dallas Semiconductors i drugi) se na mikrokontroler priključuju serijskim portom, obično I2C ili SPI protokolom, te zahtevaju 2 ili 3 I/O linije za komunikaciju. Ako "procesorska moć" PIC-a omogućuje da se primene ove procedure, ušteda na specijalnom kolu i na 2 do 3 I/O porta nije zanemariva.
-------------------------------------------
Dear Sirs,
I decided to send you some program code that I was incited to write when I read Microchip`s TB28. Here is shorter, more compact, faster and in general better solution for date-related calculations.
If you respond to me, I`ll be happy to send you more text about theory of
calculation and explanations for applied code optimization.
Regards
CENSORED
CENSORED
PROGRAM CODE FOLLOWS:
List P=16F84A
;********************************************************************************
*********************
;* These routines are intended for calculating day of the week, for validation
of particular date,
;* and for finding date of the next day. First two routines represent better
solution than ones
;* that were published in Microchip`s TB28. Third routine is not published in
TB28, but can be
;* very useful.
;* Routine GetDayOfWeek (together with AddMod7 i GetMonthVal) is 43 lines long
compared to 72 lines
;* in TB28. This routine requires only 1 auxillary RAM location -> Temp1.
;* Routine CheckDate is 50 lines long compared to 22 lines in TB28, but solution
in TB28 only
;* checks for valid year range (1990.-2099.), and does not check if date is
valid or not; therefore
;* dates like Feb, 29th 1998. and Mar, 32nd 1999. are evaluated as valid dates in
TB28, but not in this
;* solution.
;* Routine GetNextDate is useful when we want to find date of the next day.
;********************************************************************************
*********************
;* Author: CENSORED, CENSORED, blaza@www.com
;********************************************************************************
*********************
PCL equ 02h
STATUS equ 03h
#define Z STATUS,2
#define C STATUS,0
Day equ 10h
Month equ 11h
YearH equ 12h
YearL equ 13h
DayOfWeek equ 14h
Temp1 equ 15h
org 0x00
main movlw 0x0005
movwf Day
movlw 0x0005
movwf Month
movlw 0x0007
movwf YearH
movlw 0x00d1
movwf YearL ;May, 5th 2001.
call CheckDate
nop ; <- break point here
call GetDayOfWeek
nop ; <-break point here
end_ call GetNextDate
goto end_ ; <-break point here
;********************************************************************************
********************
;* This routine computes day of week for particular date
;* Input: Day, Month, YearH & YearL --> Date in range Jan, 1st 1984. - Dec, 31st
2099.
;* Output: DayOfWeek --> 1 Monday, 2 Tuesday, 3 Wensday, 4 Thursday, 5 Friday, 6
Saturday, 7 Sunday
;* This routine uses routines AddMod7 i GetMonthVal, and RAM loccation Temp1
;* Total code length : 43 lines (together with routines AddMod7 and GetMonthVal)
;********************************************************************************
********************
GetDayOfWeek movf Day,w
btfsc YearH,3
addlw 0x0002
movwf DayOfWeek
movf YearL,w
movwf Temp1
call AddMod7
rrf Temp1
rrf Temp1,w
call AddMod7
btfss YearL,0
btfsc YearL,1
goto Cont1
movlw 0x0002
subwf Month,w
btfss c
decf DayOfWeek
Cont1 decf Month,w
call GetMonthVal
call AddMod7
call AddMod7
AddMod7 andlw 0x003f
addwf DayOfWeek
movlw 0x0007
andwf DayOfWeek,w
xorwf DayOfWeek
rlf DayOfWeek
swapf DayOfWeek
addwf DayOfWeek
retlw 0
GetMonthVal addwf PCL
retlw 1
retlw 4
retlw 4
retlw 0
retlw 2
retlw 5
retlw 0
retlw 3
retlw 6
retlw 1
retlw 4
retlw 6
;********************************************************************************
********************
;* This routine determines if particular date is valid or not
;* Input: Day, Month, YearH & YearL --> Date in range Jan 1st 1984. - Dec 31st
2099.
;* Output: Z --> 0 - Date is not valid ; 1 - Date is valid
;* This routine uses RAM loccation Temp1
;* Code length : 50 lines
;********************************************************************************
********************
CheckDate movf Month,w
btfsc z
goto NotValid
movwf Temp1
sublw 0x000c
btfss c
goto NotValid
btfsc Temp1,3
incf Temp1
movf Day,w
btfsc z
goto NotValid
andlw 0x00e0
btfss z
goto NotValid
btfsc temp1,0
goto Cont2
incf Day,w
andlw 0x0020
btfss z
goto NotValid
movf Month,w
xorlw 0x0002
btfss z
goto Cont2
movlw 0x001d
subwf Day,w
btfss c
goto Cont2
btfss z
goto NotValid
btfss YearL,0
btfsc YearL,1
goto NotValid
Cont2 movf YearH,w
sublw 0x0007
btfss z
goto Cont3
movf Yearl,w
sublw 0x00bf
goto Cont4
Cont3 addlw 0x0001
btfss z
goto NotValid
movlw 0x0034
subwf YearH,w
Cont4 btfsc c
NotValid bcf z
Valid bsf z
retlw 0
;********************************************************************************
********************
;* This routine computes date of the next day
;* Input: Day, Month, YearH & YearL --> Date in range Jan, 1st 1984. - Dec, 30th
2099.
;* Output: Day, Month, YearH & YearL --> Date of the next day
;* This routine uses routine CheckDate
;* Code length : 16 lines
;********************************************************************************
********************
GetNextDate incf Day
call CheckDate
btfsc z
retlw 0
movlw 0x0001
movwf Day
incf Month
call CheckDate
btfsc z
retlw 0
movlw 0x0001
movwf Month
incf Yearl
btfsc z
incf YearH
goto CheckDate
end
n
int�H = rand() % 10000; /