Problem in Glcd clock with ds1307 rtc

Thread Starter

adarsh33

Joined Jan 20, 2014
1
Hello Everyone,
Kindly anyone could help me, I am making a Glcd based clock with ds1307 rtc using pic 18f4520,I am using HS oscillator of 20Mhz. My Glcd(12864a) is working fine and I have also checked rtc(also using 32khz crystal for drving the rtc ) through oscilloscope. I am not able to find why my clock is not working and It only displays one digit ascii character and keeps blinking always. I am attaching my source code. I am using MikroC pro for Pic compiler and pic kit 3 programmer in .

Rich (BB code):
// Glcd module connections
char GLCD_DataPort at PORTD;
 
sbit GLCD_CS1 at LATB3_bit;
sbit GLCD_CS2 at LATB4_bit;
sbit GLCD_RS  at LATB0_bit;
sbit GLCD_RW  at LATB1_bit;
sbit GLCD_EN  at LATB2_bit;
sbit GLCD_RST at LATB5_bit;
sbit GLCD_DB0 at LATD0_bit;
sbit GLCD_DB1 at LATD1_bit;
sbit GLCD_DB2 at LATD2_bit;
sbit GLCD_DB3 at LATD3_bit;
sbit GLCD_DB4 at LATD4_bit;
sbit GLCD_DB5 at LATD5_bit;
sbit GLCD_DB6 at LATD6_bit;
sbit GLCD_DB7 at LATD7_bit;
 
sbit GLCD_CS1_Direction at TRISB3_bit;
sbit GLCD_CS2_Direction at TRISB4_bit;
sbit GLCD_RS_Direction  at TRISB0_bit;
sbit GLCD_RW_Direction  at TRISB1_bit;
sbit GLCD_EN_Direction  at TRISB2_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
 
sbit GLCD_DB0_Direction at TRISD0_bit;
sbit GLCD_DB1_Direction at TRISD1_bit;
sbit GLCD_DB2_Direction  at TRISD2_bit;
sbit GLCD_DB3_Direction  at TRISD3_bit;
sbit GLCD_DB4_Direction  at TRISD4_bit;
sbit GLCD_DB5_Direction at TRISD5_bit;
sbit GLCD_DB6_Direction  at TRISD6_bit;
sbit GLCD_DB7_Direction at TRISD7_bit;
// End Glcd module connections
 
 
 
unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  I2C1_Start();
  I2C1_Wr(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  I2C1_Wr(address);
  I2C1_Repeated_Start();
  I2C1_Wr(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=I2C1_Rd(0);
  I2C1_Stop();
  return(r_data);
}
 
 
void write_ds1307(unsigned short address,unsigned short w_data)
{
  I2C1_Start(); // issue I2C start signal
  //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  I2C1_Wr(0xD0); // send byte via I2C (device address + W)
  I2C1_Wr(address); // send byte (address of DS1307 location)
  I2C1_Wr(w_data); // send data (data to be written)
  I2C1_Stop(); // issue I2C stop signal
}
 
 
unsigned char BCD2UpperCh(unsigned char bcd)
{
  return ((bcd >> 4) + '1');
}
 
 
unsigned char BCD2LowerCh(unsigned char bcd)
{
  return ((bcd & 0x0F) + '1');
}
 
 
int Binary2BCD(int a)
{
   int t1, t2;
   t1 = a%10;
   t1 = t1 & 0x0F;
   a = a/10;
   t2 = a%10;
   t2 = 0x0F & t2;
   t2 = t2 << 4;
   t2 = 0xF0 & t2;
   t1 = t1 | t2;
   return t1;
}
 
 
int BCD2Binary(int a)
{
   int r,t;
   t = a & 0x0F;
   r = t;
   a = 0xF0 & a;
   t = a >> 4;
   t = 0x0F & t;
   r = t*10 + r;
   return r;
}
 
 
 
int second;
int minute;
int hour;
int hr;
int day;
int dday;
int month;
int year;
int ap;
 
unsigned short set_count = 0;
short set;
 
char *time = "00:00:00 PM";
char *date = "00-00-00";
 
void main()
{
 
 
I2C1_Init(100000); //DS1307 I2C is running at 100KHz
 
    ADRESL = 0;
    ADRESH = 0;
   CMCON = 0x07;   // To turn off comparators
   ADCON1 = 0xFF;  // To turn off analog to digital converters
 
 
   TRISA = 0x07;
   PORTA = 0x00;
 
   Glcd_Init();                        // Initialize GLCD
   Glcd_Fill(0xFF);
   Delay_ms(100);
 
   Glcd_Set_Font(Font_Glcd_Character8x7, 8 , 7, 32);
   Glcd_Write_Text( "Time:" , 80, 1, 2);
   Glcd_Write_Text( "Date:" , 65, 5, 2);
 
 
   do
   {
     set = 0;
     if(PORTA.F0 == 0)
     {
         Delay_ms(100);
         if(PORTA.F0 == 0)
         {
             set_count++;
             if(set_count >= 7)
             {
                set_count = 0;
             }
         }
     }
     if(set_count)
     {
        if(PORTA.F2 == 0)
        {
          Delay_ms(100);
          if(PORTA.F2 == 0)
              set = 1;
        }
 
        if(PORTA.F0 == 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;
            case 3:
                    if(abs(set))
                      write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator
                    break;
            case 4:
                     day = BCD2Binary(day);
                     day = day + set;
                     day = Binary2BCD(day);
                     if(day >= 0x32)
                        day = 1;
                     if(day <= 0)
                        day = 0x31;
                     write_ds1307(4, day); // write date 17
                     break;
            case 5:
                    month = BCD2Binary(month);
                    month = month + set;
                    month = Binary2BCD(month);
                    if(month > 0x12)
                      month = 1;
                    if(month <= 0)
                      month = 0x12;
                    write_ds1307(5,month); // write month 6 June
                    break;
            case 6:
                    year = BCD2Binary(year);
                    year = year + set;
                    year = Binary2BCD(year);
                    if(year <= -1)
                       year = 0x99;
                    if(year >= 0x50)
                       year = 0;
                    write_ds1307(6, year); // write year
                    break;
          }
        }
     }
 
      second = read_ds1307(0);
      minute = read_ds1307(1);
      hour = read_ds1307(2);
       hr = hour & 0b00011111;
       ap = hour & 0b00100000;
      dday = read_ds1307(3);
      day = read_ds1307(4);
      month = read_ds1307(5);
      year = read_ds1307(6);
 
 
      time[0] = BCD2UpperCh(hr);
      time[1] = BCD2LowerCh(hr);
      time[3] = BCD2UpperCh(minute);
      time[4] = BCD2LowerCh(minute);
      time[6] = BCD2UpperCh(second);
      time[7] = BCD2LowerCh(second);
 
      date[0] = BCD2UpperCh(day);
      date[1] = BCD2LowerCh(day);
      date[3] = BCD2UpperCh(month);
      date[4] = BCD2LowerCh(month);
      date[6] = BCD2UpperCh(year);
      date[7] = BCD2LowerCh(year);
 
      if(ap)
      {
         time[9] = 'P';
         time[10] = 'M';
      }
      else
      {
         time[9] = 'A';
         time[10] = 'M';
      }
 
      Glcd_Write_Char( time, 80, 2, 2);
      Glcd_Write_Char( date, 70, 6, 2);
 
      Delay_ms(100);
 
 
   }while(1);
}
 

Ian Rogers

Joined Dec 12, 2012
1,136
Rich (BB code):
Glcd_Write_Char( time, 80, 2, 2);
This function only write 1 char..

Try something like this.
Rich (BB code):
for(x=0:x<8;x++)
   Glcd_Write_Char( time[x], 80, 2+x, 2);
 

ErnieM

Joined Apr 24, 2011
8,377
That's what happens when you write lots and lots of code without any intermediate testing. You describe the display as working (you get a single digit) but then state the display doesn't work.

You merged together at least 3 tasks inside main:

Defining the time structure
Incrementing the time structure
Displaying the time structure

Plus the date stuff, updating the DS1307...

First you want to get a static time (or date) to display, then work from there.

Lastly, if you can get a single character to display but not a string keep in mind a string in c is an array that ends in a zero, and the zero marks the end of the string.

The string buffer must be at least as long as the string, but may be longer then the string.
 

hexreader

Joined Apr 16, 2011
581
I agree 100% with everything that ErnieM stated in the previous post.

Luckily for you I am in good mood and desperately bored, so I have fixed some of the more basic errors in your code.

Still plenty left for you to do though.

Here are just enough fixes to give you encouragement:

Rich (BB code):
// Glcd module connections
char GLCD_DataPort at PORTD;
 
sbit GLCD_CS1 at LATB3_bit;
sbit GLCD_CS2 at LATB4_bit;
sbit GLCD_RS  at LATB0_bit;
sbit GLCD_RW  at LATB1_bit;
sbit GLCD_EN  at LATB2_bit;
sbit GLCD_RST at LATB5_bit;
sbit GLCD_DB0 at LATD0_bit;
sbit GLCD_DB1 at LATD1_bit;
sbit GLCD_DB2 at LATD2_bit;
sbit GLCD_DB3 at LATD3_bit;
sbit GLCD_DB4 at LATD4_bit;
sbit GLCD_DB5 at LATD5_bit;
sbit GLCD_DB6 at LATD6_bit;
sbit GLCD_DB7 at LATD7_bit;
 
sbit GLCD_CS1_Direction at TRISB3_bit;
sbit GLCD_CS2_Direction at TRISB4_bit;
sbit GLCD_RS_Direction  at TRISB0_bit;
sbit GLCD_RW_Direction  at TRISB1_bit;
sbit GLCD_EN_Direction  at TRISB2_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
 
sbit GLCD_DB0_Direction at TRISD0_bit;
sbit GLCD_DB1_Direction at TRISD1_bit;
sbit GLCD_DB2_Direction  at TRISD2_bit;
sbit GLCD_DB3_Direction  at TRISD3_bit;
sbit GLCD_DB4_Direction  at TRISD4_bit;
sbit GLCD_DB5_Direction at TRISD5_bit;
sbit GLCD_DB6_Direction  at TRISD6_bit;
sbit GLCD_DB7_Direction at TRISD7_bit;
// End Glcd module connections
 
 
 
unsigned short read_ds1307(unsigned short address)
{
  unsigned short r_data;
  I2C1_Start();
  I2C1_Wr(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  I2C1_Wr(address);
  I2C1_Repeated_Start();
  I2C1_Wr(0xD1); //0x68 followed by 1 --> 0xD1
  r_data=I2C1_Rd(0);
  I2C1_Stop();
  return(r_data);
}
 
 
void write_ds1307(unsigned short address,unsigned short w_data)
{
  I2C1_Start(); // issue I2C start signal
  //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
  I2C1_Wr(0xD0); // send byte via I2C (device address + W)
  I2C1_Wr(address); // send byte (address of DS1307 location)
  I2C1_Wr(w_data); // send data (data to be written)
  I2C1_Stop(); // issue I2C stop signal
}
 
 
unsigned char BCD2UpperCh(unsigned char bcd)
{
  return ((bcd >> 4) + '0');
}
 
 
unsigned char BCD2LowerCh(unsigned char bcd)
{
  return ((bcd & 0x0F) + '0');
}
 
 
int Binary2BCD(int a)
{
   int t1, t2;
   t1 = a%10;
   t1 = t1 & 0x0F;
   a = a/10;
   t2 = a%10;
   t2 = 0x0F & t2;
   t2 = t2 << 4;
   t2 = 0xF0 & t2;
   t1 = t1 | t2;
   return t1;
}
 
 
int BCD2Binary(int a)
{
   int r,t;
   t = a & 0x0F;
   r = t;
   a = 0xF0 & a;
   t = a >> 4;
   t = 0x0F & t;
   r = t*10 + r;
   return r;
}
 
 
 
int second;
int minute;
int hour;
int hr;
int day;
int dday;
int month;
int year;
int ap;
int old_second;
 
unsigned short set_count = 0;
short set;
 
char time[16] = "00:00:00 PM";
char date[16] = "00-00-00";
 
void main()
{
 
 
    I2C1_Init(100000); //DS1307 I2C is running at 100KHz
 
    ADRESL = 0;
    ADRESH = 0;
    CMCON = 0x07;   // To turn off comparators
    ADCON1 = 0xFF;  // To turn off analog to digital converters
 
    TRISA = 0x07;
    PORTA = 0x00;
 
    Glcd_Init();                        // Initialize GLCD
   Glcd_Set_Font(Font_Glcd_Character8x7, 8 , 7, 32);

   do
   {

     set = 0;
     if(PORTA.F0 == 0)
     {
         Delay_ms(100);
         if(PORTA.F0 == 0)
         {
             set_count++;
             if(set_count >= 7)
             {
                set_count = 0;
             }
         }
     }
     if(set_count)
     {
        if(PORTA.F2 == 0)
        {
          Delay_ms(100);
          if(PORTA.F2 == 0)
              set = 1;
        }
 
        if(PORTA.F0 == 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;
            case 3:
                    if(abs(set))
                      write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator
                    break;
            case 4:
                     day = BCD2Binary(day);
                     day = day + set;
                     day = Binary2BCD(day);
                     if(day >= 0x32)
                        day = 1;
                     if(day <= 0)
                        day = 0x31;
                     write_ds1307(4, day); // write date 17
                     break;
            case 5:
                    month = BCD2Binary(month);
                    month = month + set;
                    month = Binary2BCD(month);
                    if(month > 0x12)
                      month = 1;
                    if(month <= 0)
                      month = 0x12;
                    write_ds1307(5,month); // write month 6 June
                    break;
            case 6:
                    year = BCD2Binary(year);
                    year = year + set;
                    year = Binary2BCD(year);
                    if(year <= -1)
                       year = 0x99;
                    if(year >= 0x50)
                       year = 0;
                    write_ds1307(6, year); // write year
                    break;
          }
        }
     }
 
      second = read_ds1307(0);
      minute = read_ds1307(1);
      hour = read_ds1307(2);
       hr = hour & 0b00011111;
       ap = hour & 0b00100000;
      dday = read_ds1307(3);
      day = read_ds1307(4);
      month = read_ds1307(5);
      year = read_ds1307(6);
 
      time[0] = BCD2UpperCh(hr);
      time[1] = BCD2LowerCh(hr);
      time[3] = BCD2UpperCh(minute);
      time[4] = BCD2LowerCh(minute);
      time[6] = BCD2UpperCh(second);
      time[7] = BCD2LowerCh(second);
 
      date[0] = BCD2UpperCh(day);
      date[1] = BCD2LowerCh(day);
      date[3] = BCD2UpperCh(month);
      date[4] = BCD2LowerCh(month);
      date[6] = BCD2UpperCh(year);
      date[7] = BCD2LowerCh(year);
 
      if(ap)
      {
         time[9] = 'P';
         time[10] = 'M';
      }
      else
      {
         time[9] = 'A';
         time[10] = 'M';
      }
 
      if(second != old_second){                        // only display if data has changed
          Glcd_Fill(0xFF);
          Glcd_Write_Text( "Time:" , 10, 1, 2);
          Glcd_Write_Text( "Date:" , 10, 5, 2);

          Glcd_Write_Text( time, 20, 2, 2);
          Glcd_Write_Text( date, 20, 6, 2);
          old_second = second;                            // prevent repeat display of same data
      }

   }while(1);
}
 
Top