Buenos días compañeros:
Mi problema con el DS1307 no es para que arranque sino para que guarde el día del mes, los demás datos como hora, mes, año permanecen intactos al retirar la alimentación de 5V.
He intentado de todo: revisé las resistencias pull-up, medir el voltaje de la batería, cambiar el integrado y cambiar la librería (estoy usando la de acá del foro) pero todas dan el mismo problema. ¿Alguien lo ha tenido?
Adjunto código y librería:
CÓDIGO
#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
LIBRERÍA
///////////////////////////////////////////////////////////////////////////////////////
/// 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));
}
Saludos y gracias!