Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC DayOfWeek() routine, 2000-2099

Status
Not open for further replies.

Mike - K8LH

Well-Known Member
Thought I'd share a DayOfWeek() algorithm I put together after studying some examples on the Internet. I needed the routine to light up the day-of-week LEDs on my Techie' BCD Clock kit and thought it might be useful to some of the others building PIC clocks. It might also be handy for displaying Mon, Tue, Wed, etc., on someones dot-matrix or LCD Clock/Calendar project.

Have fun. Regards, Mike

Code:
;******************************************************************
;*                                                                *
;*  Day_of_Week, 2000-2099           Mike McLaren, K8LH, Aug '07  *
;*                                                                *
;*  params: Month (1..12), Day (1..31), Year (0..99)              *
;*  output: W = 0..6 (Sun..Sat)                                   *
;*                                                                *
;*  39 words (14 bit core)                                        *
;******************************************************************
        radix dec
;
;  char Month;                  // 1..12
;  char Day;                    // 1..31
;  char Year;                   // 0..99 (2000-2099)
;
;  char DayOfWeek()
;  {                            // returns 0..6 (Sun..Sat)
;    char Leap;
;    char Y2000 [] = { 5, 1, 1, 4, 6, 2, 4, 0, 3, 5, 1, 3 };
;    Leap = (Year & 3) || (Month > 2);
;    return (Y2000[Month-1] + Day + Leap + Year + Year/4) % 7;
;  }
;
DayOfWeek
        clrf    Leap            ; Leap = 0                        |B0
        movf    Month,W         ; W = Month (1..12)               |B0
        addlw   -3              ; C = 0 if Jan or Feb             |B0
        movf    Year,W          ; W = Year (0..99)                |B0
        andlw   b'00000011'     ; is this a leap year?            |B0
        skpz                    ; yes, skip, else                 |B0
        setc                    ; set C (will force Leap = 1)     |B0
        rlf     Leap,F          ; Leap = 0 or 1                   |B0
;
;  an "in-line" table of DOW values minus 1 for the 1st of each
;  month in 2000, a leap year.  1st param is desired value, 2nd
;  param cancels out WREG, and 3rd param cancels out next table
;  entry.  an "in-line" table saves me 1 word and 1 stack level
;  but uses more cycles for lower table index values.  table is
;  256-byte-boundary tolerant.
;
        movlw   high (Y2000)    ;                                 |B0
        movwf   PCLATH          ;                                 |B0
        decf    Month,W         ;                                 |B0
        addlw   low (Y2000)     ;                                 |B0
        skpnc                   ;                                 |B0
        incf    PCLATH,F        ;                                 |B0
        movwf   PCL             ;                                 |B0
Y2000   xorlw   5^$^(1^$+1)     ; 6 (Jan 2000)                    |B0
        xorlw   1^$^(1^$+1)     ; 2 (Feb)                         |B0
        xorlw   1^$^(4^$+1)     ; 2 (Mar)                         |B0
        xorlw   4^$^(6^$+1)     ; 5 (Apr)                         |B0
        xorlw   6^$^(2^$+1)     ; 0 (May)                         |B0
        xorlw   2^$^(4^$+1)     ; 3 (Jun)                         |B0
        xorlw   4^$^(0^$+1)     ; 5 (Jul)                         |B0
        xorlw   0^$^(3^$+1)     ; 1 (Aug)                         |B0
        xorlw   3^$^(5^$+1)     ; 4 (Sep)                         |B0
        xorlw   5^$^(1^$+1)     ; 6 (Oct)                         |B0
        xorlw   1^$^(3^$+1)     ; 2 (Nov)                         |B0
        xorlw   3^$             ; 4 (Dec)                         |B0
;
;  WREG = (((Y2000[Month-1] + Day + Leap)*2 + Year/2)/2 + Year) % 7
;
        addwf   Day,W           ; add Day (1..31)                 |B0
        addwf   Leap,F          ; add Leapday (0 or 1)            |B0
        rlf     Leap,F          ; multiply by 2                   |B0
        rrf     Year,W          ; divide year by 2                |B0
        addwf   Leap,F          ; add 'em together                |B0
        rrf     Leap,W          ; divide result by 2              |B0
        addwf   Year,W          ; add Year (0..99)                |B0
Mod7    addlw   -7              ; result % 7                      |B0
        bc      Mod7            ;                                 |B0
        addlw   7               ;                                 |B0
        return                  ;                                 |B0

;******************************************************************
 
Last edited:
Probably not very valid for PIC's, but I used to do it using Julian date routines I wrote (in Turbo Pascal) - simply divide the Julian date by 7, and the integer remainder is the day (between 0 and 6).

BTW, nice routine!.
 
Nice bit of code, very neat, the Julian method is a little tricky on a PIC I think, 64-bit floating point (double precision) math...
 
Gordz said:
Nice bit of code, very neat, the Julian method is a little tricky on a PIC I think, 64-bit floating point (double precision) math...

You obviously don't require that degree of precision, and while it would be doable on a PIC, I never suggested it would be a good idea!.
 
Gordz said:
Nice bit of code, very neat, the Julian method is a little tricky on a PIC I think, 64-bit floating point (double precision) math...

Indeed you did not Nigel, sorry, did I infer that you had ? My applogy.
 
Status
Not open for further replies.

Latest threads

Back
Top