CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

DS1307 doesn't keep day of the month
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

DS1307 doesn't keep day of the month
PostPosted: Sun Jun 21, 2015 6:54 am     Reply with quote

Hi all:

I'm having a rare problem with the DS1307 RTC chip, doesn't keep the day of the month when I retire the 5V.

I checked the basic: battery, pull-up resistor, tried with different libraries and nothing, the problem persist. So I think that problem could be in the code. Basically, when you start the microcontroller, the DS1307 init, then enters an infinite loop to display data (7 segments) and see if the user wants to change the time (TIMESET flag). To read the DS1307, I do it in the function mostrar() to avoid flashes on the display while the micro performs the reading.

CODE
Code:
#include <16F873.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#BYTE TRISD=0x88
#BYTE PORTD=0x08
#include <math.h>
#include <ds1307todopic.c>
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)
byte day=31;
byte dow=7;
byte year=15;
byte mth=12;
byte hr=23;
byte prehr=0,min=59,copia=0, TIMESET=0;
byte contaseg=0, estado=1,mipre=0,uni=0,dec=0,buni=0,bdec=0,grup1=0,grup2=0,lectoconta=0, daycarrier=0;
byte sec=0;
int1 turnseg=0,setling=0,leeds=0;
byte const num[10]={238,6,220,158,54,186,250,14,254,62};
#define DATA      PIN_A1   
#define CLOCK     PIN_A0
#define RAYA      PIN_C1
#define SEGUNDERO PIN_C0
#define HAB1      PIN_C2
#define HAB2      PIN_C5
#define HAB3      PIN_C6
#define HAB4      PIN_C7
#define TS        PIN_B0
#define MINSET    PIN_B2
#define HORASET   PIN_B1
#define DIASET    PIN_B3
#define SETMES    PIN_B4
#define ANOSET    PIN_B5
#define AM        PIN_B6
#define PM        PIN_B7
//#define DEBUG3    PIN_C3
//#define DEBUG4    PIN_C4

void escribir(int8 aux){ ////////FUNCION ESCRIBIR PARA LOS REGISTROS DE DESPLAZAMIENTO
   int i;
   for(i=0;i<8;i++)
    {
      if(bit_test(aux, i)==0)
      {
         output_low (DATA);
         output_low (CLOCK);
         output_high(CLOCK);
      }
      if(bit_test(aux,i)==1)
      {
         output_high(DATA);
         output_low (CLOCK);
         output_high(CLOCK);
      }
   }
} ///////////////////////////////FIN DE FUNCION ESCRIBIR

void bin_bcd(){ /////////////////SEPARA LOS DATOS PARA IMPRIMIR
  if (hr==0){
  prehr=12;
  output_low (PM); //PM OFF
  output_high (AM);   //AM ON
  }
  else if (hr==12){
  prehr=hr;
  output_low (AM); // AM OFF
  output_high (PM);   //PM ON
  }
  else if (hr>12){
  prehr=hr-12;
  output_low (AM); // AM OFF
  output_high (PM);   //PM ON
  }
  else{
  prehr=hr;
  output_low (PM); //PM OFF
  output_high (AM);   //AM ON
  }
if (TIMESET==1){
grup2=20;
grup1=year;
}
if ((TIMESET==2)||(estado==2)){
grup2=day;
grup1=mth;
//grup1=daycarrier;
}
if ((TIMESET==3)||(estado==1)){
grup2=prehr;
grup1=min;
}
      copia=grup1;
      dec= copia/10;
      copia= copia%10;
      uni=copia;
      copia=grup2;
      bdec= copia/10;
      copia= copia%10;
      buni=copia; 
}   

void mostrar(){
   bin_bcd();
   output_low(HAB4);
   escribir(num[uni]);
   output_high(HAB1);
   if (leeds==0){
   delay_ms(2);
   }
   if (leeds==1){
   ds1307_get_date(day,mth,year,dow);
   }
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribir(num[dec]);
   delay_us(10);
   output_high(HAB2);
   if (leeds==1){
   ds1307_get_time(hr,min,sec);
   leeds=0;
   }
   if (leeds==0){
   delay_ms(2);
   }
    output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribir(num[buni]);
   delay_us(10);
   output_high(HAB3);
   delay_ms(2);
   if((bdec>0))
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      escribir(num[bdec]);
      delay_us(10);
      output_high(HAB4);
      delay_ms(2);
   }
   else
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      delay_ms(2);
   }
 
}
#INT_TIMER1
void temp1_isr() {
      disable_interrupts(INT_TIMER1);
      if (mipre==2){
      turnseg=!turnseg;
      mipre=0;

      }
      if (contaseg==20){
      contaseg=0;
      estado++;
      }
      if (estado>2){
      estado=1;
      }
      if (lectoconta==0){
      lectoconta=20;
      leeds=1;
      }
      contaseg++;
      mipre++;
      lectoconta--;
      set_timer1(3036);
      enable_interrupts(INT_TIMER1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(){ //INICIO DEL PROGRAMA
      set_tris_C(0b00000000);
      PORTD=0b00000000;
      delay_ms(1000);
      disable_interrupts(global);
      output_low (SEGUNDERO);
      output_low (RAYA);
      ds1307_init(DS1307_ALL_DISABLED); //INICIALIZACIÓN DEL DS1307
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
      set_timer1(3036);
      disable_interrupts(INT_TIMER1);
      ds1307_get_date(day,mth,year,dow);//LECTURA INICIAL
      ds1307_get_time(hr,min,sec);      //LECTURA INICIAL
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_TIMER1);

while (1){
mostrar();
if (input(TS)==0){
 while (input(TS)==0){
 mostrar();
 }
 TIMESET++;
 if (TIMESET>3){
 TIMESET=0;
 }
 }

if (TIMESET>0){ ///INICIO DEL DE LA CONFIGURACIÓN DEL TIEMPO
       disable_interrupts(INT_TIMER1);
       setling=1;
       estado=0;
       leeds=0;
       if (TIMESET==1){
       output_low(SEGUNDERO);
       output_low(RAYA);
       }
       if (TIMESET==2){
       output_high (RAYA);
       output_low  (SEGUNDERO);
       }
       if (TIMESET==3){
       output_high (SEGUNDERO);
       output_low  (RAYA);
       }
       if ((input(HORASET)==0)&&(TIMESET==3)){//INICIO CONFIGURACION DE LA HORA
           while(input(HORASET)==0){
           mostrar();}
            if (hr>=23){
               hr=0;
            }
            else{
               hr++;
            }   
       }//////////////////FINAL CONFIGURACIÓN DE LA HORA   
       if((input(MINSET)==0)&&(TIMESET==3)){ //INICIO CONFIGURACIÓN DE LOS MINUTOS
         while(input(MINSET)==0){
         mostrar();}
            if (min>=59){
               min=0;
            }
            else{
               min++;
            }
         } //////////////////FINAL CONFIGURACIÓN DE LOS MINUTOS
    if ((input(DIASET)==0)&&(TIMESET==2)){//////INICIO CONFIGURACION DEL DÍA
      while(input(DIASET)==0){
      mostrar();
      }
         if (mth==1||mth==3||mth==5||mth==7||mth==8||mth==10||mth==12){
            if(day>=31){
               day=1;
            }
            else{
               day++;
            }
         }
         else if (mth==4||mth==6||mth==9||mth==11){
            if(day>=30){
               day=1;
            }
            else{
               day++;
            }
         }
         else if (mth==2){
            if(year==16||year==20||year==24||year==28||year==32||year==36||year==40||year==44){
               if (day==29){
                  day=1;
               }
               else{
                  day++;
               }
            }
            else if (day==28){
                 day=1;
               
            }
            else{
                 day++;
           
            }
      }
  }//////////////////////////FINAL DE CONFIGURACIÓN DEL DÍA
   if ((input(SETMES)==0)&&(TIMESET==2)){////INICIO DE CONFIGURACIÓN DEL MES
         while(input(SETMES)==0){
         mostrar();
           }
         if (mth>=12){
               mth=1;
            }
            else{
               mth++;
            }
        } //////////////////FIN DE CONFIGURACIÓN DEL MES
 
  if ((input(ANOSET)==0)&&(TIMESET==1)){///INICIO CONFIGURACION DEL AÑO
         while(input(ANOSET)==0){
         mostrar();
         }
         if (year>=99){
            year=1;
           }
            else{
               year++;
               }
      }//////////////////////FINAL DE CONFUGURACIÓN DEL AÑO
         
}////////////////////////////FINAL DEL CICLO IF DE LA CONFIGURACIÓN DEL TIEMPO
if ((TIMESET==0)&&(setling==1)){
setling=0;
sec=0;
daycarrier=day;
delay_ms(200);
ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
delay_ms(200);
estado=1;
set_timer1(3036);
enable_interrupts(INT_TIMER1);
}

  if (TIMESET==0){
  if ((estado==1)&&(turnseg==1)){
  output_high(SEGUNDERO);
  }
  else {
  output_low (SEGUNDERO);
  }
  if (estado==2){
  output_high (RAYA);
  }
  else{
  output_low (RAYA);
  }
  }
 }
}//FINAL DEL PROGRAMA

LIBRARY
Code:
///////////////////////////////////////////////////////////////////////////////////////
///                               DS1307.C                                           ///
///                     Driver for Real Time Clock                                   ///
///                     modified by Redpic 08/2006                                   ///
///                  http://picmania.garcia-cuervo.com                               ///
///                                                                                  ///
/// void ds1307_init(val)                                                            ///
///                  - Enable oscillator without clearing the seconds register       ///
///                    used when PIC loses power and DS1307 run from 3V BAT          ///
///                  - Config Control Register with next parameters:                 ///
///                     DS1307_ALL_DISABLED          All disabled                    ///
///                     DS1307_OUT_ON_DISABLED_HIHG  Out to Hight on Disable Out     ///
///                     DS1307_OUT_ENABLED           Out Enabled                     ///
///                     DS1307_OUT_1_HZ              Freq. Out to 1 Hz               ///
///                     DS1307_OUT_4_KHZ             Freq. Out to 4.096 Khz          ///
///                     DS1307_OUT_8_KHZ             Freq. Out to 8.192 Khz          ///
///                     DS1307_OUT_32_KHZ            Freq. Out to 32.768 Khz         ///
///                                                                                  ///
///                     Example init:                                                ///
///                     ds1307_init(DS1307_ALL_DISABLED);                            ///
///                     ds1307_init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);           ///
///                                                                                  ///
/// void ds1307_set_date_time(day,mth,year,dow,hour,min,sec) - Set the date/time     ///
///                                                                                  ///
/// void ds1307_get_date(day,mth,year,dow)                   - Get the date          ///
///                                                                                  ///
/// void ds1307_get_time(hr,min,sec)                         - Get the time          ///
///                                                                                  ///
/// char ds1307_read_nvram_byte(char addr)                   - Read byte in address  ///
///                                                                                  ///
/// void ds1307_write_nvram_byte(char addr, char value)      - Write byte in address ///
///                                                                                  ///
/// void ds1307_get_day_of_week(char* ptr)                   - Get string Day Of Week///
///                                                                                  ///
/// If defined USE_INTERRUPTS all functions disable Global Interrupts on starts and  ///
///                           enable Global on ends else usar can do it hiself       ///
///                                                                                  ///
///////////////////////////////////////////////////////////////////////////////////////

#ifndef RTC_SDA
#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3
#endif

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

#define DS1307_ALL_DISABLED         0b00000000 // All disabled
#define DS1307_OUT_ON_DISABLED_HIHG 0b10000000 // Out to Hight on Disable Out
#define DS1307_OUT_ENABLED          0b00010000 // Out Enabled
#define DS1307_OUT_1_HZ             0b00000000 // Freq. Out to 1 Hz
#define DS1307_OUT_4_KHZ            0b00000001 // Freq. Out to 4.096 Khz
#define DS1307_OUT_8_KHZ            0b00000010 // Freq. Out to 8.192 Khz
#define DS1307_OUT_32_KHZ           0b00000011 // Freq. Out to 32.768 Khz

#define Start_user_address_nvram    0x08
#define End_user_address_nvram      0x3f

char days_of_week[7][11]={"Lunes\0","Martes\0","Miércoles\0","Jueves\0","Viernes\0","Sábado\0","Domingo\0"};

byte ds1307_bin2bcd(byte binary_value);
byte ds1307_bcd2bin(byte bcd_value);

void ds1307_init(int val){

   byte seconds = 0;

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xD1);
   seconds = ds1307_bcd2bin(i2c_read(0));
   i2c_stop();
   seconds &= 0x7F;

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_write(ds1307_bin2bcd(seconds));
   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x07);
   i2c_write(val);
   i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_set_date_time(byte day, byte mth, byte year, byte dow, byte hr, byte min, byte sec){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);
  i2c_write(ds1307_bin2bcd(sec));
  i2c_write(ds1307_bin2bcd(min));
  i2c_write(ds1307_bin2bcd(hr));
  i2c_write(ds1307_bin2bcd(dow));
  i2c_write(ds1307_bin2bcd(day));
  i2c_write(ds1307_bin2bcd(mth));
  i2c_write(ds1307_bin2bcd(year));
  i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_get_date(byte &day, byte &mth, byte &year, byte &dow){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);
  i2c_start();
  i2c_write(0xD1);
  dow  = ds1307_bcd2bin(i2c_read() & 0x7f);
  day  = ds1307_bcd2bin(i2c_read() & 0x3f);
  mth  = ds1307_bcd2bin(i2c_read() & 0x1f);
  year = ds1307_bcd2bin(i2c_read(0));
  i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_get_time(byte &hr, byte &min, byte &sec){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);
  i2c_start();
  i2c_write(0xD1);
  sec = ds1307_bcd2bin(i2c_read() & 0x7f);
  min = ds1307_bcd2bin(i2c_read() & 0x7f);
  hr  = ds1307_bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}


char ds1307_read_nvram_byte(char addr){

   char retval;

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

   i2c_start();
   i2c_write(0xD0);
   i2c_write(addr);

   i2c_start();
   i2c_write(0xD1);
   retval = i2c_read(0);
   i2c_stop();

   return(retval);

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_write_nvram_byte(char addr, char value){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

   i2c_start();
   i2c_write(0xD0);
   i2c_write(addr);
   i2c_write(value);
   i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_get_day_of_week(char* ptr){

   byte lday;
   byte lmonth;
   byte lyr;
   byte ldow;
   ds1307_get_date(lday,lmonth,lyr,ldow);
   sprintf(ptr,"%s",days_of_week[ldow]);
}

///////////////////////////////////////////////////////////////////////////////

byte ds1307_bin2bcd(byte binary_value){

  byte temp;
  byte retval;

  temp = binary_value;
  retval = 0;
  while(1){
    if(temp >= 10){
      temp -= 10;
      retval += 0x10;
    }else{
      retval += temp;
      break;
    }
  }
  return(retval);
}

byte ds1307_bcd2bin(byte bcd_value){

  byte temp;

  temp = bcd_value;
  temp >>= 1;
  temp &= 0x78;
  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}


Best regards from Venezuela.
_________________
From Cumaná, Venezuela.
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Sun Jun 21, 2015 8:14 am     Reply with quote

First, get rid of the interrupt disable/enable inside the timer interrupt. This is pointless (interrupts are already disabled in the interrupt handler). Just a waste of space.
Then you have two I2C setups. Should only be one. The driver already contains an I2C setup....

Then a worrying one. The driver uses 'reference' parameters to allow it to change the value in an external variable. You have global variables, with the same name as the reference parameters, which are then being passed as the variables for the reference parameters. This is dangerous coding, and I would not be at all surprised if this did cause problems.... The driver expects to be handed _local_ variable names, not global variables, and certainly not with the same name.

Then if you want us to understand your code, it needs to be laid out much better, and have some documentation. As it stands, it is a mess. Tell us where in the code you are actually getting to, and what is missing at this point, as the minimum starting point.
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

PostPosted: Tue Jun 23, 2015 8:49 pm     Reply with quote

Hi

First, thanks for the quick response. One of my reasons for get in this forum is to learn to make more orderly and efficient codes.

About your request, I put a synthesis of software:

- escribir (): I used it to write the 74LS164
-bin_bcd() : take the bin value to bcd
-mostrar() : multiplex the 7 segments displays and read the DS1307
-TIMER 1 : Is called every 250mS, I used to control the colon and the reading rate of the DS1307.

The rest of the program is to set the time through the buttons.

In the other hand, your recomendation is something like this?
-mth,day,hr,min (local variables into the DS1307 driver library)
-mes,dia, hora, minutos (global variables into the main program

**In the read process
mes=mth;
day=dia;
hora=hr;
minutos=min;

**In the write process (like setting the time)
mth=mes;
day=dia;
hr=hora;
min=minutos;

By the way, how I upload the Proteus simulation to the forum?

Best regards.
_________________
From Cumaná, Venezuela.
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Wed Jun 24, 2015 1:10 am     Reply with quote

You don't.

If this is a problem in Proteus, they we don't want to hear about it. Read the sticky post at the top of the forum. The Proteus simulator is the cause of more wasted time than any other piece of software involved with the PIC. It'll tell you 'good' software can't work, and also tell you that designs can work, that have not got a hope of functioning on a real chip. Don't waste your time with it....
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

PostPosted: Wed Jun 24, 2015 5:27 am     Reply with quote

Ohhhh No, no,no! It's a real problem, real chip, real hardware, i was asking to upload the schematic of the circuit due to you requested more information.

So, what do you think about my proposal ?

Thanks in advance
_________________
From Cumaná, Venezuela.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Jun 24, 2015 5:50 am     Reply with quote

At initialisation you set dow=7
Then at start of main this is overwritten by a call to ds1307_get_date(day,mth,year,dow). Now dow contains a random value that was in the DS1307
You never change dow.
When the user changes the time, you write the random DOW value back to the chip.

How do you know the chip doesn't remember the day of the month?
Nowhere in your code do you use the value.
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

PostPosted: Wed Jun 24, 2015 6:21 am     Reply with quote

I used the "day" variable inside of the bin_bcd() and mostrar() sub functions.

So, do you think that the random value in the dow variable is the origin of the problem?

Ttelmah make me a warning advice when using the local variables of the driver in the main program.

void bin_bcd(){ //

if (TIMESET==1){
grup2=20;
grup1=year;
}
if ((TIMESET==2)||(estado==2)){
grup2=day;
grup1=mth;

}
if ((TIMESET==3)||(estado==1)){
grup2=prehr;
grup1=min;
}
copia=grup1;
dec= copia/10;
copia= copia%10;
uni=copia;
copia=grup2;
bdec= copia/10;
copia= copia%10;
buni=copia;
}

void mostrar(){
bin_bcd();
output_low(HAB4);
escribir(num[uni]);
output_high(HAB1);
if (leeds==0){
delay_ms(2);
}
if (leeds==1){
ds1307_get_date(day,mth,year,dow);
}
}
_________________
From Cumaná, Venezuela.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Jun 24, 2015 2:42 pm     Reply with quote

My mistake. First time I read your question as having problems with the Day Of Week instead of Day of month.

I tried following your code but it took too much of my time. Your code is difficult to follow.
Here are a few hints:
- Use English comments
- When you have parts consisting of more than 20 lines of code, then break them into multiple functions. Repeat until each function is maximum 20 lines.
- At the top of each function add little comment (in English) about what the function is doing. For example, for the timer interrupt it is great help when you write how often the interrupt is called each second.
- Try to use as little global variables as possible. Try to move them into the local function that uses them. This makes your code easier to read and saves memory.
- Convention is to only write constants and defines in all capital letters. Your variables like TIMESET and TS do not follow this rule.
- Instead of hard coded values like 'TIMESET==3' try to use defines or enums for better readability:
Code:
enum timeSet_t {
  SET_NONE = 0,
  SET_YEAR,
  SET_DAY,
  SET_MIN
};

enum timeSet_t timeSet;

...

if (timeSet == SET_YEAR) {
   ...
}
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 7:41 am     Reply with quote

Hi:

First of all, thanks for your time and help!

I couldn't understand the structure of the "enums". In the other hand, for a quick test, I erased the part of the program to set the time in the DS1307 and ran the code. The problem continues, so I keep confused about it.

Summarizing:

1.- I put global variables for the main program and local variables for the DS1307 chip.

2.- Corrected writing of random values of DOW variable

3-re-re-re-re-re-re-re checked the hardware (battery, pull-ups resistors).

Finally, a short video of the program in the real life.

https://www.youtube.com/watch?v=D6mpoEcyygQ&feature=youtu.be

Best regards from Venezuela

PS: Program with english comments and without the messy part of setting the time.

Code:
#include <16F873.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#BYTE TRISD=0x88
#BYTE PORTD=0x08
#include <math.h>
#include <ds1307todopic.c>
//////////////////////////////////////////////////// LOCAL & GLOBAL  VARIABLES
byte day=26,hr=22,sec=0,mth=6,year=15,min=0,dow=3;
byte dia=31;
byte diasem=7;
byte anno=15;
byte mes=12;
byte hora=23;
byte prehr=0,minutos=20,copia=0, time_set=0;
byte contaseg=0, estado=1,mipre=0,uni=0,dec=0,buni=0,bdec=0,grup1=0,grup2=0,lectoconta=0, daycarrier=0;
byte segundos=0;
int1 turnseg=0,setling=0,leeds=0;
byte const num[10]={238,6,220,158,54,186,250,14,254,62};
///////////////////////////////////////////////// PINOUT OF MICROCONTROLER
#define DATA      PIN_A1   
#define CLOCK     PIN_A0
#define RAYA      PIN_C1
#define SEGUNDERO PIN_C0
#define HAB1      PIN_C2
#define HAB2      PIN_C5
#define HAB3      PIN_C6
#define HAB4      PIN_C7
#define TS        PIN_B0
#define MINSET    PIN_B2
#define HORASET   PIN_B1
#define DIASET    PIN_B3
#define SETMES    PIN_B4
#define ANOSET    PIN_B5
#define AM        PIN_B6
#define PM        PIN_B7

void write_74(int8 aux){ //////// THIS FUNCTION IS USED TO WRITE THE 74LS164 (SERIAL-PARALLEL REGISTER)
   int i;
   for(i=0;i<8;i++)
    {
      if(bit_test(aux, i)==0)
      {
         output_low (DATA);
         output_low (CLOCK);
         output_high(CLOCK);
      }
      if(bit_test(aux,i)==1)
      {
         output_high(DATA);
         output_low (CLOCK);
         output_high(CLOCK);
      }
   }
} ///////////////////////////////END OF write_74

void bin_bcd(){ /////////////////binary to BCD
  if (hora==0){       
  prehr=12;
  output_low (PM); //PM OFF
  output_high (AM);   //AM ON
  }
  else if (hora==12){
  prehr=hora;
  output_low (AM); // AM OFF
  output_high (PM);   //PM ON
  }
  else if (hora>12){
  prehr=hora-12;
  output_low (AM); // AM OFF
  output_high (PM);   //PM ON
  }
  else{
  prehr=hora;
  output_low (PM); //PM OFF
  output_high (AM);   //AM ON
  }
if (time_set==1){ ///////////// This part is used to show time of date acording to "estado" variable.
grup2=20;
grup1=anno;
}
if ((time_set==2)||(estado==2)){
grup2=dow;
grup1=mes;
//grup1=daycarrier;
}
if ((time_set==3)||(estado==1)){
grup2=prehr;
grup1=minutos;
}
      copia=grup1;
      dec= copia/10;
      copia= copia%10;
      uni=copia;
      copia=grup2;
      bdec= copia/10;
      copia= copia%10;
      buni=copia; 
}   

void mostrar(){      /// Multiplexing of display
   bin_bcd();
   write_74(num[uni]); //Write the 74LS164
   delay_us (20);      //small time to avoid ghost
   output_high(HAB1);   //turn the 1 display
   if (leeds==0){      // "leeds" is a flag to decide if read or not the DS1307 chip
   delay_ms(2);
   }
   if (leeds==1){     // Read the DS1307
   ds1307_get_date(day,mth,year,dow);
   dia=day;           //local to global variable
   mes=mth;
   anno=year;
   }
   output_low(HAB1);
   write_74(num[dec]);
   delay_us(20);
   output_high(HAB2);
   if (leeds==1){
   ds1307_get_time(hr,min,sec);
   hora=hr;
   minutos=min;
   leeds=0;
   }
   if (leeds==0){
   delay_ms(2);
   }
   output_low(HAB2);
   write_74(num[buni]);
   delay_us(20);
   output_high(HAB3);
   delay_ms(2);
   output_low (HAB3);
   if((bdec>0))
   {
      write_74(num[bdec]);
      delay_us(20);
      output_high(HAB4);
      delay_ms(2);
      output_low (HAB4);
   }
   else
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      delay_ms(2);
   }
 
}
#INT_TIMER1
void temp1_isr() { /// Is called every 250mS
     
      if (mipre==2){    // This control the flag to turn ON/OFF the colon
      turnseg=!turnseg;
      mipre=0;
      }
     
      if (contaseg==20){ //This control how fast the display change to show HH:MM   DAY-MONTH
      contaseg=0;
      estado++;
      }
      if (estado>2){
      estado=1;
      }
      if (lectoconta==0){//This control de reading rate of the DS1307 chip
      lectoconta=20;
      leeds=1;
      }
      contaseg++;
      mipre++;
      lectoconta--;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(){ ///// MAIN PROGRAM
      set_tris_C(0b00000000);
      PORTD=0b00000000;
      disable_interrupts(global);
      output_low (SEGUNDERO);
      output_low (RAYA);
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
      set_timer1(3036);
      disable_interrupts(INT_TIMER1);
      delay_ms(1000);
      ds1307_init(DS1307_ALL_DISABLED); //INIT OF DS1307
      ////ds1307_set_date_time(day,mth,year,dow,hr,min,sec); ///<-- This line was udes to the time and date and later, I removed to no re-write data
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_TIMER1);

while (1){ ///infinite loop
mostrar(); /// Show data in display
 }
}//END OF THE MAIN

_________________
From Cumaná, Venezuela.
temtronic



Joined: 01 Jul 2010
Posts: 9205
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 10:30 am     Reply with quote

I suggest a test using 'dummy data' instead of reading the RTC.
With this known data, does the display correctly show all variables?
I'd try several values especially for the 'day' variable as that's the only one not functioning properly.

your mostrar() function should be split into two functions

1) the actual display function
and
2) the test to see if you should read the RTC.
Actually I'm not sure why you need this test. Simply get the RTC data every time you update the display.

Jay
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 10:41 am     Reply with quote

Hi,

Please post a clear, in focus picture of your hardware. I suspect you have a problem with your circuit!

John
Ttelmah



Joined: 11 Mar 2010
Posts: 19454

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 11:14 am     Reply with quote

If he is keeping all the other clock values OK, then I doubt if there is a hardware problem.

However there is a big problem in overall 'messiness', and abusing the way that parameters are actually referenced.
The key is he needs to step back, simplify, and use one part at a time. Temtronic has suggested a good way to start 'back', and doing this would allow things to be 'narrowed down'.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 11:32 am     Reply with quote

Hi,

My suspicion is that the "hardware problem" is that there is no hardware, and this is a Proteus project. On everything else I agree whole-heartedly Very Happy

John
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 12:02 pm     Reply with quote

ezflyr wrote:
Hi,

My suspicion is that the "hardware problem" is that there is no hardware, and this is a Proteus project. On everything else I agree whole-heartedly Very Happy

John


Hi, in the beginning of the post, I mention that's a REAL hardware. In proof of that, I upload a video and now, a picture of the circuit. NO Proteus!!

VIDEO: https://www.youtube.com/watch?v=D6mpoEcyygQ&feature=youtu.be

PICTURE:


Ttelmah wrote:
step back, simplify, and use one part at a time.


I did it.. Also find out that DAY OF THE WEEK doesn't keep.. always back from DS1307 like 7.

Thanks in advance
_________________
From Cumaná, Venezuela.
AnthonyRFC



Joined: 21 Jun 2015
Posts: 16
Location: Venezuela

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 12:11 pm     Reply with quote

PS: The battery and buttons are located in a different PCB.


I think, there is possibility of a bug in compiler? I have Version 4.104
_________________
From Cumaná, Venezuela.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group