|
|
View previous topic :: View next topic |
Author |
Message |
pilar
Joined: 30 Jan 2008 Posts: 197
|
format problems with the DS1307 |
Posted: Mon Aug 10, 2009 11:43 am |
|
|
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
|
|
Posted: Mon Aug 10, 2009 12:51 pm |
|
|
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:
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
Either of these methods will fix the problem. The result will now be
correct for this calculation:
|
|
|
pilar
Joined: 30 Jan 2008 Posts: 197
|
|
Posted: Mon Aug 10, 2009 2:55 pm |
|
|
Hi PCM programmer, thank you very much for your help, my program is run OK.. |
|
|
|
|
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
|