Hola agradece sus respuestas, por lo que me comentan estoy setenado de forma correcta el registro por lo que ahora ya no se que pasa.
Aislando mi programa e detectado que cuando seteo un BIT del registro me modifica el dato completo y no encuentro como resolver esto.
Intentare explicarme.
El registro 0x02h es el registro de la hora , pero también este registro cumple otra función el bit 6 configura la hora en modo 12/24hs 0=24HS 1=12HS pues bien cuando escribo este registro así: hours=22; no tengo problema leo la hora bien
Pero cuando modifico el bit=6 a 1 para el modo 12hs así: hours=22, bit_set(hours,6), la lectura de la hora es incorrecta en lugar de leer 10pm(22hs) me da 6 hs
Y lo mismo me pasa con todos los registros que operan así (que tienen doble función.)
Este es el problema por el cual las alarmas no se activan ya que si al setear un bit del registro me modifica el dato de la hora la alarma nunca va a coincidir.
No tengo ni jodida de por que hace esto
////////////////////////////////////////////////////////////////////////////////
// //
// ds1337.c //
// //
// void ds1337_config (void) //
// //
// void DS1337_write_byte(int8 address, int8 data) //
// //
// int8 DS1337_read_bytes(int8 address) //
// //
// void DS1337_set_datetime() //
// //
// void ds1337_set_alarma1(void) //
// //
// void ds1337_set_alarma2(void) //
// //
//////////////////////////////////////////////////////////////////////////////
#define DS1337_SDA PIN_C4
#define DS1337_SCL PIN_C3
#use i2c(master, sda=DS1337_SDA, scl=DS1337_SCL,fast=400000,force_hw)
// i2c addresses
#define DS1337_I2C_WRITE_ADDR 0xD0
#define DS1337_I2C_READ_ADDR 0xD1
// DS1337 register addresses
#define DS1337_SECONDS_REG 0x00
#define DS1337_MINUTES_REG 0x01
#define DS1337_HOURS_REG 0x02
#define DS1337_DAY_OF_WEEK_REG 0x03
#define DS1337_DATE_REG 0x04
#define DS1337_MONTH_REG 0x05
#define DS1337_YEAR_REG 0x06
//DS1337 Unique Registers
#define DS1337_ALM1_SECONDS_REG 0x07
#define DS1337_ALM1_MINUTES_REG 0x08
#define DS1337_ALM1_HOURS_REG 0x09
#define DS1337_ALM1_DAYDATE_REG 0x0A
#define DS1337_ALM2_MINUTES_REG 0x0B
#define DS1337_ALM2_HOURS_REG 0x0C
#define DS1337_ALM2_DAYDATE_REG 0x0D
#define DS1337_CONTROL_REG 0x0E
#define DS1337_STATUS_REG 0x0F
//opcion1= Enable Oscillator, Disable SQWV, Disable Ints
#define DS1337_CTRL_REG_INIT_VAL 0x04
//opcion2= enable oscillator,disable sqwv,enable ints
#define DS1337_CTRL_REG_INIT_VAL2 0x01 //valor 0x07
//Clear OSF (Oscillator Stop Flag), A2F (Alarm 2 Flag), and A1F (Alarm 1 Flag)
#define DS1337_CLEAR_STATUS_VAL 0x00
////////////////////// variables clok ////////////////////////
int8 seconds; // 0 to 59
int8 minutes; // 0 to 59
int8 hours; // 0 to 23 (24-hour time)
int8 day; // 0 = Sunday, 1 = Monday, etc.
int8 date; // 1 to 31
int8 month; // 1 to 12
int8 year; // 00 to 99
///////////////////// variables alarma1 ////////////////////////////////
int8 seconds_alm1; // 0 to 59
int8 minutes_alm1; // 0 to 59
int8 hours_alm1; // 0 to 23 (24-hour time)
int8 day_alm1; // 1 = Sunday, 2 = Monday, etc.
//////////////////// variables alarma2 //////////////////////////////////
//int8 seconds_alm2; // 0 to 59
int8 minutes_alm2; // 0 to 59
int8 hours_alm2; // 0 to 23 (24-hour time)
int8 day_alm2; // 0 = Sunday, 1 = Monday, etc.
//---------------------------------------------------
//configurar ds1337
void ds1337_config (void){
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(DS1337_SECONDS_REG);
i2c_write(0x00); //seconds
i2c_write(0x00); //minutes
i2c_write(0x40); //hours & 12/24 hour mode
i2c_write(0x01); //day
i2c_write(0x01); //date
i2c_write(0x01); //month
i2c_write(0x00); //year
i2c_write(0x00); //alm1 seconds
i2c_write(0x00); //alm1 minutes
i2c_write(0x00); //alm1 hours
i2c_write(0x00); //alm1 day/date
i2c_write(0x00); //alm2 minutes
i2c_write(0x00); //alm2 hours
i2c_write(0x00); //alm2 day/date
i2c_write(DS1337_CTRL_REG_INIT_VAL2); //Turn off the squarewave output pin.
//i2c_write(DS1337_CLEAR_STATUS_VAL); //Clear the status registers
i2c_stop();
enable_interrupts(GLOBAL);
//disable_interrupts(GLOBAL);
//i2c_start();
//i2c_write(DS1337_I2C_WRITE_ADDR);
//i2c_write(DS1337_CONTROL_REG );
//i2c_write(DS1337_CTRL_REG_INIT_VAL2); //
//i2c_write(DS1337_CLEAR_STATUS_VAL); //
//i2c_stop();
//enable_interrupts(GLOBAL);
}
//----------------------------------------------
void DS1337_write_byte(int8 address, int8 data) {
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(address);
i2c_write(data);
i2c_stop();
enable_interrupts(GLOBAL);
}
//----------------------------------------------
int8 DS1337_read_bytes(int8 address) { //<-----------------------1
int8 retval;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(address);
i2c_start();
i2c_write(DS1337_I2C_READ_ADDR);
retval = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
return(retval);
}
//----------------------------------------------
// This function converts an 8 bit binary value
// to an 8 bit BCD value.
// The input range must be from 0 to 99.
int8 bin2bcd(int8 value) {
char retval;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(value >= 10)
{
value -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += value;
break;
}
}
return(retval);
}
//----------------------------------------------
// This function converts an 8 bit BCD value to
// an 8 bit binary value.
// The input range must be from 00 to 99.
char bcd2bin(char bcd_value) {
char temp;
temp = bcd_value;
// Shifting the upper digit right by 1 is
// the same as multiplying it 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));
}
//----------------------------------------------
void DS1337_set_datetime() {
int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_day;
int8 bcd_date;
int8 bcd_mon;
int8 bcd_year;
// Convert the input date/time into BCD values
// that are formatted for the DS1337 registers.
bcd_sec = bin2bcd(seconds);
bcd_min = bin2bcd(minutes);
bcd_hrs = bin2bcd(hours); //default to 24 hour mode
bcd_day = bin2bcd(day);
bcd_date = bin2bcd(date);
bcd_mon = bin2bcd(month); //ignore century bit
bcd_year = bin2bcd(year);
// Write to the date and time registers. Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(DS1337_SECONDS_REG); // Start at seconds register
i2c_write(bcd_sec);
i2c_write(bcd_min);
i2c_write(bcd_hrs);
i2c_write(bcd_day);
i2c_write(bcd_date);
i2c_write(bcd_mon);
i2c_write(bcd_year);
i2c_stop();
enable_interrupts(GLOBAL);
}
//----------------------------------------------
//setear alarma1_ds1337
void ds1337_set_alarma1(void){
int8 bcd_sec_alm1;
int8 bcd_min_alm1;
int8 bcd_hrs_alm1;
int8 bcd_day_alm1;
// Convert the input date/time into BCD values
// that are formatted for the DS1337 registers.
bcd_sec_alm1 = bin2bcd(seconds_alm1);
bcd_min_alm1 = bin2bcd(minutes_alm1);
bcd_hrs_alm1 = bin2bcd(hours_alm1); //default to 24 hour mode
bcd_day_alm1 = bin2bcd(day_alm1);
// Write to the date and time registers. Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(DS1337_ALM1_SECONDS_REG); // Start at seconds register
i2c_write(bcd_sec_alm1);
i2c_write(bcd_min_alm1);
i2c_write(bcd_hrs_alm1);
i2c_write(bcd_day_alm1);
i2c_stop();
enable_interrupts(GLOBAL);
}
// setear alarma2_max6958
void ds1337_set_alarma2(void){
//int8 bcd_sec_alm2;
int8 bcd_min_alm2;
int8 bcd_hrs_alm2;
int8 bcd_day_alm2;
// Convert the input date/time into BCD values
// that are formatted for the DS1337 registers.
//bcd_sec_alm2 = bin2bcd(seconds_alm2);
bcd_min_alm2 = bin2bcd(minutes_alm2);
bcd_hrs_alm2 = bin2bcd(hours_alm2); //default to 24 hour mode
bcd_day_alm2 = bin2bcd(day_alm2);
// Write to the date and time registers. Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(DS1337_ALM2_MINUTES_REG ); // Start at minutes register
i2c_write(bcd_min_alm2);
i2c_write(bcd_hrs_alm2);
i2c_write(bcd_day_alm2);
i2c_stop();
enable_interrupts(GLOBAL);
}
//----------------------------------------------
// Read the Date and Time from the hardware registers
// in the DS1337.
void DS1337_read_datetime() {
int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_day;
int8 bcd_date;
int8 bcd_mon;
int8 bcd_year;
// Disable interrupts so the i2c process is not disrupted.
disable_interrupts(GLOBAL);
// Read the date/time registers from the DS1337.
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(DS1337_SECONDS_REG); // Start at seconds register
i2c_start();
i2c_write(DS1337_I2C_READ_ADDR);
bcd_sec = i2c_read();
bcd_min = i2c_read();
bcd_hrs = i2c_read();
bcd_day = i2c_read();
bcd_date = i2c_read();
bcd_mon = i2c_read();
bcd_year = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
// Convert the date/time values from BCD to
// unsigned 8-bit integers. Unpack bits in
// DS1337 registers where required.
seconds = bcd2bin(bcd_sec & 0x7F);
minutes = bcd2bin(bcd_min & 0x7F);
hours = bcd2bin(bcd_hrs & 0x3F);
day = bcd2bin(bcd_day & 0x07);
date = bcd2bin(bcd_date & 0x3F);
month = bcd2bin(bcd_mon & 0x1F);
year = bcd2bin(bcd_year);
}
//----------------------------------------------
//If there has been an oscillator failure since last
//init, then init DS1337. A default time and date is set as well.
void DS1337_init(void) {
int8 temp = 0;
//Read the status register to see if the oscillator has failed.
temp = DS1337_read_bytes(DS1337_STATUS_REG);//<-------------------2
//Unpack OSF bit
temp = temp >> 7;
//If oscillator has failed then init DS1337
if(temp) {
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(DS1337_I2C_WRITE_ADDR);
i2c_write(DS1337_SECONDS_REG);
i2c_write(0x00); //seconds
i2c_write(0x00); //minutes
i2c_write(0x40); //hours & 12/24 hour mode
i2c_write(0x00); //day
i2c_write(0x01); //date
i2c_write(0x01); //month
i2c_write(0x06); //year
i2c_write(0x00); //alm1 seconds
i2c_write(0x00); //alm1 minutes
i2c_write(0x00); //alm1 hours
i2c_write(0x00); //alm1 day/date
i2c_write(0x00); //alm2 minutes
i2c_write(0x00); //alm2 hours
i2c_write(0x00); //alm2 day/date
i2c_write(DS1337_CTRL_REG_INIT_VAL); //Turn off the squarewave output pin.
i2c_write(DS1337_CLEAR_STATUS_VAL); //Clear the status registers
i2c_stop();
enable_interrupts(GLOBAL);
}
}
#include <16f877a.h>
#fuses HS,NOWDT,NOLVP,NOPROTECT,NOPUT,NOBROWNOUT,NODEBUG
#use delay(clock=20000000)
#org 0x1eaf, 0x1FFF void loader16F877A(void) {} //protect bootloader code for the 8k 16F876/7
#include <ds1337.c>
////////////////////////////////////////////////////////////////////////////////
// Canal de Comunicación : usart
////////////////////////////////////////////////////////////////////////////////
#define TTL_TX PIN_C6
#define TTL_RX PIN_C7
#use rs232(baud=9600, xmit=TTL_TX, rcv=TTL_RX)
VOID MAIN (VOID){
int8 data,dia_s;
set_tris_b(0b11111111);
set_tris_a(0b00000000);
setup_adc_ports(NO_ANALOGS);
ds1337_config();
year=9;
month=12;
date=10;
day=3;
hours=22;
bit_set(hours,6); // Setea bit 6 del registro 02h para cambiar a modo 12hs
seconds=40;
minutes=30;
DS1337_set_datetime();
hours_alm1=22;
minutes_alm1=31;
seconds_alm1=50;
day_alm1=3;
ds1337_set_alarma1();
while(1){
DS1337_read_datetime(); // leer rtc
data=hours*1000; //Convertir a long hora y minutos
data=data/10;
data=data+minutes;
dia_s=day;
printf("HS:%u",hours);
printf(" MIN:%u",minutes);
printf(" SEC:%u",seconds);
printf(" day:%u",day);
printf(" fecha:%u",date);
printf(" mes:%u",month);
printf(" ano:%u\n\r",year);
printf("HS_A1:%u", hours_alm1);
printf(" MIN_A1:%u", minutes_alm1);
printf(" SEC_A1:%u",seconds_alm1 );
printf(" DAY_A1:%u \n\r",day_alm1 );
delay_ms(1000);
}
}