1. 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.
    Dismiss Notice

Clock

Discussion in 'Microcontrollers' started by AtomSoft, Dec 24, 2008.

  1. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Damn interrupts:
    This is the configs for the interrup. Im trying to set INT1 & INT2 where :
    INT1 = Low Priority
    INT2 = HIGH Priority
    Code (text):

    /*  Interrupt Items  */
        RCON = 0x80;
        INTCON = 0xC0;
        INTCON2 = 0x80;
        INTCON3 = 0x98;

    /**********************************
                Interrupt Code
    ***********************************/
    #pragma code low_vector=0x18
    void interrupt_at_low_vector(void)
    {
      _asm GOTO low_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interruptlow low_isr
    void low_isr (void)
    {
        myTmp = PORTB;
        UpdateTime();
        INTCON3 = 0xFC;

    }


    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
      _asm GOTO high_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interrupt high_isr
    void high_isr (void)
    {
        myTmp = PORTB;
        alarmOut = 1;
        RTCRegRead(0x07);  
        INTCON3 = 0xFC;
    }
     
    Any thoughts of why this isnt working? It seems to only jump to the "high_isr".

    I have the 1hz thing from DS1306 to RB1 and RB2 is the INT0 from DS1306
     
    Last edited: Dec 30, 2008
  2. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    ok this code is all of it except set the date i left the simplest for last lol The interrupt seems to be working now i think i had a bit wrong dont remember.
    Code (text):

    /******************************************************************************
     *
     *          AtomSoft Clock Using PIC18F248, DS1306, 74LS164, 74LS165
     *
     ******************************************************************************
     * FileName:        main.c
     * Author:          Jason Lopez
     * Processor:       PIC18F248(0)
     * Compiler:        C18
     * Company:         AtomSoftTech
     * Version:         1.0.0
     ******************************************************************************/
    #include <p18F248.h>
    #include <stdio.h>
    #include <delays.h>
    #include <spi.h>

    #pragma config WDT = OFF, LVP = OFF, OSC = HS
    /************************************
    Prototypes
    *************************************/
    void main(void);

    void initSPI(void);
    void e_togg(void);
    void lcd_line(char line);
    void lcd_cmd(unsigned char letter);
    void lcd_char(unsigned char letter);
    void lcd_string(char *senpoint);
    void lcd_init(void);
    void delay_ms(int mS);
    void delay_us(int uS);
    void delay_s(int S);
    void lcdByte(unsigned char dNyb,unsigned char rs);

    char RTCRegRead(char adx);
    void RTCRegWrite(char adx, char data);

    static unsigned char uint2bcd(unsigned char ival);
    char readBtn(void);
    unsigned char bcd2dec(unsigned char aBCD, char type);

    void putDate(char type, char data);

    void UpdateTime(void) ;
    void ShowMenu(void);
    void SetTime(char type);
    void low_isr(void);
    void high_isr(void);

    /************************************
    Definitions
    ************************************/
    #define CS LATCbits.LATC2
    #define CS_T  TRISCbits.TRISC2
    #define SCL_T TRISCbits.TRISC3
    #define SDA_T TRISCbits.TRISC4
    #define SDO_T TRISCbits.TRISC5

    #define LCD_DAT_T TRISCbits.TRISC0
    #define LCD_CLK_T TRISCbits.TRISC1

    #define LCD_DAT LATCbits.LATC0
    #define LCD_CLK LATCbits.LATC1

    #define LCD_E_T TRISCbits.TRISC6
    #define LCD_E   LATCbits.LATC6

    #define PL  LATBbits.LATB0
    #define CP2 LATBbits.LATB1
    #define SDL  PORTBbits.RB2

    #define PL_T   TRISBbits.TRISB0
    #define CP2_T  TRISBbits.TRISB1
    #define SDL_T  TRISBbits.TRISB2

    #define Button      (PORTA >> 1) & 0x0F;
    #define Button_T    TRISA    
    #define setupBtn    0x01
    #define downBtn     0x02
    #define upBtn       0x04
    #define selectBtn   0x08

    #define alarmOut  LATBbits.LATB3
    #define alarmOutT TRISBbits.TRISB3
    #define alarmIn_T   TRISBbits.TRISB1
    #define OneHz_T   TRISBbits.TRISB0
    /************************************
    Variables
    ************************************/
    char string[]       = "                ";
    char string2[]      = "                ";
    char company[]      = "  AtomSoftTech  ";
    char SetStr[]       = "    Settings    ";
    char SetTA[]        = " Adjust:        ";
    char TimeStr[]      = "1. Set Time     ";
    char DateStr[]      = "2. Set Date     ";
    char AlarmStr[]     = "3. Set Alarm    ";


    unsigned char lDate[16];
    unsigned char myTmp;
    //////////////////////////
    /*       NEW VARs       */
    //////////////////////////
    unsigned char decHour;
    unsigned char decMin;
    unsigned char decAPM;
    unsigned char BcdHour;
    unsigned char BcdMin;
    unsigned char BcdAPM;
    unsigned char BcdSec;

    unsigned char decDate;
    unsigned char decMonth;
    unsigned char decYear;

    unsigned char time[16];
    unsigned char comDate[16];
    unsigned char view;

    /************************************
    Main
    ************************************/
    void main(void) {

        ADCON1 = 0x0E;

        initSPI();
        lcd_init();

        SDL_T = 1;
        Button_T = 0xFF;    //TRISA (all input)

        RTCRegWrite(0x8F,0x05);

        alarmIn_T = 1;
        OneHz_T = 1;
        alarmOutT = 0;
        alarmOut = 0;

    /*  Interrupt Items  */
        RCON = 0x80;
        INTCON = 0xC0;
        INTCON2 = 0x80;
        INTCON3 = 0x98;

        UpdateTime();
        view = 0;
        RTCRegRead(0x07);
        while(1) {
            myTmp = Button;

            if(myTmp == selectBtn){
                if(view == 1){
                    lcd_string(company);
                    view = 0;
                } else {
                    lcd_string(comDate);
                    view = 1;
                }
                UpdateTime();
                while(myTmp == selectBtn){myTmp = Button};
            }

            if(myTmp == setupBtn){
                INTCON = 0x00;
                ShowMenu();
                UpdateTime();
                delay_s(1);
                INTCON = 0xC0;
            }
           
            if(myTmp == upBtn){
                alarmOut = 0;
            }    
        }
    }
    /***********************************
    RTC Tools
    ************************************
    Convert Char(byte) to BCD
    ************************************/
    unsigned char uint2bcd(unsigned char ival)
    {
        return ((ival / 10) << 4) | (ival % 10);
    }
    /************************************
    Convert BCD to Char(byte)
    ************************************/
    unsigned char bcd2dec(unsigned char aBCD, char type)
    {
        char lowNyb = aBCD & 0x0F;
        char highNyb = aBCD >> 4;
        char MyDec = lowNyb;
        char x;

        switch(type){
            case 0:
                highNyb &= 0x0F;
                break;
            case 1:
                highNyb &= 0x01;
                break;
            case 2:
                highNyb &= 0x03;
                break;
            case 3:
                highNyb &= 0x07;
                break;
            case 4:
                highNyb &= 0x00;
                break;
        }

        for(x=0;x<highNyb;x++){
            MyDec += 10;    
        }

        return MyDec;
    }
    /************************************
    Read a Register off the DS1306
    ************************************/
    char RTCRegRead(char adx){
        char tmp;
        CS = 1;
            WriteSPI(adx); //sec
            tmp = ReadSPI();
        CS = 0;

        return tmp;
    }
    /************************************
    Write to a Register on the DS1306
    ************************************/
    void RTCRegWrite(char adx, char data){
        CS = 1;
            WriteSPI((adx | 0x80 ));
            WriteSPI(data);
        CS = 0;
    }
    /************************************
    Initialize SPI
    ************************************/
    void initSPI(void){
        CS_T = 0;       //CS is output
        SCL_T = 0;      //SCL is output
        SDA_T = 1;      //SDA is input
        SDO_T = 0;      //SDO is output

        OpenSPI(SPI_FOSC_4,MODE_10,SMPEND);        

        CS = 1;
            WriteSPI(0x8F);
            WriteSPI(0x00);
        CS = 0;

    }
    /***********************************
    LCD Functions
    ************************************
    Send String to LCD
    ************************************/
    void lcd_string(char *senpoint){
        delay_ms(1);
        while(*senpoint != '\0'){
            lcd_char(*senpoint);
            senpoint++;
        }
    }
    /************************************
    Send Data(Nybble) to LCD
    ************************************/
    void lcdByte(unsigned char dNyb,unsigned char rs){
        int i;

        LCD_DAT=0;                          //Clear 74LS164 set initial bit to 0
        for(i=0;i<8;i++){                   //repeat for 8 bits
            LCD_CLK=1;LCD_CLK=0;            //write 0's to the 164
        }

        for(i=0;i<4;i++){                   //output the nybble
            if((dNyb & 0x08) != 0)
                LCD_DAT=1;
            else
                LCD_DAT=0;

            LCD_CLK=1;LCD_CLK=0;
            dNyb=dNyb<<1;
        }

        LCD_DAT = rs;                           //output the RS bit value
        LCD_CLK=1;LCD_CLK=0;

        LCD_DAT = 0;
        LCD_CLK=1;LCD_CLK=0;
        LCD_CLK=1;LCD_CLK=0;
        LCD_CLK=1;LCD_CLK=0;

        e_togg();
    }
    /************************************
    Toggle E Line
    ************************************/
    void e_togg(void){
        LCD_E=1;LCD_E=0;
    }
    /************************************
    Set LCD Line
    ************************************/
    void lcd_line(char line){
        if(line == 0x01)
            lcd_cmd(0x80);
        else
            lcd_cmd(0xc0);
    }
    /************************************
    LCD Send Command
    ************************************/
    void lcd_cmd(unsigned char letter){
        unsigned char temp;
        temp=letter;
        temp=temp>>4;
        lcdByte(temp,0);
        temp=letter;
        temp=temp&0x0f;
        lcdByte(temp,0);
    }
    /************************************
    LCD Send Character
    ************************************/
    void lcd_char(unsigned char letter){
        unsigned char temp;
        temp=letter;
        temp=temp>>4;
        lcdByte(temp,1);
        temp=letter;
        temp=temp&0x0f;
        lcdByte(temp,1);
    }
    /************************************
    LCD Initialization
    ************************************/
    void lcd_init(void){

        LCD_E_T = 0;
        LCD_CLK_T = 0;
        LCD_DAT_T = 0;

        lcdByte(0x03,0);
        delay_ms(5);
        e_togg();
        delay_us(160);
        e_togg();
        delay_us(160);
        lcdByte(0x02,0);
        delay_us(160);
        lcd_cmd(0x28);                  //set 4-bit mode and 2 lines
        delay_us(160);
        lcd_cmd(0x10);                  //cursor move & shift left
        delay_us(160);
        lcd_cmd(0x06);                  //entry mode = increment
        delay_us(160);
        lcd_cmd(0x0d);                  //display on - cursor blink on
        delay_us(160);
        lcd_cmd(0x01);                  //clear display
        delay_ms(500);
    }
    /************************************
    Delays (S,mS,uS) for 20Mhz
    ************************************/
    /*********************
        Delay Second(s)
    **********************/
    void delay_s(int S){
        int y;
        char x;

        for(y=0;y<S;y++)
            for(x=0;x<4;x++)
                delay_ms(250);

    }
    /************************
        Delay MilliSecond(s)
    *************************/
    void delay_ms(int mS){
        int y;

        for(y=0;y<mS;y++)
            Delay1KTCYx(5);
    }
    /************************
        Delay MicroSeconds
    *************************
    Lowercase 'u' is common
    symbol for Micro
    *************************/
    void delay_us(int uS){
        int y;
        char x;

        for(y=0;y<uS;y++)
            for(x=0;x<5;x++)
                Nop();
    }
    /**********************************
    readBtn
    ***********************************/
    char readBtn(void){
        char tmpA;
       
        tmpA = myTmp = Button;
        while(myTmp == tmpA){myTmp = Button};
     
        return tmpA;
    }
    /**********************************
    LCD / RTC stuff
    ***********************************/
    void UpdateTime(void) {
        unsigned char tmp,tmp2;
        char i;

        // Fill In the LCD String
        time[0] = 'T';
        time[1] = 'i';
        time[2] = 'm';
        time[3] = 'e';
        time[4] = ':';
        time[5] = ' ';
        time[8] = ':';
        time[11] = ' ';
        time[13] = 'M';
        time[14] = ' ';
        time[15] = ' ';

        // Get Date
        comDate[0] = 'D';
        comDate[1] = 'a';
        comDate[2] = 't';
        comDate[3] = 'e';
        comDate[4] = ':';
        comDate[5] = ' ';
        comDate[8] = '/';
        comDate[11] = '/';
        comDate[14] = ' ';
        comDate[15] = ' ';

       // Get Minutes
        tmp = RTCRegRead(0x01);
        time[10] = (tmp & 0x0F) + 0x30;
        time[9] = (tmp >> 4) + 0x30;
       
        // Get Hours
        tmp = RTCRegRead(0x02);
        time[7] = (tmp & 0x0F) + 0x30;
        time[6] = ((tmp >> 4) & 0x01 ) + 0x30;

        // GET AM or PM (already read register 0x02)
        time[12] = ((tmp >> 4) & 0x01 ) + 0x30;

        if(time[12] == 0){
            time[12]='A';
        } else {
            time[12]='P';
        }

        //Get Month
        tmp = RTCRegRead(0x05);    
        comDate[6] = (tmp >> 4) + 0x30 ;
        comDate[7] = (tmp & 0x0F) + 0x30 ;

        //Get Date(day)
        tmp = RTCRegRead(0x04);    
        comDate[9] = (tmp >> 4) + 0x30 ;
        comDate[10] = (tmp & 0x0F) + 0x30 ;


        //Get Year
        tmp = RTCRegRead(0x06);    
        comDate[12] = (tmp >> 4) + 0x30 ;
        comDate[13] = (tmp & 0x0F) + 0x30 ;

        lcd_line(2);
        lcd_string(time);

        lcd_line(1);
        if(view == 0){
            lcd_string(company);
        } else {
            lcd_string(comDate);
        }

        decMonth = bcd2dec(RTCRegRead(0x05), 2);
        decDate  = bcd2dec(RTCRegRead(0x04), 0);
        decYear  = bcd2dec(RTCRegRead(0x06), 0);

        decHour  = bcd2dec(RTCRegRead(0x02),1);
        decMin   = bcd2dec(RTCRegRead(0x01),3);
        decAPM   = bcd2dec(RTCRegRead(0x05),0);
        decAPM   = (decAPM >> 4) & 0x01;
    }
    /**********************************
                Show Menu
    ***********************************/
    void ShowMenu(void){
    char MyButton = 0;
    char views = 1;
    myTmp = setupBtn;
    while(myTmp == setupBtn){myTmp = Button};

    while(1){

        MyButton = Button;

    lcd_line(1);
    lcd_string(SetStr);
    lcd_line(2);
        switch(views){
            case 1:
                lcd_string(TimeStr);
                break;
            case 2:
                lcd_string(DateStr);
                break;
            case 3:
                lcd_string(AlarmStr);
                break;
        }

        switch(MyButton){
            case upBtn:
                if(views>3)
                    views = 1;
                else
                    views++;
                break;
            case downBtn:
                if(views<1)
                    views = 3;
                else
                    views--;
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                switch(views){
                    case 1:
                        SetTime('t');
                        break;
                    case 2:
                         break;
                    case 3:
                       SetTime('a');
                       break;
                }
                break;
        }
       
        delay_ms(200);
    }
    }
    /**********************************
                Set the Time
    ***********************************/
    void SetTime(char type){
    char MyButton = 0;
    char views;
    myTmp = selectBtn;
    while(myTmp == selectBtn){myTmp = Button};

    views = 1;
    if(type == 't'){
        string2[0] = 'T';    
        string2[1] = 'i';
        string2[2] = 'm';
        string2[3] = 'e';
        string2[4] = ':';
        string2[5] = ' ';
    } else {
        string2[0] = 'A';    
        string2[1] = 'l';
        string2[2] = 'a';
        string2[3] = 'r';
        string2[4] = 'm';
        string2[5] = ':';
    }
        string2[6] = ' ';
        string2[9] = ':';
        string2[12] = ' ';
        string2[14] = 'M';
        string2[15] = ' ';

    while(1){

        MyButton = Button;

        switch(MyButton){
            case upBtn:
                switch(views){
                    case 1:
                        decHour++;
                        break;
                    case 2:
                        decMin++;
                        break;
                    case 3:
                        decAPM++;
                        break;
                }
                break;
            case downBtn:
                switch(views){
                    case 1:
                        decHour--;
                        break;
                    case 2:
                        decMin--;
                        break;
                    case 3:
                        decAPM--;
                        break;
                }
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                views++;
                break;
        }
     
        if(decHour > 12) decHour = 1;
        if(decHour <= 0) decHour = 12;
        if(decMin > 59) decMin = 0;
        if(decMin < 0) decMin = 59;
        if(decAPM > 2) decAPM = 0;
        if(decAPM < 0) decAPM = 1;

        //Minutes
        myTmp = uint2bcd(decMin);
        string2[10] = (myTmp >> 4) + 0x30;
        string2[11] = (myTmp & 0x0F) + 0x30;    

        //Hours
        myTmp = uint2bcd(decHour);
        string2[7] = ((myTmp >> 4) & 0x01) + 0x30;
        string2[8] = (myTmp & 0x0F) + 0x30;

        //AM-PM
        if(decAPM == 0)
            string2[13] = 'A';
        else
            string2[13] = 'P';

        switch(views){
            case 1:
                SetTA[9] = 'H';SetTA[10] = 'o';SetTA[11] = 'u';SetTA[12] = 'r';SetTA[13] = ' ';
                break;
            case 2:
                SetTA[9] = 'M';SetTA[10] = 'i';SetTA[11] = 'n';SetTA[12] = ' ';SetTA[13] = ' ';
                break;
            case 3:
                SetTA[9] = 'A';SetTA[10] = 'M';SetTA[11] = '/';SetTA[12] = 'P';SetTA[13] = 'M';
                break;
        }

        lcd_line(1);
        lcd_string(SetTA);
        lcd_line(2);
        lcd_string(string2);  
        delay_ms(200);

        if(views >= 4) break;

    }

        if(decAPM == 0)
            BcdHour = uint2bcd(decHour) | 0b01000000;
        else
            BcdHour = uint2bcd(decHour) | 0b01100000;

        BcdMin = uint2bcd(decMin) & 0b01111111;
        BcdSec = 0x00;

        if(type == 't'){
            RTCRegWrite(0x80,BcdSec);
            RTCRegWrite(0x81,BcdMin);
            RTCRegWrite(0x82,BcdHour);
        } else {
            RTCRegWrite(0x87,BcdSec);
            RTCRegWrite(0x88,BcdMin);
            RTCRegWrite(0x89,BcdHour);
            RTCRegWrite(0x8A,0x80);
        }

    }
       

    /**********************************
                Set the Date
    ***********************************/

    /**********************************
                Interrupt Code
    ***********************************/
    #pragma code low_vector=0x18
    void interrupt_at_low_vector(void)
    {
      _asm GOTO low_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interruptlow low_isr
    void low_isr (void)
    {
        myTmp = PORTB;
        UpdateTime();
        INTCON3 = 0x98;

    }


    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
      _asm GOTO high_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interrupt high_isr
    void high_isr (void)
    {
        myTmp = PORTB;
        alarmOut = 1;
        UpdateTime();
        RTCRegRead(0x07);  
        INTCON3 = 0x98;
    }

     
     
    Last edited: Dec 30, 2008
  3. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    compete Rev 2 code: (new schematic coming soon!):

    Code (text):

    /******************************************************************************
     *
     *          AtomSoft Clock Using PIC18F248, DS1306, 74LS164, 3v Buzzer
     *
     ******************************************************************************
     * FileName:        main.c
     * Author:          Jason Lopez
     * Processor:       PIC18F248(0)
     * Compiler:        C18
     * Company:         AtomSoftTech
     * Version:         2.0.0
     ******************************************************************************/
    #include <p18F248.h>
    #include <stdio.h>
    #include <delays.h>
    #include <spi.h>

    #pragma config WDT = OFF, LVP = OFF, OSC = HS
    /************************************
    Prototypes
    *************************************/
    void main(void);

    void initSPI(void);
    void e_togg(void);
    void lcd_line(char line);
    void lcd_cmd(unsigned char letter);
    void lcd_char(unsigned char letter);
    void lcd_string(char *senpoint);
    void lcd_init(void);
    void delay_ms(int mS);
    void delay_us(int uS);
    void delay_s(int S);
    void lcdByte(unsigned char dNyb,unsigned char rs);

    char RTCRegRead(char adx);
    void RTCRegWrite(char adx, char data);

    static unsigned char uint2bcd(unsigned char ival);
    char readBtn(void);
    unsigned char bcd2dec(unsigned char aBCD, char type);

    void putDate(char type, char data);

    void UpdateTime(void) ;
    void ShowMenu(void);
    void SetTime(char type);
    void low_isr(void);
    void high_isr(void);
    void SetDate(void);
    /************************************
    Definitions
    ************************************/
    #define CS LATCbits.LATC2
    #define CS_T  TRISCbits.TRISC2
    #define SCL_T TRISCbits.TRISC3
    #define SDA_T TRISCbits.TRISC4
    #define SDO_T TRISCbits.TRISC5

    #define LCD_DAT_T TRISCbits.TRISC0
    #define LCD_CLK_T TRISCbits.TRISC1

    #define LCD_DAT LATCbits.LATC0
    #define LCD_CLK LATCbits.LATC1

    #define LCD_E_T TRISCbits.TRISC6
    #define LCD_E   LATCbits.LATC6

    #define PL  LATBbits.LATB0
    #define CP2 LATBbits.LATB1
    #define SDL  PORTBbits.RB2

    #define PL_T   TRISBbits.TRISB0
    #define CP2_T  TRISBbits.TRISB1
    #define SDL_T  TRISBbits.TRISB2

    #define Button      (PORTA >> 1) & 0x0F;
    #define Button_T    TRISA    
    #define setupBtn    0x01
    #define downBtn     0x02
    #define upBtn       0x04
    #define selectBtn   0x08

    #define alarmOut  LATBbits.LATB3
    #define alarmOutT TRISBbits.TRISB3
    #define alarmIn_T   TRISBbits.TRISB1
    #define OneHz_T   TRISBbits.TRISB0
    /************************************
    Variables
    ************************************/
    char string[]       = "                ";
    char string2[]      = "                ";
    char company[]      = "  AtomSoftTech  ";
    char SetStr[]       = "    Settings    ";
    char SetTA[]        = " Adjust:        ";
    char TimeStr[]      = "1. Set Time     ";
    char DateStr[]      = "2. Set Date     ";
    char AlarmStr[]     = "3. Set Alarm    ";


    unsigned char lDate[16];
    unsigned char myTmp;
    //////////////////////////
    /*       NEW VARs       */
    //////////////////////////
    unsigned char decHour;
    unsigned char decMin;
    unsigned char decAPM;
    unsigned char BcdHour;
    unsigned char BcdMin;
    unsigned char BcdAPM;
    unsigned char BcdSec;

    unsigned char decDate;
    unsigned char decMonth;
    unsigned char decYear;
    unsigned char BcdDate;
    unsigned char BcdMonth;
    unsigned char BcdYear;


    unsigned char time[16];
    unsigned char comDate[16];
    unsigned char view;

    /************************************
    Main
    ************************************/
    void main(void) {

        ADCON1 = 0x0E;

        initSPI();
        lcd_init();

        SDL_T = 1;
        Button_T = 0xFF;    //TRISA (all input)

        RTCRegWrite(0x8F,0x05);

        alarmIn_T = 1;
        OneHz_T = 1;
        alarmOutT = 0;
        alarmOut = 0;

    /*  Interrupt Items  */
        RCON = 0x80;
        INTCON = 0xC0;
        INTCON2 = 0x80;
        INTCON3 = 0x98;

        UpdateTime();
        view = 0;
        RTCRegRead(0x07);
        while(1) {
            myTmp = Button;

            if(myTmp == selectBtn){
                if(view == 1){
                    lcd_string(company);
                    view = 0;
                } else {
                    lcd_string(comDate);
                    view = 1;
                }
                UpdateTime();
                while(myTmp == selectBtn){myTmp = Button};
            }

            if(myTmp == setupBtn){
                INTCON = 0x00;
                ShowMenu();
                UpdateTime();
                delay_s(1);
                INTCON = 0xC0;
            }
           
            if(myTmp == upBtn){
                alarmOut = 0;
            }    
        }
    }
    /***********************************
    RTC Tools
    ************************************
    Convert Char(byte) to BCD
    ************************************/
    unsigned char uint2bcd(unsigned char ival)
    {
        return ((ival / 10) << 4) | (ival % 10);
    }
    /************************************
    Convert BCD to Char(byte)
    ************************************/
    unsigned char bcd2dec(unsigned char aBCD, char type)
    {
        char lowNyb = aBCD & 0x0F;
        char highNyb = aBCD >> 4;
        char MyDec = lowNyb;
        char x;

        switch(type){
            case 0:
                highNyb &= 0x0F;
                break;
            case 1:
                highNyb &= 0x01;
                break;
            case 2:
                highNyb &= 0x03;
                break;
            case 3:
                highNyb &= 0x07;
                break;
            case 4:
                highNyb &= 0x00;
                break;
        }

        for(x=0;x<highNyb;x++){
            MyDec += 10;    
        }

        return MyDec;
    }
    /************************************
    Read a Register off the DS1306
    ************************************/
    char RTCRegRead(char adx){
        char tmp;
        CS = 1;
            WriteSPI(adx); //sec
            tmp = ReadSPI();
        CS = 0;

        return tmp;
    }
    /************************************
    Write to a Register on the DS1306
    ************************************/
    void RTCRegWrite(char adx, char data){
        CS = 1;
            WriteSPI((adx | 0x80 ));
            WriteSPI(data);
        CS = 0;
    }
    /************************************
    Initialize SPI
    ************************************/
    void initSPI(void){
        CS_T = 0;       //CS is output
        SCL_T = 0;      //SCL is output
        SDA_T = 1;      //SDA is input
        SDO_T = 0;      //SDO is output

        OpenSPI(SPI_FOSC_4,MODE_10,SMPEND);        

        CS = 1;
            WriteSPI(0x8F);
            WriteSPI(0x00);
        CS = 0;

    }
    /***********************************
    LCD Functions
    ************************************
    Send String to LCD
    ************************************/
    void lcd_string(char *senpoint){
        delay_ms(1);
        while(*senpoint != '\0'){
            lcd_char(*senpoint);
            senpoint++;
        }
    }
    /************************************
    Send Data(Nybble) to LCD
    ************************************/
    void lcdByte(unsigned char dNyb,unsigned char rs){
        int i;

        LCD_DAT=0;                          //Clear 74LS164 set initial bit to 0
        for(i=0;i<8;i++){                   //repeat for 8 bits
            LCD_CLK=1;LCD_CLK=0;            //write 0's to the 164
        }

        for(i=0;i<4;i++){                   //output the nybble
            if((dNyb & 0x08) != 0)
                LCD_DAT=1;
            else
                LCD_DAT=0;

            LCD_CLK=1;LCD_CLK=0;
            dNyb=dNyb<<1;
        }

        LCD_DAT = rs;                           //output the RS bit value
        LCD_CLK=1;LCD_CLK=0;

        LCD_DAT = 0;
        LCD_CLK=1;LCD_CLK=0;
        LCD_CLK=1;LCD_CLK=0;
        LCD_CLK=1;LCD_CLK=0;

        e_togg();
    }
    /************************************
    Toggle E Line
    ************************************/
    void e_togg(void){
        LCD_E=1;LCD_E=0;
    }
    /************************************
    Set LCD Line
    ************************************/
    void lcd_line(char line){
        if(line == 0x01)
            lcd_cmd(0x80);
        else
            lcd_cmd(0xc0);
    }
    /************************************
    LCD Send Command
    ************************************/
    void lcd_cmd(unsigned char letter){
        unsigned char temp;
        temp=letter;
        temp=temp>>4;
        lcdByte(temp,0);
        temp=letter;
        temp=temp&0x0f;
        lcdByte(temp,0);
    }
    /************************************
    LCD Send Character
    ************************************/
    void lcd_char(unsigned char letter){
        unsigned char temp;
        temp=letter;
        temp=temp>>4;
        lcdByte(temp,1);
        temp=letter;
        temp=temp&0x0f;
        lcdByte(temp,1);
    }
    /************************************
    LCD Initialization
    ************************************/
    void lcd_init(void){

        LCD_E_T = 0;
        LCD_CLK_T = 0;
        LCD_DAT_T = 0;

        lcdByte(0x03,0);
        delay_ms(5);
        e_togg();
        delay_us(160);
        e_togg();
        delay_us(160);
        lcdByte(0x02,0);
        delay_us(160);
        lcd_cmd(0x28);                  //set 4-bit mode and 2 lines
        delay_us(160);
        lcd_cmd(0x10);                  //cursor move & shift left
        delay_us(160);
        lcd_cmd(0x06);                  //entry mode = increment
        delay_us(160);
        lcd_cmd(0x0d);                  //display on - cursor blink on
        delay_us(160);
        lcd_cmd(0x01);                  //clear display
        delay_ms(500);
    }
    /************************************
    Delays (S,mS,uS) for 20Mhz
    ************************************/
    /*********************
        Delay Second(s)
    **********************/
    void delay_s(int S){
        int y;
        char x;

        for(y=0;y<S;y++)
            for(x=0;x<4;x++)
                delay_ms(250);

    }
    /************************
        Delay MilliSecond(s)
    *************************/
    void delay_ms(int mS){
        int y;

        for(y=0;y<mS;y++)
            Delay1KTCYx(5);
    }
    /************************
        Delay MicroSeconds
    *************************
    Lowercase 'u' is common
    symbol for Micro
    *************************/
    void delay_us(int uS){
        int y;
        char x;

        for(y=0;y<uS;y++)
            for(x=0;x<5;x++)
                Nop();
    }
    /**********************************
    readBtn
    ***********************************/
    char readBtn(void){
        char tmpA;
       
        tmpA = myTmp = Button;
        while(myTmp == tmpA){myTmp = Button};
     
        return tmpA;
    }
    /**********************************
    LCD / RTC stuff
    ***********************************/
    void UpdateTime(void) {
        unsigned char tmp,tmp2;
        char i;

        // Fill In the LCD String
        time[0] = 'T';
        time[1] = 'i';
        time[2] = 'm';
        time[3] = 'e';
        time[4] = ':';
        time[5] = ' ';
        time[8] = ':';
        time[11] = ' ';
        time[13] = 'M';
        time[14] = ' ';
        time[15] = ' ';

        // Get Date
        comDate[0] = 'D';
        comDate[1] = 'a';
        comDate[2] = 't';
        comDate[3] = 'e';
        comDate[4] = ':';
        comDate[5] = ' ';
        comDate[8] = '/';
        comDate[11] = '/';
        comDate[14] = ' ';
        comDate[15] = ' ';

       // Get Minutes
        tmp = RTCRegRead(0x01);
        time[10] = (tmp & 0x0F) + 0x30;
        time[9] = (tmp >> 4) + 0x30;
       
        // Get Hours
        tmp = RTCRegRead(0x02);
        time[7] = (tmp & 0x0F) + 0x30;
        time[6] = ((tmp >> 4) & 0x01 ) + 0x30;

        // GET AM or PM (already read register 0x02)
        time[12] = ((tmp >> 4) & 0x01 ) + 0x30;

        if(time[12] == 0){
            time[12]='A';
        } else {
            time[12]='P';
        }

        //Get Month
        tmp = RTCRegRead(0x05);    
        comDate[6] = (tmp >> 4) + 0x30 ;
        comDate[7] = (tmp & 0x0F) + 0x30 ;

        //Get Date(day)
        tmp = RTCRegRead(0x04);    
        comDate[9] = (tmp >> 4) + 0x30 ;
        comDate[10] = (tmp & 0x0F) + 0x30 ;


        //Get Year
        tmp = RTCRegRead(0x06);    
        comDate[12] = (tmp >> 4) + 0x30 ;
        comDate[13] = (tmp & 0x0F) + 0x30 ;

        lcd_line(2);
        lcd_string(time);

        lcd_line(1);
        if(view == 0){
            lcd_string(company);
        } else {
            lcd_string(comDate);
        }

        decMonth = bcd2dec(RTCRegRead(0x05), 2);
        decDate  = bcd2dec(RTCRegRead(0x04), 0);
        decYear  = bcd2dec(RTCRegRead(0x06), 0);

        decHour  = bcd2dec(RTCRegRead(0x02),1);
        decMin   = bcd2dec(RTCRegRead(0x01),3);
        decAPM   = bcd2dec(RTCRegRead(0x05),0);
        decAPM   = (decAPM >> 4) & 0x01;
    }
    /**********************************
                Show Menu
    ***********************************/
    void ShowMenu(void){
    char MyButton = 0;
    char views = 1;
    myTmp = setupBtn;
    while(myTmp == setupBtn){myTmp = Button};

    while(1){

        MyButton = Button;

    lcd_line(1);
    lcd_string(SetStr);
    lcd_line(2);
        switch(views){
            case 1:
                lcd_string(TimeStr);
                break;
            case 2:
                lcd_string(DateStr);
                break;
            case 3:
                lcd_string(AlarmStr);
                break;
        }

        switch(MyButton){
            case upBtn:
                if(views>3)
                    views = 1;
                else
                    views++;
                break;
            case downBtn:
                if(views<1)
                    views = 3;
                else
                    views--;
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                switch(views){
                    case 1:
                        SetTime('t');
                        break;

                    case 2:
                        SetDate();
                         break;
                    case 3:
                       SetTime('a');
                       break;
                }
                break;
        }
       
        delay_ms(200);
    }
    }
    /**********************************
                Set the Time
    ***********************************/
    void SetTime(char type){
    char MyButton = 0;
    char views;
    myTmp = selectBtn;
    while(myTmp == selectBtn){myTmp = Button};

    views = 1;
    if(type == 't'){
        string2[0] = 'T';    
        string2[1] = 'i';
        string2[2] = 'm';
        string2[3] = 'e';
        string2[4] = ':';
        string2[5] = ' ';
    } else {
        string2[0] = 'A';    
        string2[1] = 'l';
        string2[2] = 'a';
        string2[3] = 'r';
        string2[4] = 'm';
        string2[5] = ':';
    }
        string2[6] = ' ';
        string2[9] = ':';
        string2[12] = ' ';
        string2[14] = 'M';
        string2[15] = ' ';

    while(1){

        MyButton = Button;

        switch(MyButton){
            case upBtn:
                switch(views){
                    case 1:
                        decHour++;
                        break;
                    case 2:
                        decMin++;
                        break;
                    case 3:
                        decAPM++;
                        break;
                }
                break;
            case downBtn:
                switch(views){
                    case 1:
                        decHour--;
                        break;
                    case 2:
                        decMin--;
                        break;
                    case 3:
                        decAPM--;
                        break;
                }
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                views++;
                break;
        }
     
        if(decHour > 12) decHour = 1;
        if(decHour <= 0) decHour = 12;
        if(decMin > 59) decMin = 0;
        if(decMin < 0) decMin = 59;
        if(decAPM > 2) decAPM = 0;
        if(decAPM < 0) decAPM = 1;

        //Minutes
        myTmp = uint2bcd(decMin);
        string2[10] = (myTmp >> 4) + 0x30;
        string2[11] = (myTmp & 0x0F) + 0x30;    

        //Hours
        myTmp = uint2bcd(decHour);
        string2[7] = ((myTmp >> 4) & 0x01) + 0x30;
        string2[8] = (myTmp & 0x0F) + 0x30;

        //AM-PM
        if(decAPM == 0)
            string2[13] = 'A';
        else
            string2[13] = 'P';

        switch(views){
            case 1:
                SetTA[9] = 'H';SetTA[10] = 'o';SetTA[11] = 'u';SetTA[12] = 'r';SetTA[13] = ' ';
                break;
            case 2:
                SetTA[9] = 'M';SetTA[10] = 'i';SetTA[11] = 'n';SetTA[12] = ' ';SetTA[13] = ' ';
                break;
            case 3:
                SetTA[9] = 'A';SetTA[10] = 'M';SetTA[11] = '/';SetTA[12] = 'P';SetTA[13] = 'M';
                break;
        }

        lcd_line(1);
        lcd_string(SetTA);
        lcd_line(2);
        lcd_string(string2);  
        delay_ms(200);

        if(views >= 4) break;

    }

        if(decAPM == 0)
            BcdHour = uint2bcd(decHour) | 0b01000000;
        else
            BcdHour = uint2bcd(decHour) | 0b01100000;

        BcdMin = uint2bcd(decMin) & 0b01111111;
        BcdSec = 0x00;

        if(type == 't'){
            RTCRegWrite(0x80,BcdSec);
            RTCRegWrite(0x81,BcdMin);
            RTCRegWrite(0x82,BcdHour);
        } else {
            RTCRegWrite(0x87,BcdSec);
            RTCRegWrite(0x88,BcdMin);
            RTCRegWrite(0x89,BcdHour);
            RTCRegWrite(0x8A,0x80);
        }

    }
       

    /**********************************
                Set the Date
    ***********************************/
    void SetDate(void){
    char MyButton = 0;
    char views;
    myTmp = selectBtn;
    while(myTmp == selectBtn){myTmp = Button};

    views = 1;
        string2[0] = 'D';    
        string2[1] = 'a';
        string2[2] = 't';
        string2[3] = 'e';
        string2[4] = ':';
        string2[5] = ' ';

    while(1){

        MyButton = Button;

        switch(MyButton){
            case upBtn:
                switch(views){
                    case 1:
                        decMonth++;
                        break;
                    case 2:
                        decDate++;
                        break;
                    case 3:
                        decYear++;
                        break;
                }
                break;
            case downBtn:
                switch(views){
                    case 1:
                        decMonth--;
                        break;
                    case 2:
                        decDate--;
                        break;
                    case 3:
                        decYear--;
                        break;
                }
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                views++;
                break;
        }
     
        if(decYear > 99) decYear = 1;
        if(decYear <= 0) decYear = 99;
        if(decDate > 31) decDate = 1;
        if(decDate <= 0) decDate = 31;
        if(decMonth > 12) decMonth = 1;
        if(decMonth <= 0) decMonth = 12;

        //Month
        myTmp = uint2bcd(decMonth);
        string2[6] = (myTmp >> 4) + 0x30;
        string2[7] = (myTmp & 0x0F) + 0x30;    
        string2[8] = '/';

        //Date
        myTmp = uint2bcd(decDate);
        string2[9] = (myTmp >> 4) + 0x30;
        string2[10] = (myTmp & 0x0F) + 0x30;
        string2[11] = '/';

        //Year
        myTmp = uint2bcd(decYear);
        string2[12] = (myTmp >> 4) + 0x30;
        string2[13] = (myTmp & 0x0F) + 0x30;


        switch(views){
            case 1:
                SetTA[9] = 'M';SetTA[10] = 'o';SetTA[11] = 'n';SetTA[12] = 't';SetTA[13] = 'h';
                break;
            case 2:
                SetTA[9] = 'D';SetTA[10] = 'a';SetTA[11] = 't';SetTA[12] = 'e';SetTA[13] = ' ';
                break;
            case 3:
                SetTA[9] = 'Y';SetTA[10] = 'e';SetTA[11] = 'a';SetTA[12] = 'r';SetTA[13] = ' ';
                break;
        }

        lcd_line(1);
        lcd_string(SetTA);
        lcd_line(2);
        lcd_string(string2);  
        delay_ms(200);

        if(views >= 4) break;

    }

        BcdMonth = uint2bcd(decMonth);
        BcdDate  = uint2bcd(decDate);
        BcdYear  = uint2bcd(decYear);

            RTCRegWrite(0x85,BcdMonth);
            RTCRegWrite(0x84,BcdDate);
            RTCRegWrite(0x86,BcdYear);

    }
    /**********************************
                Interrupt Code
    ***********************************/
    #pragma code low_vector=0x18
    void interrupt_at_low_vector(void)
    {
      _asm GOTO low_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interruptlow low_isr
    void low_isr (void)
    {
        myTmp = PORTB;
        UpdateTime();
        INTCON3 = 0x98;

    }


    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
      _asm GOTO high_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interrupt high_isr
    void high_isr (void)
    {
        myTmp = PORTB;
        alarmOut = 1;
        UpdateTime();
        RTCRegRead(0x07);  
        INTCON3 = 0x98;
    }

     
     

    Attached Files:

    • rtc.png
      rtc.png
      File size:
      37.3 KB
      Views:
      87
    Last edited: Dec 30, 2008
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

    Here is a picture of it in prototype form. Ill post a video soon.

    EDIT: Video:
    [embed]http://www.youtube.com/v/VT9xQCN-DUo[/embed]
     

    Attached Files:

    Last edited: Jan 12, 2009
  6. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    New code with commented updates:(REV:3)
    Code (text):

    /******************************************************************************
     *
     *          AtomSoft Clock Using PIC18F248, DS1306, 74LS164
     *
     ******************************************************************************
     * FileName:        main.c
     * Author:          Jason Lopez
     * Processor:       PIC18F248(0)
     * Compiler:        C18
     * Company:         AtomSoftTech
     * Version/Rev:     3.0.0
     ******************************************************************************
        Changes in V3.
        1. Alarm Beeps 4 times a second and is in interrupt.
        2. Cleaned up code a bit.
        3. Fixed LCD string mistake in date.
        4. Finishing a Setup now takes you back to main menu.
        5. Insuring that the Alarm Flag is cleared:

           "IRQF0 is cleared when the address pointer goes to any of
            the Alarm 0 registers during a read or write"
     ******************************************************************************/
    #include <p18F248.h>
    #include <stdio.h>
    #include <delays.h>
    #include <spi.h>

    #pragma config WDT = OFF, LVP = OFF, OSC = HS
    /************************************
    Prototypes
    *************************************/
    void main(void);

    void initSPI(void);
    void e_togg(void);
    void lcd_line(char line);
    void lcd_cmd(unsigned char letter);
    void lcd_char(unsigned char letter);
    void lcd_string(char *senpoint);
    void lcd_init(void);
    void delay_ms(int mS);
    void delay_us(int uS);
    void delay_s(int S);
    void lcdByte(unsigned char dNyb,unsigned char rs);

    char RTCRegRead(char adx);
    void RTCRegWrite(char adx, char data);

    static unsigned char uint2bcd(unsigned char ival);
    char readBtn(void);
    unsigned char bcd2dec(unsigned char aBCD, char type);

    void putDate(char type, char data);

    void UpdateTime(void) ;
    void ShowMenu(void);
    void SetTime(char type);
    void low_isr(void);
    void high_isr(void);
    void SetDate(void);
    /************************************
    Definitions
    ************************************/
    #define CS LATCbits.LATC2
    #define CS_T  TRISCbits.TRISC2
    #define SCL_T TRISCbits.TRISC3
    #define SDA_T TRISCbits.TRISC4
    #define SDO_T TRISCbits.TRISC5

    #define LCD_DAT_T TRISCbits.TRISC0
    #define LCD_CLK_T TRISCbits.TRISC1

    #define LCD_DAT LATCbits.LATC0
    #define LCD_CLK LATCbits.LATC1

    #define LCD_E_T TRISCbits.TRISC6
    #define LCD_E   LATCbits.LATC6

    #define PL  LATBbits.LATB0
    #define CP2 LATBbits.LATB1
    #define SDL  PORTBbits.RB2

    #define PL_T   TRISBbits.TRISB0
    #define CP2_T  TRISBbits.TRISB1
    #define SDL_T  TRISBbits.TRISB2

    #define Button      (PORTA >> 1) & 0x0F;
    #define Button_T    TRISA    
    #define setupBtn    0x01
    #define downBtn     0x02
    #define upBtn       0x04
    #define selectBtn   0x08

    #define alarmOut  LATBbits.LATB3
    #define alarmOutT TRISBbits.TRISB3
    #define alarmIn_T   TRISBbits.TRISB1
    #define OneHz_T   TRISBbits.TRISB0
    /************************************
    Variables
    ************************************/
    char string[]       = "                ";
    char string2[]      = "                ";
    char company[]      = "  AtomSoftTech  ";
    char SetStr[]       = "    Settings    ";
    char SetTA[]        = " Adjust:        ";
    char TimeStr[]      = "1. Set Time     ";
    char DateStr[]      = "2. Set Date     ";
    char AlarmStr[]     = "3. Set Alarm    ";


    unsigned char lDate[16];
    unsigned char myTmp;
    //////////////////////////
    /*       NEW VARs       */
    //////////////////////////
    unsigned char decHour;
    unsigned char decMin;
    unsigned char decAPM;
    unsigned char BcdHour;
    unsigned char BcdMin;
    unsigned char BcdAPM;
    unsigned char BcdSec;

    unsigned char decDate;
    unsigned char decMonth;
    unsigned char decYear;
    unsigned char BcdDate;
    unsigned char BcdMonth;
    unsigned char BcdYear;


    unsigned char time[16];
    unsigned char comDate[16];
    unsigned char view;

    unsigned char AlarmSet;
    /************************************
    Main
    ************************************/
    void main(void) {
        char x;

        AlarmSet = 0;
        ADCON1 = 0x0E;

        initSPI();
        lcd_init();

        SDL_T = 1;
        Button_T = 0xFF;    //TRISA (all input)

        RTCRegWrite(0x8F,0x05);

        alarmIn_T = 1;
        OneHz_T = 1;
        alarmOutT = 0;
        alarmOut = 0;

    /*  Interrupt Items  */
        RCON = 0x80;
        INTCON = 0xC0;
        INTCON2 = 0x80;
        INTCON3 = 0x98;

        UpdateTime();
        view = 0;

        while(1) {
            myTmp = Button;

            if(myTmp == selectBtn){
                if(view == 1){
                    lcd_string(company);
                    view = 0;
                } else {
                    lcd_string(comDate);
                    view = 1;
                }
                UpdateTime();
                while(myTmp == selectBtn){myTmp = Button};
            }

            if(myTmp == setupBtn){
                INTCON = 0x00;
                ShowMenu();
                UpdateTime();
                delay_s(1);
                INTCON = 0xC0;
            }
           
            if(myTmp > 0x00){
                alarmOut = 0;
                AlarmSet = 0;
                myTmp = RTCRegRead(0x0A);       //Clear the flag in DS1306 (IRQF0)
            }  
        }
    }
    /***********************************
    RTC Tools
    ************************************
    Convert Char(byte) to BCD
    ************************************/
    unsigned char uint2bcd(unsigned char ival)
    {
        return ((ival / 10) << 4) | (ival % 10);
    }
    /************************************
    Convert BCD to Char(byte)
    ************************************/
    unsigned char bcd2dec(unsigned char aBCD, char type)
    {
        char lowNyb = aBCD & 0x0F;
        char highNyb = aBCD >> 4;
        char MyDec = lowNyb;
        char x;

        switch(type){
            case 0:
                highNyb &= 0x0F;
                break;
            case 1:
                highNyb &= 0x01;
                break;
            case 2:
                highNyb &= 0x03;
                break;
            case 3:
                highNyb &= 0x07;
                break;
            case 4:
                highNyb &= 0x00;
                break;
        }

        for(x=0;x<highNyb;x++){
            MyDec += 10;    
        }

        return MyDec;
    }
    /************************************
    Read a Register off the DS1306
    ************************************/
    char RTCRegRead(char adx){
        char tmp;
        CS = 1;
            WriteSPI(adx); //sec
            tmp = ReadSPI();
        CS = 0;

        return tmp;
    }
    /************************************
    Write to a Register on the DS1306
    ************************************/
    void RTCRegWrite(char adx, char data){
        CS = 1;
            WriteSPI((adx | 0x80 ));
            WriteSPI(data);
        CS = 0;
    }
    /************************************
    Initialize SPI
    ************************************/
    void initSPI(void){
        CS_T = 0;       //CS is output
        SCL_T = 0;      //SCL is output
        SDA_T = 1;      //SDA is input
        SDO_T = 0;      //SDO is output

        OpenSPI(SPI_FOSC_4,MODE_10,SMPEND);        

        CS = 1;
            WriteSPI(0x8F);
            WriteSPI(0x00);
        CS = 0;

    }
    /***********************************
    LCD Functions
    ************************************
    Send String to LCD
    ************************************/
    void lcd_string(char *senpoint){
        delay_ms(1);
        while(*senpoint != '\0'){
            lcd_char(*senpoint);
            senpoint++;
        }
    }
    /************************************
    Send Data(Nybble) to LCD
    ************************************/
    void lcdByte(unsigned char dNyb,unsigned char rs){
        int i;

        LCD_DAT=0;                          //Clear 74LS164 set initial bit to 0
        for(i=0;i<8;i++){                   //repeat for 8 bits
            LCD_CLK=1;LCD_CLK=0;            //write 0's to the 164
        }

        for(i=0;i<4;i++){                   //output the nybble
            if((dNyb & 0x08) != 0)
                LCD_DAT=1;
            else
                LCD_DAT=0;

            LCD_CLK=1;LCD_CLK=0;
            dNyb=dNyb<<1;
        }

        LCD_DAT = rs;                           //output the RS bit value
        LCD_CLK=1;LCD_CLK=0;

        LCD_DAT = 0;
        LCD_CLK=1;LCD_CLK=0;
        LCD_CLK=1;LCD_CLK=0;
        LCD_CLK=1;LCD_CLK=0;

        e_togg();
    }
    /************************************
    Toggle E Line
    ************************************/
    void e_togg(void){
        LCD_E=1;LCD_E=0;
    }
    /************************************
    Set LCD Line
    ************************************/
    void lcd_line(char line){
        if(line == 0x01)
            lcd_cmd(0x80);
        else
            lcd_cmd(0xc0);
    }
    /************************************
    LCD Send Command
    ************************************/
    void lcd_cmd(unsigned char letter){
        unsigned char temp;
        temp=letter;
        temp=temp>>4;
        lcdByte(temp,0);
        temp=letter;
        temp=temp&0x0f;
        lcdByte(temp,0);
    }
    /************************************
    LCD Send Character
    ************************************/
    void lcd_char(unsigned char letter){
        unsigned char temp;
        temp=letter;
        temp=temp>>4;
        lcdByte(temp,1);
        temp=letter;
        temp=temp&0x0f;
        lcdByte(temp,1);
    }
    /************************************
    LCD Initialization
    ************************************/
    void lcd_init(void){

        LCD_E_T = 0;
        LCD_CLK_T = 0;
        LCD_DAT_T = 0;

        lcdByte(0x03,0);
        delay_ms(5);
        e_togg();
        delay_us(160);
        e_togg();
        delay_us(160);
        lcdByte(0x02,0);
        delay_us(160);
        lcd_cmd(0x28);                  //set 4-bit mode and 2 lines
        delay_us(160);
        lcd_cmd(0x10);                  //cursor move & shift left
        delay_us(160);
        lcd_cmd(0x06);                  //entry mode = increment
        delay_us(160);
        lcd_cmd(0x0d);                  //display on - cursor blink on
        delay_us(160);
        lcd_cmd(0x01);                  //clear display
        delay_ms(500);
    }
    /************************************
    Delays (S,mS,uS) for 20Mhz
    ************************************/
    /*********************
        Delay Second(s)
    **********************/
    void delay_s(int S){
        int y;
        char x;

        for(y=0;y<S;y++)
            for(x=0;x<4;x++)
                delay_ms(250);

    }
    /************************
        Delay MilliSecond(s)
    *************************/
    void delay_ms(int mS){
        int y;

        for(y=0;y<mS;y++)
            Delay1KTCYx(5);
    }
    /************************
        Delay MicroSeconds
    *************************
    Lowercase 'u' is common
    symbol for Micro
    *************************/
    void delay_us(int uS){
        int y;
        char x;

        for(y=0;y<uS;y++)
            for(x=0;x<5;x++)
                Nop();
    }
    /**********************************
    readBtn
    ***********************************/
    char readBtn(void){
        char tmpA;
       
        tmpA = myTmp = Button;
        while(myTmp == tmpA){myTmp = Button};
     
        return tmpA;
    }
    /**********************************
    LCD / RTC stuff
    ***********************************/
    void UpdateTime(void) {
        unsigned char tmp,tmp2;
        char i;

        // Fill In the LCD String
        time[0] = 'T';
        time[1] = 'i';
        time[2] = 'm';
        time[3] = 'e';
        time[4] = ':';
        time[5] = ' ';
        time[8] = ':';
        time[11] = ' ';
        time[13] = 'M';
        time[14] = ' ';
        time[15] = ' ';

        // Get Date
        comDate[0] = 'D';
        comDate[1] = 'a';
        comDate[2] = 't';
        comDate[3] = 'e';
        comDate[4] = ':';
        comDate[5] = ' ';
        comDate[8] = '/';
        comDate[11] = '/';
        comDate[14] = ' ';
        comDate[15] = ' ';

       // Get Minutes
        tmp = RTCRegRead(0x01);
        time[10] = (tmp & 0x0F) + 0x30;
        time[9] = (tmp >> 4) + 0x30;
       
        // Get Hours
        tmp = RTCRegRead(0x02);
        time[7] = (tmp & 0x0F) + 0x30;
        time[6] = ((tmp >> 4) & 0x01 ) + 0x30;

        // GET AM or PM (already read register 0x02)
        time[12] = (tmp >> 4) & 0x02;

        if(time[12] == 0){
            time[12]='A';
        } else {
            time[12]='P';
        }

        //Get Month
        tmp = RTCRegRead(0x05);    
        comDate[6] = (tmp >> 4) + 0x30 ;
        comDate[7] = (tmp & 0x0F) + 0x30 ;

        //Get Date(day)
        tmp = RTCRegRead(0x04);    
        comDate[9] = (tmp >> 4) + 0x30 ;
        comDate[10] = (tmp & 0x0F) + 0x30 ;


        //Get Year
        tmp = RTCRegRead(0x06);    
        comDate[12] = (tmp >> 4) + 0x30 ;
        comDate[13] = (tmp & 0x0F) + 0x30 ;

        lcd_line(2);
        lcd_string(time);

        lcd_line(1);
        if(view == 0){
            lcd_string(company);
        } else {
            lcd_string(comDate);
        }

        decMonth = bcd2dec(RTCRegRead(0x05), 2);
        decDate  = bcd2dec(RTCRegRead(0x04), 0);
        decYear  = bcd2dec(RTCRegRead(0x06), 0);

        decHour  = bcd2dec(RTCRegRead(0x02),1);
        decMin   = bcd2dec(RTCRegRead(0x01),3);
        decAPM   = bcd2dec(RTCRegRead(0x05),0);
        decAPM   = (decAPM >> 5) & 0x01;
    }
    /**********************************
                Show Menu
    ***********************************/
    void ShowMenu(void){
    char MyButton = 0;
    char views = 1;
    myTmp = setupBtn;
    while(myTmp == setupBtn){myTmp = Button};

    while(1){

        MyButton = Button;

    lcd_line(1);
    lcd_string(SetStr);
    lcd_line(2);
        switch(views){
            case 1:
                lcd_string(TimeStr);
                break;
            case 2:
                lcd_string(DateStr);
                break;
            case 3:
                lcd_string(AlarmStr);
                break;
        }

        switch(MyButton){
            case upBtn:
                if(views>3)
                    views = 1;
                else
                    views++;
                break;
            case downBtn:
                if(views<1)
                    views = 3;
                else
                    views--;
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                switch(views){
                    case 1:
                        SetTime('t');
                        break;
                    case 2:
                        SetDate();
                         break;
                    case 3:
                        SetTime('a');
                        break;
                }
                break;
        }
       
        delay_ms(200);
    }
    }
    /**********************************
                Set the Time
    ***********************************/
    void SetTime(char type){
    char MyButton = 0;
    char views;
    myTmp = selectBtn;
    while(myTmp == selectBtn){myTmp = Button};

    views = 1;
    if(type == 't'){
        string2[0] = 'T';    
        string2[1] = 'i';
        string2[2] = 'm';
        string2[3] = 'e';
        string2[4] = ':';
        string2[5] = ' ';
    } else {
        string2[0] = 'A';    
        string2[1] = 'l';
        string2[2] = 'a';
        string2[3] = 'r';
        string2[4] = 'm';
        string2[5] = ':';
    }
        string2[6] = ' ';
        string2[9] = ':';
        string2[12] = ' ';
        string2[14] = 'M';
        string2[15] = ' ';

    while(1){

        MyButton = Button;

        switch(MyButton){
            case upBtn:
                switch(views){
                    case 1:
                        decHour++;
                        break;
                    case 2:
                        decMin++;
                        break;
                    case 3:
                        decAPM++;
                        break;
                }
                break;
            case downBtn:
                switch(views){
                    case 1:
                        decHour--;
                        break;
                    case 2:
                        decMin--;
                        break;
                    case 3:
                        decAPM--;
                        break;
                }
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                views++;
                break;
        }
     
        if(decHour > 12) decHour = 1;
        if(decHour <= 0) decHour = 12;
        if(decMin > 59) decMin = 0;
        if(decMin < 0) decMin = 59;
        if(decAPM > 1) decAPM = 0;
        if(decAPM < 0) decAPM = 1;

        //Minutes
        myTmp = uint2bcd(decMin);
        string2[10] = (myTmp >> 4) + 0x30;
        string2[11] = (myTmp & 0x0F) + 0x30;    

        //Hours
        myTmp = uint2bcd(decHour);
        string2[7] = ((myTmp >> 4) & 0x01) + 0x30;
        string2[8] = (myTmp & 0x0F) + 0x30;

        //AM-PM
        if(decAPM == 0)
            string2[13] = 'A';
        else
            string2[13] = 'P';

        switch(views){
            case 1:
                SetTA[9] = 'H';SetTA[10] = 'o';SetTA[11] = 'u';SetTA[12] = 'r';SetTA[13] = ' ';
                break;
            case 2:
                SetTA[9] = 'M';SetTA[10] = 'i';SetTA[11] = 'n';SetTA[12] = ' ';SetTA[13] = ' ';
                break;
            case 3:
                SetTA[9] = 'A';SetTA[10] = 'M';SetTA[11] = '/';SetTA[12] = 'P';SetTA[13] = 'M';
                break;
        }

        lcd_line(1);
        lcd_string(SetTA);
        lcd_line(2);
        lcd_string(string2);  
        delay_ms(200);

        if(views >= 4) break;

    }

        if(decAPM == 0)
            BcdHour = uint2bcd(decHour) | 0b01000000;
        else
            BcdHour = uint2bcd(decHour) | 0b01100000;

        BcdMin = uint2bcd(decMin) & 0b01111111;
        BcdSec = 0x00;

        if(type == 't'){
            RTCRegWrite(0x80,BcdSec);
            RTCRegWrite(0x81,BcdMin);
            RTCRegWrite(0x82,BcdHour);
        } else {
            RTCRegWrite(0x87,BcdSec);
            RTCRegWrite(0x88,BcdMin);
            RTCRegWrite(0x89,BcdHour);
            RTCRegWrite(0x8A,0x80);
        }

    }
       

    /**********************************
                Set the Date
    ***********************************/
    void SetDate(void){
    char MyButton = 0;
    char views;
    myTmp = selectBtn;
    while(myTmp == selectBtn){myTmp = Button};

    views = 1;
        string2[0] = 'D';    
        string2[1] = 'a';
        string2[2] = 't';
        string2[3] = 'e';
        string2[4] = ':';
        string2[5] = ' ';

    while(1){

        MyButton = Button;

        switch(MyButton){
            case upBtn:
                switch(views){
                    case 1:
                        decMonth++;
                        break;
                    case 2:
                        decDate++;
                        break;
                    case 3:
                        decYear++;
                        break;
                }
                break;
            case downBtn:
                switch(views){
                    case 1:
                        decMonth--;
                        break;
                    case 2:
                        decDate--;
                        break;
                    case 3:
                        decYear--;
                        break;
                }
                break;
            case setupBtn:
                return;
                break;
            case selectBtn:
                views++;
                break;
        }
     
        if(decYear > 99) decYear = 1;
        if(decYear <= 0) decYear = 99;
        if(decDate > 31) decDate = 1;
        if(decDate <= 0) decDate = 31;
        if(decMonth > 12) decMonth = 1;
        if(decMonth <= 0) decMonth = 12;

        //Month
        myTmp = uint2bcd(decMonth);
        string2[6] = (myTmp >> 4) + 0x30;
        string2[7] = (myTmp & 0x0F) + 0x30;    
        string2[8] = '/';

        //Date
        myTmp = uint2bcd(decDate);
        string2[9] = (myTmp >> 4) + 0x30;
        string2[10] = (myTmp & 0x0F) + 0x30;
        string2[11] = '/';

        //Year
        myTmp = uint2bcd(decYear);
        string2[12] = (myTmp >> 4) + 0x30;
        string2[13] = (myTmp & 0x0F) + 0x30;
        string2[14] = string2[15] = ' ';        //String FIX! in Rev. 3


        switch(views){
            case 1:
                SetTA[9] = 'M';SetTA[10] = 'o';SetTA[11] = 'n';SetTA[12] = 't';SetTA[13] = 'h';
                break;
            case 2:
                SetTA[9] = 'D';SetTA[10] = 'a';SetTA[11] = 't';SetTA[12] = 'e';SetTA[13] = ' ';
                break;
            case 3:
                SetTA[9] = 'Y';SetTA[10] = 'e';SetTA[11] = 'a';SetTA[12] = 'r';SetTA[13] = ' ';
                break;
        }

        lcd_line(1);
        lcd_string(SetTA);
        lcd_line(2);
        lcd_string(string2);  
        delay_ms(200);

        if(views >= 4) break;

    }

        BcdMonth = uint2bcd(decMonth);
        BcdDate  = uint2bcd(decDate);
        BcdYear  = uint2bcd(decYear);

            RTCRegWrite(0x85,BcdMonth);
            RTCRegWrite(0x84,BcdDate);
            RTCRegWrite(0x86,BcdYear);

    }
    /**********************************
                Interrupt Code
    ***********************************/
    #pragma code low_vector=0x18
    void interrupt_at_low_vector(void)
    {
      _asm GOTO low_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interruptlow low_isr
    void low_isr (void)
    {
        char x;
        if(AlarmSet == 1){
           for(x=0;x<4;x++){
                alarmOut = 1;
                delay_ms(100);
                alarmOut = 0;
                delay_ms(100);
            }
        }  
        myTmp = PORTB;
        UpdateTime();
        INTCON3 = 0x98;

    }


    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
      _asm GOTO high_isr _endasm
    }
    #pragma code /* return to the default code section */
    #pragma interrupt high_isr
    void high_isr (void)
    {
        myTmp = PORTB;
        AlarmSet = 1;
        UpdateTime();
        RTCRegRead(0x07);  
        INTCON3 = 0x98;
    }

     
     
    Last edited: Jan 12, 2009
  7. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    here is a better picture.. my camera came in yay! i took a nice picture of a IC also to test the depth of the picture lol
     

    Attached Files:

  8. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Excellent! What camera did you get?

    What's all the mung in the IC macro photo? :D That's a dirty, dirty breadboard. It looks like you been eating crackers over it. :p

    Mine always have cat hair when I zoom in close.
     
  9. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
  10. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Unidentified icky stuff?

    Nice price on the camera. Would make a good "beater" for places I don't want to take my good camera. Decent macro shots.
     
  11. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    yeah it said 5cm but that was about 3cm distance. It does awesome nice video also. (mainly of people) Close up video is decent. Ill post something on youtube in a minute
     
    Last edited: Feb 3, 2009
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    I updated the blog it now has a sample video of the SD stuff.

    I will be doing that blog starting tomorrow or the day after.
     
  13. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    You have inspired me :) Santa brought me a Samsung L200. Up to now I have not taken the time to mess with more then point and shoot. You closeup looked so good I had to give it a try. The auto focus in close is a bit hit and miss. I did not manage to get in as close as yours. Good work :)

    Up to now I had left the bit of clingy plastic covering the LCD. It made a nice but foggy protector.

    3v0
     

    Attached Files:

    Last edited: Feb 3, 2009
  14. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
  16. premkumar9

    premkumar9 Member

    Joined:
    Oct 28, 2008
    Messages:
    513
    Likes:
    1
    Location:
    India
    I used DS1307 earlier with 89C2051 MC and it worked displaying clock and calendar. That was a few years back. Now I have been going through it again . I could write to DS1307 and read and display the contents. But the clock is not running itself. I made the CH bit 0. Can you give me any other hint. I am just on that job
     
  17. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,199
    Likes:
    640
    Location:
    Derbyshire, UK
  18. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    i dont want to kill the sites bandwidth. If i was to post so many pictures on the site it would increase its bandwidth and may increase or help to create that issue.


    premkumar9: I have used some other clocks but never the DS1307 ill check the datasheet and see what you are refering to.

    But can you please explain it better.

    EDIT
    It sounds like you have a OSC issue. Are you sure the Crystal is good?
     
    Last edited: Feb 4, 2009
  19. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,199
    Likes:
    640
    Location:
    Derbyshire, UK
    A few pictures aren't going to cause any problems :D

    By posting external links it means the pictures will disappear, making nonsense of the posts.
     
  20. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    ive had pictures on photobucket for years now. I dont think they are leaving anytime soon :D But I always keep the images on my PC anyway even if crap. So i can replace em in the future :)
     
  21. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    I understand what you are saying but.

    Who knows how long photobucket will be around. They could close up shop without notice. If you are anything like me I would not have a lot of motivation to search for all my posts with attachments, find the right image on my PC and upload them.

    In the end Nigel is correct.

    3v0
     

Share This Page