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 CCS Technical Support

format problems with the DS1307

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

format problems with the DS1307
PostPosted: Mon Aug 10, 2009 11:43 am     Reply with quote

Hi, I am using the DS1307 to activate an alarm. I read the register time of DS1307 (hrs,min,sec) to compare with the values stored in the EEprom (from address 200). To do it I am trying to convert all to seconds.

RTC = ((hrs *3600)+(min*60)+sec)

Code:
RTC = ((hrs * 0x0E10) + (min * 0x03C) + (sec * 0X01))

Code:
Alarma = ((Alar_hrs * 0x0E10) + (Alar_min * 0x03C) + (Alar_sec * 0X01))


My problem is I can not get the correct values of RCT and Alarm to do comparison.

Here is my code:
Code:

#include <18F452.h>
#include <string.h>
#include <stdlib.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define RTC_SDA     PIN_C4
#define RTC_SCL     PIN_C3

#define SIRENA    PIN_D0
#define Alarma_ON  output_high
#define Alarma_OFF output_low

#include <DS1307x.h>

char Alarma_Seg[] = "00";
char Alarma_Min[] = "30";
char Alarma_Hrs[] = "23";
int i;
int8 sec ;
int8 min ;
int8 hrs ;

int16 Alar_sec;
int16 Alar_min;
int16 Alar_hrs;

int32 Alarma;
int32 RTC;
int32 var1;
int32 var2;

char Buffer_Seg[3];
char Buffer_Min[3];
char Buffer_Hrs[3];

#INT_EXT
void IntRB0()
{
      ds1307_get_time(hrs,min,sec);
}

void Init_Alarma_EEprom(){

       for (i = 0; i< 2; i++) write_eeprom( 210+i, Alarma_Seg[i]);
       for (i = 0; i< 2; i++) write_eeprom( 212+i, Alarma_Min[i]);
       for (i = 0; i< 2; i++) write_eeprom( 214+i, Alarma_Hrs[i]);
}

void Compara_RTC_Alarma(){

       for (i = 0; i< 2; i++){ Buffer_Seg[i] = read_eeprom(210+i);
            Alar_sec = atoi(Buffer_Seg);}
       for (i = 0; i< 2; i++){ Buffer_Min[i] = read_eeprom(212+i);
            Alar_min = atoi(Buffer_Min);}
       for (i = 0; i< 2; i++){ Buffer_Hrs[i] = read_eeprom(214+i);
            Alar_hrs = atoi(Buffer_Hrs);}

       RTC = ((hrs * 0x0E10) + (min * 0x03C) + (sec * 0X01));
       var1 = printf("%lx \n\r ", RTC);

       Alarma = ((Alar_hrs * 0x0E10) + (Alar_min * 0x03C) + (Alar_sec * 0X01));
       var2 = printf("%lx \n\r ", Alarma);

       if (var2 >= var1)
          Alarma_ON(SIRENA);
       else
          Alarma_OFF(SIRENA);
      
}
   
void main() {

      enable_interrupts(int_ext);      
      ext_int_edge(H_TO_L);         
      enable_interrupts(GLOBAL);      
      Init_Alarma_EEprom();

      ds1307_init();
      Delay_ms(300);

while (TRUE){

       Compara_RTC_Alarma();
   
    }   
}

Este es el include


Código:


the include also

Code:
********************************************************
*                               DS1307.C                                          *
*                   Driver para el Time Clock DS1307             *
********************************************************/

#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3

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

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(0xD0);                  // WR to RTC
   i2c_write(0x00);                  // REG 0
   i2c_start();
   i2c_stop();

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);                  // WR to RTC
   i2c_write(0x00);                  // REG 0
   i2c_write(0x00);
   i2c_write(0x00);                  // WR to RTC
   i2c_write(0x00);                  // WR to RTC
   i2c_write(0x00);                  // WR to RTC
   i2c_write(0x00);                  // WR to RTC
   i2c_write(0x00);                  // WR to RTC
   i2c_write(0x00);                  // Control Register
   i2c_write(0x10);                  // Disable squarewave output pin
   i2c_stop();

}

void ds1307_set_time(BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);                     // I2C write address
  i2c_write(0x00);                     // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));            // REG 0
  i2c_write(bin2bcd(min));            // REG 1
  i2c_write(bin2bcd(hr));               // REG 2
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);                     // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
 
 
 Reportar al moderador    190.41.129.227 
 
 
 
 
Páginas: [1] 
 
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 10, 2009 12:51 pm     Reply with quote

You had this problem before, in this thread, where we went through it
with you:
http://www.ccsinfo.com/forum/viewtopic.php?t=39825

You need to learn an important thing about Math calculations in CCS.
CCS does not always promote the variable size to the required size
to hold the complete result. You often need to tell the compiler to do
this. Remember that idea. It's important.

Make a short test program to study the problem. You need to learn
to do that, also. Here's the program:
Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//======================================
void main(void)
{
int8 min;
int32 RTC;

min = 35;

RTC = min*60;

printf("RTC = %lu\n\r", RTC);

while(1);
}

Here is the result, and it is not correct:
Quote:
RTC = 52


What can be done to fix this ? In the program above, if you multiply
35 * 60 the result is 2100. Both of the values in the equation are byte
values. They are less than 256. So they can fit in a byte.
But the value of 2100 requires a 16-bit variable to hold it.

Important idea:
CCS does not automatically promote the intermediate result to a 16-bit
value. That's the reason for the problem. You can fix it by promoting
one of the values in the equation by yourself. You can "cast" the 'min'
variable to an int16, or you can make the '60' into a "long" value by
putting an 'L' on the end. Examples:
Code:
RTC = (int16)min * 60;

or
Code:
RTC = min * 60L;

Either of these methods will fix the problem. The result will now be
correct for this calculation:
Quote:
RTC = 2100
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Mon Aug 10, 2009 2:55 pm     Reply with quote

Hi PCM programmer, Very Happy thank you very much for your help, my program is run OK..
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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