Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Digital Clock PIC16F628A + RTC DS1307 + 7 Segment Multiplexing Problem..

Status
Not open for further replies.

asking

Full Member level 5
Full Member level 5
Joined
Sep 21, 2010
Messages
279
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,298
Activity points
3,377
I tried to modify the LCD clock circuit and tried to multiplex the out into 7 Segment. So here i have combined 2 circuits to make 1 Digital 7 segment circuit. But m confused about PORT A.6 and A.7 Pins as this pins are used for I2C Connection they should be I/o Pins... But how to make only those 2 pins as input/output ? Because my Port A0-A3 are used for Display Refresh multiplexing so they're consider as only outputs...

i have tried to run code and attached proteus circuit file but its not working.... please suggest whats wrong ?

Here the count = 1234 i write i get on display 1234 so what i did is count = hour*100 + minute so whatever output from DS1307 it will be display on 7 segment... please correct me if m wrong... Still i have not implemented time set i was just starting and i got error...so please help


Code:
unsigned short i, DD0, DD1, DD2, DD3;
unsigned int Count, hour, minute;
//------ Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
 switch (num) {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
 } //case end
}
 // Software I2C connections
sbit Soft_I2C_Scl           at RA6_bit;
sbit Soft_I2C_Sda           at RA7_bit;
sbit Soft_I2C_Scl_Direction at TRISA6_bit;
sbit Soft_I2C_Sda_Direction at TRISA7_bit;
// End Software I2C connections
// this is my programming part 1

unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  Soft_I2C_Start();
  Soft_I2C_Write(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(address);
  Soft_I2C_Start();
  Soft_I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=Soft_I2C_Read(0);
  Soft_I2C_Stop();
  return(r_data);
}

void write_ds1307(unsigned short address,unsigned short w_data)
{
  Soft_I2C_Start(); // issue I2C start signal
  //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(0xD0); // send byte via I2C (device address + W)
  Soft_I2C_Write(address); // send byte (address of DS1307 location)
  Soft_I2C_Write(w_data); // send data (data to be written)
  Soft_I2C_Stop(); // issue I2C stop signal
}

void main()
{
  Soft_I2C_Init();
  minute = read_ds1307(1);
  hour = read_ds1307(2);
  CMCON  |= 7;        // Disable Comparators
  TRISB = 0xff; // Set PORTB7 input all other direction to be output
  PORTB = 0xff;    // Turn OFF LEDs on PORTB
  TRISA = 0b11100000; // RA5-6-7 is input only


  do {
  DD0 = Count%10;  // Extract Ones Digit
  DD0 = mask(DD0);
  DD1 = (Count/10)%10; // Extract Tens Digit
  DD1 = mask(DD1);
  DD2 = (Count/100)%10; // Extract Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (Count/1000);  // Extract Thousands Digit
  DD3 = mask(DD3);

  for (i = 0; i<=50; i++) {


      RA3_bit = 1;                //disable RA3
      PORTB = DD0;
      RA0_bit = 0;      // Select Ones Digit
      RA1_bit = 1;
      RA2_bit = 1;
      delay_ms(5);

      RA0_bit = 1;                //disable RA0
      PORTB = DD1;
      RA1_bit = 0;     // Select Tens Digit
      RA2_bit = 1;
      RA3_bit = 1;
      delay_ms(5);

      RA1_bit = 1;                //disable RA1
      PORTB = DD2;
      RA0_bit = 1;
      RA2_bit = 0;     // Select Hundreds Digit
      RA3_bit = 1;
      delay_ms(5);

      RA2_bit = 1;                //disable RA2
      PORTB   = DD3;
      RA0_bit = 1;
      RA1_bit = 1;
      RA3_bit = 0;     // Select Thousands Digit
      delay_ms(5);
      }
      
      Count = hour*100 + minute;

     } while(1);
}

           // endless loop
 

Attachments

  • Digital Clock.zip
    20.9 KB · Views: 204

Code:
 DD0 = Count%10;  // Extract Ones Digit
  DD0 = mask(DD0);
  DD1 = (Count/10)%10; // Extract Tens Digit
  DD1 = mask(DD1);
  DD2 = (Count/100)%10; // Extract Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (Count/1000);  // Extract Thousands Digit
  DD3 = mask(DD3);


change this codes please. ds1307 stores minutes and hours data in bcd format. first read them from ds1307 and convert them from bcd to integer.

a example come for you

Code:
int bcd2int(int BCD){return(BCD>>4)*10+(BCD&0x0F);}
 

How to convert it using Mikroc ? but as far as i know...7 Segment works on Binary Values or HEX Code...so why not to convert BCD to direct Hex code ? please suggest something...regarding..it
 

read the datasheet of ds1307. you will see that at it holds minutes at 0x01h address. the lower 4 bits for minutes and the other 3 bits for 10 minutes. and the last bit is empty.

after you read minute data from ds1307, you must reformat it.
Code:
Do{
minute=(minute>>4)*10+(minute&0x0F);
hour=((hour>>4)&0x01)*10+(hour&0x0F);//if you use 12 hour format
hour=((hour>>4)&0x03)*10+(hour&0x0F);//if you use 24 hour format
count=hour*100+minute;

  DD0 = Count%10;  // Extract Ones Digit
  DD0 = mask(DD0);
  DD1 = (Count/10)%10; // Extract Tens Digit
  DD1 = mask(DD1);
  DD2 = (Count/100)%10; // Extract Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (Count/1000);  // Extract Thousands Digit
  DD3 = mask(DD3);
 
  • Like
Reactions: asking

    asking

    Points: 2
    Helpful Answer Positive Rating
Thanks for the code :) i will try it and let you know..

- - - Updated - - -

I am still confused about RA6 and RA7 Pins, they are defined for SCL/SDA I2C Soft connections. Do i need to make them I/O or automatically they will be working as Digital I/O ?because i have defined PORTA as output port....so m confused how to make any pin as Digital I/O (both)..plz help..
 

read the datasheet of ds1307. you will see that at it holds minutes at 0x01h address. the lower 4 bits for minutes and the other 3 bits for 10 minutes. and the last bit is empty.

after you read minute data from ds1307, you must reformat it.
Do{
minute=(minute>>4)*10+(minute&0x0F);
hour=((hour>>4)&0x01)*10+(hour&0x0F);//if you use 12 hour format
hour=((hour>>4)&0x03)*10+(hour&0x0F);//if you use 24 hour format
count=hour*100+minute;

DD0 = Count%10; // Extract Ones Digit
DD0 = mask(DD0);
DD1 = (Count/10)%10; // Extract Tens Digit
DD1 = mask(DD1);
DD2 = (Count/100)%10; // Extract Hundreds Digit
DD2 = mask(DD2);
DD3 = (Count/1000); // Extract Thousands Digit
DD3 = mask(DD3);

If you dont mind could you help me to understand it better ? i m not able to understand after looking into DS1307 Datasheet."minute=(minute>>4)*10+(minute&0x0F);" please elaborate this part...what it is doing.....
 

for example, it is 23:35:14 (hour:minute:second)
the contents of ds1307 is
0x00: 0001 0100 (1 and 4 in bcd format)
0x01: 0011 0101 (3 and 5 in bcd format)
0x02: 0010 0011 (2 and 3 in bcd format)

if you read these addresses you obtain
20 for seconds
53 for minutes
35 for hours

to obtain real values
you should use my codes. did you understand?
 
  • Like
Reactions: asking

    asking

    Points: 2
    Helpful Answer Positive Rating
Thanks mate... :) i did tried to burn your code onto pic but did not worked... m confused about defining i2C Pins... as i have define TRISA = 0 (means all pins are output) then how it can be bidirectional for i2c Pins ? so m confused i doubt thats why its not working :(
 

Thanks Bigdogguru,
for the link. But i want to use soft i2c connection and that is where i m stucked. If i define TRISA = 0 (means all pins are set for output) then how can i define

sbit Soft_I2C_Scl at RA6_bit;
sbit Soft_I2C_Sda at RA7_bit;

because i think in serial i2c is bidirectional...so m confused...because 16F628A has no hardware i2c. so if any one can help to clear this.....please do let me know.
 
Thanks Bigdogguru,
for the link. But i want to use soft i2c connection and that is where i m stucked. If i define TRISA = 0 (means all pins are set for output) then how can i define

sbit Soft_I2C_Scl at RA6_bit;
sbit Soft_I2C_Sda at RA7_bit;

because i think in serial i2c is bidirectional...so m confused...because 16F628A has no hardware i2c. so if any one can help to clear this.....please do let me know.

The routines required to configure and access the RTC are the same regardless of whether the I2C interface is a hardware module or a software implementation.

The port pins of a PIC can only be configure as input or output, not bidirectional.

The softI2C routines change the state/direction of the pins as required during code execution, typically such software interface routines require the port pins utilized by the routines be initialized to a know state/direction.

According the MikroC Pro User Manual, you must define both the port pins to be used by the soft I2C and the TRISX register bits to control the port pin direction.

Code:
// Software I2C connections
sbit Soft_I2C_Scl at RC3_bit;
sbit Soft_I2C_Sda at RC4_bit;
[COLOR="#FF0000"]sbit Soft_I2C_Scl_Direction at TRISC3_bit;
sbit Soft_I2C_Sda_Direction at TRISC4_bit;[/COLOR]
// End Software I2C connections

Example Code:
Code:
// Software I2C connections
sbit Soft_I2C_Scl           at RC3_bit;
sbit Soft_I2C_Sda           at RC4_bit;
sbit Soft_I2C_Scl_Direction at TRISC3_bit;
sbit Soft_I2C_Sda_Direction at TRISC4_bit;
// End Software I2C connections

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

char seconds, minutes, hours, day, month, year; // Global date/time variables

//--------------------- Reads time and date information from RTC (PCF8583)
void Read_Time() {

  Soft_I2C_Start();               // Issue start signal
  Soft_I2C_Write(0xA0);           // Address PCF8583, see PCF8583 datasheet
  Soft_I2C_Write(2);              // Start from address 2
  Soft_I2C_Start();               // Issue repeated start signal
  Soft_I2C_Write(0xA1);           // Address PCF8583 for reading R/W=1
  
  seconds = Soft_I2C_Read(1);     // Read seconds byte
  minutes = Soft_I2C_Read(1);     // Read minutes byte
  hours = Soft_I2C_Read(1);       // Read hours byte
  day = Soft_I2C_Read(1);         // Read year/day byte
  month = Soft_I2C_Read(0);       // Read weekday/month byte
  Soft_I2C_Stop();                // Issue stop signal
  
}

//-------------------- Formats date and time
void Transform_Time() {
  seconds  =  ((seconds & 0xF0) >> 4)*10 + (seconds & 0x0F);  // Transform seconds
  minutes  =  ((minutes & 0xF0) >> 4)*10 + (minutes & 0x0F);  // Transform months
  hours    =  ((hours & 0xF0)  >> 4)*10  + (hours & 0x0F);    // Transform hours
  year     =   (day & 0xC0) >> 6;                             // Transform year
  day      =  ((day & 0x30) >> 4)*10    + (day & 0x0F);       // Transform day
  month    =  ((month & 0x10)  >> 4)*10 + (month & 0x0F);     // Transform month
}

//-------------------- Output values to LCD
void Display_Time() {

   Lcd_Chr(1, 6, (day / 10)   + 48);    // Print tens digit of day variable
   Lcd_Chr(1, 7, (day % 10)   + 48);    // Print oness digit of day variable
   Lcd_Chr(1, 9, (month / 10) + 48);
   Lcd_Chr(1,10, (month % 10) + 48);
   Lcd_Chr(1,15,  year        + 48);    // Print year variable  (start from year 2010)


   Lcd_Chr(2, 6, (hours / 10)   + 48);
   Lcd_Chr(2, 7, (hours % 10)   + 48);
   Lcd_Chr(2, 9, (minutes / 10) + 48);
   Lcd_Chr(2,10, (minutes % 10) + 48);
   Lcd_Chr(2,12, (seconds / 10) + 48);
   Lcd_Chr(2,13, (seconds % 10) + 48);
}


//------------------ Performs project-wide init
void Init_Main() {

  TRISB = 0;
  PORTB = 0xFF;
  TRISB = 0xff;
  ANSEL  = 0;                // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;              // Disable comparators
  C2ON_bit = 0;
  
  Soft_I2C_Init();           // Initialize Soft I2C communication
  Lcd_Init();                // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
  Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off

  Lcd_Out(1,1,"Date:");      // Prepare and output static text on LCD
  Lcd_Chr(1,8,'.');
  Lcd_Chr(1,11,'.');
  Lcd_Chr(1,16,'.');
  Lcd_Out(2,1,"Time:");
  Lcd_Chr(2,8,':');
  Lcd_Chr(2,11,':');
  Lcd_Out(1,12,"201");       // start from year 2010
}

//----------------- Main procedure
void main() {
  Delay_ms(500);
   
  Init_Main();               // Perform initialization

  while (1) {                // Endless loop
    Read_Time();             // Read time from RTC(PCF8583)
    Transform_Time();        // Format date and time
    Display_Time();          // Prepare and display on LCD
  }
}

BigDog
 
  • Like
Reactions: asking

    asking

    Points: 2
    Helpful Answer Positive Rating
My Final code :
Code:
// Software I2C connections
sbit Soft_I2C_Scl           at RA2_bit;
sbit Soft_I2C_Sda           at RA3_bit;
sbit Soft_I2C_Scl_Direction at TRISA2_bit;
sbit Soft_I2C_Sda_Direction at TRISA3_bit;
// End Software I2C connections
// this is my progRAmming part 1

unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  Soft_I2C_Start();
  Soft_I2C_Write(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(address);
  Soft_I2C_Start();
  Soft_I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=Soft_I2C_Read(0);
  Soft_I2C_Stop();
  return(r_data);
}

void write_ds1307(unsigned short address,unsigned short w_data)
{
  Soft_I2C_Start(); // issue I2C start signal
  //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(0xD0); // send byte via I2C (device address + W)
  Soft_I2C_Write(address); // send byte (address of DS1307 location)
  Soft_I2C_Write(w_data); // send data (data to be written)
  Soft_I2C_Stop(); // issue I2C stop signal
}


unsigned short i, DD0, DD1, DD2, DD3;
unsigned int Count, hour, minute;
//------ Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
 switch (num) {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
 } //case end
}

void main()
{

  CMCON  |= 7;        // Disable CompaRAtors
  TRISB = 0x00; // Set PORTB7 input all other direction to be output
  PORTB = 0xff;    // Turn OFF LEDs on PORTB
  TRISA = 0b00100000; // RA5-6-7 is input only
  
  Soft_I2C_Init();
  minute = read_ds1307(1);
  hour = read_ds1307(2);
  
  do {
  DD0 = Count%10;  // ExtRAct Ones Digit
  DD0 = mask(DD0);
  DD1 = (Count/10)%10; // ExtRAct Tens Digit
  DD1 = mask(DD1);
  DD2 = (Count/100)%10; // ExtRAct Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (Count/1000);  // ExtRAct Thousands Digit
  DD3 = mask(DD3);

  for (i = 0; i<=50; i++) {
      RA7_bit = 1;                //disable RA3
      PORTB = DD0;
      RA0_bit = 0;      // Select Ones Digit
      RA1_bit = 1;
      RA6_bit = 1;
      delay_ms(5);

      RA0_bit = 1;                //disable RA0
      PORTB = DD1;
      RA1_bit = 0;     // Select Tens Digit
      RA6_bit = 1;
      RA7_bit = 1;
      delay_ms(5);

      RA1_bit = 1;                //disable RA1
      PORTB = DD2;
      RA0_bit = 1;
      RA6_bit = 0;     // Select Hundreds Digit
      RA7_bit = 1;
      delay_ms(5);

      RA6_bit = 1;                //disable RA2
      PORTB   = DD3;
      RA0_bit = 1;
      RA1_bit = 1;
      RA7_bit = 0;     // Select Thousands Digit
      delay_ms(5);
      

      }
      minute=(minute>>4)*10+(minute&0x0F);
      hour=((hour>>4)&0x01)*10+(hour&0x0F);
      count=hour*100+minute;
     } while(1);
}

           // endless loop

When i place

Soft_I2C_Init();
minute = read_ds1307(1);
hour = read_ds1307(2);

in the main program display is stucked @ 8.8 and if i dont then it shows 0 0 0 0 means its ready to accept count = integer value now i donno where something is wrong...just need little help if anyone can find out whats wrong...in the above code :D
 

Attachments

  • final schmt.jpg
    final schmt.jpg
    350.7 KB · Views: 186
Last edited:

Hello,

Finally i managed to work with code there was little error two more variable needs to be define instead of hour hour 1 and minute minute 1, because hour and minute are already being changed with DS1307. But now problem is you can see in the attached image. Time is display at what i start the circuit. I started circuit at 23:55 and now its 23:56 in the RTC Chip as you can see in screenshot... means it holds the value. But i need real live values...please can anyone help me ? I have already achieved what i want but only thing is its not live with RTC Chip it holds the values in "Count = hour1*100+minute1;"



Code:
// Software I2C connections
sbit Soft_I2C_Scl           at RA3_bit;
sbit Soft_I2C_Sda           at RA4_bit;
sbit Soft_I2C_Scl_Direction at TRISA3_bit;
sbit Soft_I2C_Sda_Direction at TRISA4_bit;
// End Software I2C connections
// this is my progRAmming part 1


unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  Soft_I2C_Start();
  Soft_I2C_Write(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(address);
  Soft_I2C_Start();
  Soft_I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=Soft_I2C_Read(0);
  Soft_I2C_Stop();
  return(r_data);
}

void write_ds1307(unsigned short address,unsigned short w_data)
{
  Soft_I2C_Start(); // issue I2C start signal
  //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(0xD0); // send byte via I2C (device address + W)
  Soft_I2C_Write(address); // send byte (address of DS1307 location)
  Soft_I2C_Write(w_data); // send data (data to be written)
  Soft_I2C_Stop(); // issue I2C stop signal
}


unsigned short i, DD0, DD1, DD2, DD3;
unsigned short Count, hour, minute, hour1, minute1;
//------ Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
 switch (num) {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
 } //case end
}

void main()
{
  Soft_I2C_Init();
  CMCON  |= 7;        // Disable Comparators
  TRISB = 0x00; // Set PORTB7 input all other direction to be output
  PORTB = 0xff;    // Turn OFF LEDs on PORTB
  TRISA = 0b00000000; // RA5-6-7 is input only
  
  //
  minute = read_ds1307(1);
  hour = read_ds1307(2);
  
  do {
  DD0 = Count%10;  // ExtRAct Ones Digit
  DD0 = mask(DD0);
  DD1 = (Count/10)%10; // ExtRAct Tens Digit
  DD1 = mask(DD1);
  DD2 = (Count/100)%10; // ExtRAct Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (Count/1000);  // ExtRAct Thousands Digit
  DD3 = mask(DD3);


  for (i = 0; i<=50; i++) {
      RA7_bit = 1;                //disable RA3
      PORTB = DD0;
      RA0_bit = 0;      // Select Ones Digit
      RA1_bit = 1;
      RA6_bit = 1;
      delay_ms(5);

      RA0_bit = 1;                //disable RA0
      PORTB = DD1;
      RA1_bit = 0;     // Select Tens Digit
      RA6_bit = 1;
      RA7_bit = 1;
      delay_ms(5);

      RA1_bit = 1;                //disable RA1
      PORTB = DD2;
      RA0_bit = 1;
      RA6_bit = 0;     // Select Hundreds Digit
      RA7_bit = 1;
      delay_ms(5);

      RA6_bit = 1;                //disable RA2
      PORTB   = DD3;
      RA0_bit = 1;
      RA1_bit = 1;
      RA7_bit = 0;     // Select Thousands Digit
      delay_ms(5);
      
      }
      minute1=(minute>>4)*10+(minute&0x0F);
      hour1=((hour>>4)&0x02)*10+(hour&0x0F);
      Count = hour1*100+minute1;
     } while(1);
}

           // endless loop

- - - Updated - - -

Guyz thanks for support :) i solved it :) without all of you i would not have finish my first project :)

Working code:-
Code:
// Software I2C connections
sbit Soft_I2C_Scl           at RA3_bit;
sbit Soft_I2C_Sda           at RA4_bit;
sbit Soft_I2C_Scl_Direction at TRISA3_bit;
sbit Soft_I2C_Sda_Direction at TRISA4_bit;
// End Software I2C connections
// this is my progRAmming part 1


unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  Soft_I2C_Start();
  Soft_I2C_Write(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(address);
  Soft_I2C_Start();
  Soft_I2C_Write(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=Soft_I2C_Read(0);
  Soft_I2C_Stop();
  return(r_data);
}

void write_ds1307(unsigned short address,unsigned short w_data)
{
  Soft_I2C_Start(); // issue I2C start signal
  //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  Soft_I2C_Write(0xD0); // send byte via I2C (device address + W)
  Soft_I2C_Write(address); // send byte (address of DS1307 location)
  Soft_I2C_Write(w_data); // send data (data to be written)
  Soft_I2C_Stop(); // issue I2C stop signal
}


unsigned short i, DD0, DD1, DD2, DD3;
unsigned short Count, hour, minute, hour1, minute1;
//------ Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
 switch (num) {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
 } //case end
}

void main()
{
  void Soft_I2C_Init();
  CMCON  |= 7;        // Disable CompaRAtors
  TRISB = 0x00; // Set PORTB7 input all other direction to be output
  PORTB = 0xff;    // Turn OFF LEDs on PORTB
  TRISA = 0b00000000; // RA5-6-7 is input only
  
  //

  

  
  do {
  DD0 = Count%10;  // ExtRAct Ones Digit
  DD0 = mask(DD0);
  DD1 = (Count/10)%10; // ExtRAct Tens Digit
  DD1 = mask(DD1);
  DD2 = (Count/100)%10; // ExtRAct Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (Count/1000);  // ExtRAct Thousands Digit
  DD3 = mask(DD3);


  for (i = 0; i<=50; i++) {
      RA7_bit = 1;                //disable RA3
      PORTB = DD0;
      RA0_bit = 0;      // Select Ones Digit
      RA1_bit = 1;
      RA6_bit = 1;
      delay_ms(5);

      RA0_bit = 1;                //disable RA0
      PORTB = DD1;
      RA1_bit = 0;     // Select Tens Digit
      RA6_bit = 1;
      RA7_bit = 1;
      delay_ms(5);

      RA1_bit = 1;                //disable RA1
      PORTB = DD2;
      RA0_bit = 1;
      RA6_bit = 0;     // Select Hundreds Digit
      RA7_bit = 1;
      delay_ms(5);

      RA6_bit = 1;                //disable RA2
      PORTB   = DD3;
      RA0_bit = 1;
      RA1_bit = 1;
      RA7_bit = 0;     // Select Thousands Digit
      delay_ms(5);
      
      }
      
      minute = read_ds1307(1);
      hour = read_ds1307(2);
      minute1=(minute>>4)*10+(minute&0x0F);
      hour1=((hour>>4)&0x02)*10+(hour&0x0F);
      Count = hour1*100+minute1;
     } while(1);
}

           // endless loop
 

Attachments

  • final clock ready.jpg
    final clock ready.jpg
    347.3 KB · Views: 229

Have you clear the Clock Halt (CH) bit?

CLOCK AND CALENDAR
The time and calendar information is obtained by reading the appropriate register bytes. Table 2 shows the RTC registers. The time and calendar are set or initialized by writing the appropriate register bytes. The contents of the time and calendar registers are in the BCD format. The day-of-week register increments at midnight. Values that correspond to the day of week are user-defined but must be sequential (i.e., if 1 equals Sunday, then 2 equals Monday, and so on.) Illogical time and date entries result in undefined operation. Bit 7 of Register 0 is the clock halt (CH) bit. When this bit is set to 1, the oscillator is disabled. When cleared to 0, the oscillator is enabled. On first application of power to the device the time and date registers are typically reset to 01/01/00 01 00:00:00 (MM/DD/YY DOW HH:MM:SS). The CH bit in the seconds register will be set to a 1. The clock can be halted whenever the timekeeping functions are not required, which minimizes current (IBATDR).

BigDog
 

Have you clear the Clock Halt (CH) bit?



BigDog

Thanks BigDog for your concern,

But actually i dont need calender function right now. I just need Clock Hour : Min , i have tried to set time but m not getting it.

Here's the code do i need to change anything ?

Code:
do {

  set = 0;
     if(PORTA.F5 == 0)
     {
         Delay_ms(100);
         if(PORTA.F5 == 0)
         {
             set_count++;
             if(set_count >= 2)
             {
                set_count = 0;
             }
         }
     }
     if(set_count)
     {
        if(PORTA.F2 == 0)
        {
          Delay_ms(100);
          if(PORTA.F2 == 0)
              set = 1;
         }
          if(set_count && set)
        {
          switch(set_count)
          {
            case 1:
                    hour = BCD2Binary(hour);
                    hour = hour + set;
                    hour = Binary2BCD(hour);
                    if((hour & 0x1F) >= 0x13)
                    {
                      hour = hour & 0b11100001;
                      hour = hour ^ 0x20;
                    }
                    else if((hour & 0x1F) <= 0x00)
                    {
                      hour = hour | 0b00010010;
                      hour = hour ^ 0x20;
                    }
                    write_ds1307(2, hour); //write hour
                    break;
            case 2:
                     minute = BCD2Binary(minute);
                     minute = minute + set;
                     if(minute >= 60)
                        minute = 0;
                     if(minute < 0)
                        minute = 59;
                     minute = Binary2BCD(minute);
                     write_ds1307(1, minute); //write min
                     break;
          }
        }
     }

do i need to change anything in the above case ? because its not working. When i press PortA.5 pin it should be gone to set mode, then when i click it should change hour and increment would be using PortA.2, now if i press PortA.5 pin again it should move to min change, but its not happening. please can anyone tell me whats wrong ?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top