13 Ekim 2017 Cuma

Adjustable Clock DS1307

We learned how to read and set DS1307 clock in our previous examples. We will develop an adjustable clock in this example. There are three buttons SET, UP, DOWN as you see on commercial digital clocks. SET button will select and blink  hour and minutes sequentially.  UP,DOWN buttons will increment or decrement hours or minutes.

Proteus: DS1307 with a crystal. LCD is connected to PORTB. RA0, RA1,RA2 are used for setting buttons.


MCC: nothing special. RA0,RA1,RA2 is set for input. select MSSP, I2C master, 1Khz. 1Mhz internal oscillator.





XC8: Enable global and peripheral interrupts. First set clock to 03:02:01 we will not use day, month year but I set them, too. read DS1307 and print to LCD. In case of SET button pressed, set seconds to zero and check UP/DOWN buttons. If up/down buttons are pressed change hour/minutes. Second SET button will switch to minutes and third SET button will set the clock.

I converted DS1307 BCD values to decimal for math operations and turned back to BCD again for register setting.  

    
    unsigned char s1[10], s2[10];
    uint8_t hr[2]={1,0}, readValue[7], writeValue[8]={0,1,2,3,4,5,6,7};
    uint8_t c,ho,mi,se,da,mo,ye;
    I2C_MESSAGE_STATUS    I2C_status;
    
    I2C_MasterWrite( &writeValue, 8, 0b1101000, &I2C_status); //sets pointer address and write data
    while (I2C_MESSAGE_PENDING  == I2C_status ); 

    
    OpenXLCD(FOUR_BIT & LINES_5X7);
    WriteCmdXLCD(DON&CURSOR_OFF&BLINK_OFF); 
    

    while (1)
    {
        // Add your application code
        
    I2C_MasterWrite( 0, 1, 0b1101000, &I2C_status); //set pointer address to zero
    while (I2C_MESSAGE_PENDING  == I2C_status);
    I2C_MasterRead( &readValue, 7, 0b1101000, &I2C_status); // read 7 bytes starting from zero
    while (I2C_MESSAGE_PENDING  == I2C_status );

    sprintf(s1, "%02X:%02X:%02X", readValue[2],readValue[1],readValue[0]);             
        
    SetDDRamAddr(0x01); // clear LCD          
    SetDDRamAddr(0x00); // first line 
    putrsXLCD(s1);        
    SetDDRamAddr(0x40); // goto second line
    putrsXLCD(s2);
    
    writeValue[0]=0;  //pointer address of zero 
    writeValue[1]=readValue[0]; //sec
    writeValue[2]=readValue[1]; //min
    writeValue[3]=readValue[2]; //hour
    writeValue[4]=readValue[3]; //weekday
    writeValue[5]=readValue[4]; //day
    writeValue[6]=readValue[5]; //month
    writeValue[7]=readValue[6]; //year
        
    ho=readValue[2]; mi=readValue[1]; se=readValue[0];
    da=readValue[4]; mo=readValue[5]; ye=readValue[6];
    
    c=0;
    if (IO_RA0_GetValue()==1) { //set pressed
    c=(c+1) % 3;   // set value 0=no-set,1=hour,2=minutes
    
    while (c==1){ //set hours    

        
    writeValue[1]=0; //set seconds to zero
    
    ho=(ho>>4)*10+(ho&0x0F); //bcd2dec
    if (IO_RA1_GetValue()==1) ho=(ho+1) % 24; //up
    if (IO_RA2_GetValue()==1) ho=(ho+23) % 24; //down
    ho=((ho/10)<<4)+(ho%10); //dec2bcd
    writeValue[3]=ho;
    
    sprintf(s1, "%02X:%02X:%02X", ho,mi,0);             
    SetDDRamAddr(0x01); // clear LCD          
    SetDDRamAddr(0x00); // first line 
    putrsXLCD(s1);        
    __delay_ms(100);
    
    sprintf(s1, "  :%02X:%02X",mi,0);             
    SetDDRamAddr(0x01); // clear LCD          
    SetDDRamAddr(0x00); // first line 
    putrsXLCD(s1);        
    __delay_ms(100);
    
    
    if (IO_RA0_GetValue()==1) { //set pressed
        c=(c+1) % 3;
        I2C_MasterWrite( &writeValue, 8, 0b1101000, &I2C_status); //sets pointer address and write data
        while (I2C_MESSAGE_PENDING  == I2C_status ); 
    }
    }

    while (c==2){ //set minutes       
    mi=(mi>>4)*10+(mi&0x0F); //bcd2dec
    if (IO_RA1_GetValue()==1) mi=(mi+1) % 60; //up
    if (IO_RA2_GetValue()==1) mi=(mi+59) % 60; //down
    mi=((mi/10)<<4)+(mi%10); //dec2bcd
    writeValue[2]=mi; 
    
    sprintf(s1, "%02X:%02X:%02X", ho,mi,0);             
    SetDDRamAddr(0x01); // clear LCD          
    SetDDRamAddr(0x00); // first line 
    putrsXLCD(s1);        
    __delay_ms(100);
    
    sprintf(s1, "%02X:  :%02X",ho,0);             
    SetDDRamAddr(0x01); // clear LCD          
    SetDDRamAddr(0x00); // first line 
    putrsXLCD(s1);        
    __delay_ms(100);
    
   if (IO_RA0_GetValue()==1){ 
        c=(c+1) % 3;
        I2C_MasterWrite( &writeValue, 8, 0b1101000, &I2C_status); //sets pointer address and write data
        while (I2C_MESSAGE_PENDING  == I2C_status ); 

    }

    }    
    }
        
        __delay_ms(1000);
    }
    



1 yorum:

  1. Learning Pic Programing With Xc8 Compiler: Adjustable Clock Ds1307 >>>>> Download Now

    >>>>> Download Full

    Learning Pic Programing With Xc8 Compiler: Adjustable Clock Ds1307 >>>>> Download LINK

    >>>>> Download Now

    Learning Pic Programing With Xc8 Compiler: Adjustable Clock Ds1307 >>>>> Download Full

    >>>>> Download LINK zV

    YanıtlaSil