# Reloj con DS1307 no arranca en la práctica



## juanc08 (Jul 14, 2012)

Muy buenas tardes a todos,
primera vez que escribo  y es para preguntar , mil disculpas pero como dicen quien no pregunta nunca aprende
monte en proteus el reloj con ds1307 y corre perfectamente,pero al pasar al protoboard no arranca , porlo que he leido me falta iniciar el ds1307 con el bit 7 ch=0,pero ese es problema parami donde lo inserto en el programa 

adjunto el programa en proton es el que  medio he  aprendido a usar  AGRADECERE LA AYUDA


```
Device 16F628A
 Config  INTRC_OSC_NOCLKOUT,WDT_OFF,PWRTE_ON,CP_OFF,BODEN_OFF,LVP_OFF,MCLRE_OFF
CMCON=7 
TRISB=%11
TRISA =%111 ;el puerto A.0 es de entrada
define lcd_dreg PORTB
define lcd_dbit 4
define lcd_rsreg PORTB
define lcd_rsbit 3
define lcd_ereg
define lcd_ebit 2
define I2C_SCLOUT 1 ;para que no necesite resistencia pull-up en SCL
CPIN VAR PORTA.1 ;pin señal de reloj I2C
DPIN VAR PORTA.0 ;pin de datos I2C

segu VAR Byte ;definir tamaño de variable segundos 1 a 255
minu VAR Byte ;variable para los minutos
hora VAR Byte ;variable para las horas
diaS VAR Byte ;variable día de la semana
diaF VAR Byte ;variable día fecha del mes
mes VAR Byte ;variable mes
anio VAR Byte ;variable año de 2 dígitos
actualizado VAR Bit ;variable para almacenar un 1 o 0
EData 0, 0 ;memoria 0 con el valor inicial 0, sirve para
          ;indicar que nunca ha corrido este programa
actualizado=ERead 0 ;carga el valor de la memoria EEPROM dirección 0
If actualizado =0 Then grabarRTC ;si es la 1ra vez que corre ir a grabar RTC
;caso contrario sólo leer el RTC


INICIO:

I2Cin DPIN,CPIN,%11010000,0,[segu] ;leer los datos de mem. 0,
I2Cin DPIN,CPIN,%11010000,1,[minu] ;1,2,..y guardarlos en sus
I2Cin DPIN,CPIN,%11010000,2,[hora] ;respectivas variables
I2Cin DPIN,CPIN,%11010000,3,[diaS]
I2Cin DPIN,CPIN,%11010000,4,[diaF]
I2Cin DPIN,CPIN,%11010000,5,[mes]
I2Cin DPIN,CPIN,%11010000,6,[anio]
Print $fe,1, HEX2 hora,":", HEX2 minu,":", HEX2 segu,
Print $fe,$c0 ;saltar a la 2da línea del LCD
;mostrar día de la semana

If diaS=$1 Then Print "Dom."
If diaS=$2 Then Print "Lun."
If diaS=$3 Then Print "Mar."
If diaS=$4 Then Print "Mie."
If diaS=$5 Then Print "Jue."
If diaS=$6 Then Print "Vie."
If diaS=$7 Then Print "Sab."

Print $fe,$c5, HEX2 diaF,"/" ;mostrar el día del mes /
Print $fe,$cB,"/20", HEX2 anio ; mostrar año /20 + 04
Print $fe,$c8 ;pasar a la casilla 8

If mes=$1 Then Print "ene" ;mostrar el mes
If mes=$2 Then Print "feb"
If mes=$3 Then Print "mar" 
If mes=$4 Then Print "abr"
If mes=$5 Then Print "may"
If mes=$6 Then Print "jun"
If mes=$7 Then Print "jul"
If mes=$8 Then Print "ago"
If mes=$9 Then Print "sep"
If mes=$10 Then Print "oct"
If mes=$11 Then Print "nov"
If mes=$12 Then Print "dic"
 DelayMS 500

GoTo INICIO

 ; ************************ subrutina grabar *********************
grabarRTC:

I2Cout DPIN,CPIN,%11010000,0,[$00] ;setear 00 segundos
DelayMS 10 ;retardo para finalizar grabación
I2cout DPIN,CPIN,%11010000,1,[$30] ;setear 30 minutos
DelayMS 10
I2Cout DPIN,CPIN,%11010000,2,[$22] ;setear las 13 horas
DelayMS 10
I2Cout DPIN,CPIN,%11010000,3,[$3] ;setear día lunes, D=1,L=2
DelayMS 10 ;M=3, M=4, J=5, V=6, S=7
I2Cout DPIN,CPIN,%11010000,4,[$12] ;setear día 27 del mes
DelayMS 10
I2Cout DPIN,CPIN,%11010000,5,[$6] ;setear mes septiembre
DelayMS 10
I2Cout DPIN,CPIN,%11010000,6,[$12] ;setear año 04
DelayMS 10
I2Cout DPIN,CPIN,%11010000,7,[$10] ;control %00010000 para
DelayMS 10 ;encender el led cada 1 seg.
EWrite 0,[1] ;escribe en la memoria 0 el valor de 1 para que no
;se vuelva a grabar otra vez estos datos en el RTC


GoTo INICIO ;ir a presentar los datos en el LCD
```


----------



## D@rkbytes (Jul 14, 2012)

juanc08 dijo:


> Muy buenas tardes a todos,
> primera vez que escribo  y es para preguntar , mil disculpas pero como dicen quien no pregunta nunca aprende
> monte en proteus el reloj con ds1307 y corre perfectamente,pero al pasar al protoboard no arranca , porlo que he leido me falta iniciar el ds1307 con el bit 7 ch=0,pero ese es problema parami donde lo inserto en el programa


Saludos juanc08.
Revise el programa que adjuntas, y existen varias cosas por modificar.
La sintaxis que usas en algunas partes del programa, son para MCS con PICBasic Pro.
Y se supone que el programa esta escrito para usar el PICBasic de Proton.
Así que debes de empezar por corregir esos detalles.

En el programa existen variables que no están declaradas.
La configuración del LCD para Proton es diferente a la que usas, y otros detalles más.

Por aquí en el foro existe un tutorial de Proton.* [Tutorial] y manejo de proton IDE*
Dale una leída y posteriormente realiza las correcciones necesarias a tu programa.

En cuanto al DS1307, también hay que realizar algunos cambios al programa para que funcione.

Suerte.


----------



## juanc08 (Jul 14, 2012)

hola amigo
te agradezco tu respuesta , agradeceria medijeras lo que hay que corregir en la programacion del ds1307 para que ala hora de montarlo en el protoboard me funcione ,adjunto el .bas y el .dsn
veras que funciona en proteus


----------



## D@rkbytes (Jul 15, 2012)

juanc08 dijo:


> hola amigo
> te agradezco tu respuesta , agradeceria medijeras lo que hay que corregir en la programacion del ds1307 para que ala hora de montarlo en el protoboard me funcione ,adjunto el .bas y el .dsn
> veras que funciona en proteus


Saludos nuevamente juanc08
No dudo que funcione en el simulador, muchas cosas funcionan en el, y en la realidad no.
Este programa hay que tomarlo por pasos, ya que el programa que adjuntas,
es un programa en el cual muchos programas para PICBasic están basados.
Y he visto varias adaptaciones del programa que adjuntas, para otros PIC.

En tu diseño, aparte de querer tener un calendario con RTC, también quieres implementar un termómetro.
Con el PIC que usas (PIC16F628A) Eso no es posible directamente.
Ya qué el 16F628A no tiene ningún conversor de analógico a digital.
Este PIC solo tiene comparadores analógicos.
Por lo tanto, la lectura del LM35 en tu proyecto no podrá ser leída directamente por el PIC.
(Programa no la incluye, diseño si)
Para eso bien podrías usar un PIC16F88 y caso LM35 resuelto, con sus correspondientes rutinas.
PIC16F88 + DS1307 + LM35 = True 

Si miras bien tu programa verás que al iniciar graba la EEPROM del PIC con una variable tipo Flag.
Para indicar si el programa es por primera vez ejecutado o no. Y pasa a escribir los datos iniciales.
Después continúa con un Loop. Esa escritura y su verificación se tiene que modificar o eliminar.
Lo que se debe hacer es establecer datos iniciales y posteriormente poder actualizarlos.
Esto no está en tu programa. Pero en otros basados en tal programa, si tienen esta posibilidad.

Resumiendo diseño y programa, adjunto las correspondientes modificaciones en *.DSN y *.BAS
Esperando funcione realmente con Proton. Ya qué el proyecto para el DS1307 lo tengo en ensamblador.

Suerte.


----------



## juanc08 (Jul 15, 2012)

nome cansare de agradecer tus respuestas, me dispongo a probar el circuito y estamos en contacto



amigo d@arkbytes con el programa que me enviaste me corre de maravilla en el protoboard


----------



## D@rkbytes (Jul 15, 2012)

juanc08 dijo:


> nome cansare de agradecer tus respuestas, me dispongo a probar el circuito y estamos en contacto
> 
> 
> 
> amigo d@arkbytes con el programa que me enviaste me corre de maravilla en el protoboard


Perfecto!. 
Ahora solo te resta agregar las opciones para poder modificar los datos.

En lo que te podamos ayudar, cuenta con ello.

Mucha suerte y hasta pronto.


----------



## andreslg06 (Nov 15, 2012)

Estoy realizando un proyecto de un reloj digital programable con alarmas para una escuela 
estoy utilizando un rtc, lcd 16x2 y un pic 16f628A , el problema esta en los incrementos de las horas y minutos cuando llega al numero 10 decimal en la lcd sale en hexadecimal (hex2) 
tanto en horas y minutos sucede lo mismo , el otro problema es poner el rtc en modo de 12 horas pongo el bit 6 en modo de 12 horas pero en la simulación sigue estando en 24 horas.


----------



## ricbevi (Nov 15, 2012)

andreslg06 dijo:


> estoy realizando un proyecto de un reloj digital programable con alarmas para una escuela
> estoy utilizando un rtc, lcd 16x2 y un pic 16f628A , el problema esta en los incrementos de las horas y minutos cuando llega al numero 10 decimal en la lcd sale en hexadecimal (hex2)
> tanto en horas y minutos sucede lo mismo , el otro problema es poner el rtc en modo de 12 horas pongo el bit 6 en modo de 12 horas pero en la simulación sigue estando en 24 horas.



Hola...revisa la hoja de datos del DS1307 y mira aquí  https://www.forosdeelectronica.com/tutoriales/conversion-codigos.htm en la parte BCD que es el formato que trabaja el RTC por eso es que todo te funciona bien hasta el numero decimal 9 porque solo hasta ahí es igual la representación decimal y la BCD.
Saludos.

Ric.


----------



## zoomg80 (Dic 26, 2012)

Hola muchachos yo tambien trabajo con el DS1307 y funciona correctamente, mi programacion esta en CCS y en la simulacion funciona al igual que el el circuito armado, Mi problema es que estaba trabajando desde las 16:50:00 hasta las 17:30:20 y de repente se sallto la hora a las 19:51:85
en esta ultima hora ya no avanza. incluyo mi codigo aunque no creo que el problema este aqui. Mi cristal del DS1307 esta aterrizado a tierra desde la carcasa. 
Saludos cordiales


```
// Cicuito lee reloj tiempo real y temperatura con LM35
#include <16F876A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#device adc=10
#use delay(clock=4000000)
#use standard_io(a)
#use standard_io(c)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)
#define RELAY1 PIN_C0
#define RELAY2 PIN_C1
#define RELAY3 PIN_C2
#define LED    PIN_C5

#include<lcd.c>
#include<_ds1307.c>
int hr,min,sec,day,mth,year,dow;
float temper, medicion;

void caratula(){
 printf(lcd_putc,"\f");
 ds1307_get_time(hr,min,sec);
 ds1307_get_date(day,mth,year,dow);
 lcd_gotoxy(1,1);
 printf(lcd_putc,"Fecha:%2u/%2u/%2u",day,mth,year);
 lcd_gotoxy(1,2);
 printf(lcd_putc,"Hora:%2u:%2u:%2u",hr,min,sec);
 delay_ms(800);
}
void medicion_temp(){
printf(lcd_putc,"\f");
lcd_putc("Temperatura\n");
lcd_gotoxy(12,2);
lcd_putc("C");
lcd_gotoxy(8,2); //Acomoda el cursor
lcd_putc("");    //Limpia el sector de pantalla
lcd_gotoxy(8,2); //Acomoda el cursor
medicion=read_adc();
temper=medicion*(0.48875);  //Pasa Binario a C
printf(lcd_putc,"%02.1f",temper);
delay_ms(2000);
}
void main(){ 
 enable_interrupts(global);              //Habilita las interrupciones globales
 setup_adc(adc_clock_internal);
 setup_adc_ports(all_analog);
 set_adc_channel(0);                     //Elige canal a medir A/D RA0
 lcd_init();                             //Inicializa el LCD           
 ds1307_init();                          //Inicializa el Reloj
 printf(lcd_putc,"\f");
 lcd_gotoxy(2,1);
 printf(lcd_putc,"GRUPO  NUBECOR");
 lcd_gotoxy(3,2);
 printf(lcd_putc,"Reloj y Fecha");
 delay_ms(2000);   
 printf(lcd_putc,"\f");
 int cont=0;
while(1){
for(cont=0; cont<=5; cont++){
caratula();
}
cont=0;  
 medicion_temp();
 }
}
```


----------



## D@rkbytes (Dic 27, 2012)

Saludos.
Te has olvidado colocar un esquema de tu proyecto, así como también incluir la librería que utilizas.
Es recomendable que siempre coloquen sus esquemas, ya que no somos adivinos. Normas del Foro 03 y 12

Por si en dado caso fuera algún problema de software, "librería o programa", aquí adjunto un ejemplo.
Está realizado con una librería directa de CCS para trabajar con el DS1307
El código para el sensor LM35 ya es cosecha mía. 

Espero te sirva y suerte con tu proyecto.


----------



## anthony123 (Ene 10, 2013)

Como podemos agregar esta librería al copilador C? O cada vez que valla a realizar un programa debo copiarla?

Saludos!


----------



## D@rkbytes (Ene 10, 2013)

anthony123 dijo:


> Como podemos agregar esta librería al copilador C? O cada vez que valla a realizar un programa debo copiarla?
> 
> Saludos!


Saludos.
Si alguna librería la vas a utilizar en varios proyectos, puedes agregarla dentro de la carpeta  Drivers.
Así ya no tienes que copiar la o las librerías dentro de cada carpeta de proyecto.
Esta carpeta se encuentra en el directorio de instalación del PCWHD Compiler de CCS

Suerte.


----------



## ignaciolin4 (Oct 3, 2013)

Buenas amigos, ya les he escrito antes y estoy muy agradecido con su ayuda.
Esta vez les escribo por otra duda. Tengo un código en ensamblador que conseguí en internet sobre como leer y escribir un ds1307 en un pic 16f877a, el programa funciona perfecto hasta que se le modifica algo que ya voy a explicar.
Para escribir datos de tiempo en el DS1307 el creador del programa usaba *movlw B'00101000'* y luego llama a una instrucción para grabar el dato, yo cambie ese *movlw B'00101000'* a *movlw DATO2e* para poder modificar esa variable en un futuro, pero el numero que realmente tiene DATO2e no es el que envía al reloj.
Suponiendo que DATO2e tenga en binario 00010011 cuando carga eso en los minutos no se acerca en nada a ese número.
Es realmente algo extraño. Si alguien me pudiera ayudar estaría realmente agradecido.

Este es el código completo del programa. 


```
;;; programme communication entre pic16f877a et circuit rtc DS1307 viaI2C;;;;
    list p=16f877a
        #include<p16f877a.inc>
        org 0x00
        DATA0 equ  PORTA
        DATA1 equ   PORTB
    DATA2 equ    PORTD
DATA3 equ    0X0C
DATA4 equ    0X0E
DATA5 equ    0X0F
DATA6 equ    0X1F
;; programme principale;;

        bsf STATUS,RP0  ;bank 1
           bcf STATUS,RP1   ;;bank 1
        clrf TRISB    
        clrf TRISD
        clrf TRISA
        bsf TRISC,RC4 
        bsf TRISC,RC5
        BCF SSPSTAT,CKE ;;Control des niveaux de tension à l'entrée, 0 : I2C, 1 : SMBUS ** travaille avec I2c;;
        Bsf SSPSTAT,SMP;;Control de frq signal: 1 pour 100 kHz et 1 MHz, 0 pour 400 kHz ( la signal que on utilise pour SCL c'est 100 KHz or 1MHz;;
        movlw 0X02
        movwf SSPADD ;; on calcul  la valeur avec cette relation ={ Fosc-4*F(scl)}-1
           bcf STATUS,RP0 ;; bank 0
           bcf STATUS,RP1  ; bank 0
        movlw 0X28
        movwf SSPCON ;;1110 : I2C master, adresse 7 bits, interruption sur START et STOP
        clrf PORTD
        CLRF PORTB
debut   call  I2C_start  ;; cofiguration de i2c debut " mais  dans ce programme je utilise juste une seul adresse donc "je crois" nous sommes pas obliger de ecrire une adresse 
                                ;;mais dans notr projet on doit met adresse parece que on utiliseront 3 circuit DS18B20/DS1307/.. 3 bus one wire 
            ;;    MOVLW 0X00
            ;;    call I2C_ecrire   ;; appele fonction d'ecrire qui'est base sur copie le donne ou la adresse dans registre SSPBUF et lui occupe de reste..
;;;;;;;;;;;;;;;;;;;;;;;;    
    ; Ecriture dans le registre de contrôle (adresse 0x07) du DS1307
movlw B'0110110'
movwf DATA2        
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse + bit 0 Write)
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00000000' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master 
movlw B'00100111' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
movlw DATA2 ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00100111' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00000001' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00000101' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00101001' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00101001' ; 8 bits à écrire
call I2C_write
call I2C_ACK_slave_to_master
call I2C_stop

;;;;;;;;;;;;;;
    call I2C_start
  movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse + bit 0 Write)
    call I2C_write
    call I2C_ACK_slave_to_master
    movlw B'00000000' ; 8 bits à écrire
    call I2C_write
   call I2C_ACK_slave_to_master
   call I2C_Repeated_Start
   movlw B'11010001' ; 8 bits à écrire (7 bits d'adresse + bit 1 Read)
    call I2C_write
    call I2C_ACK_slave_to_master
    call I2C_read
    movwf DATA0 ; les 8 bits lus sont transférés dans le registre d'usage général DATA0
    call I2C_ACK_master_to_slave
    call I2C_read
    movwf DATA1 ; les 8 bits lus sont transférés dans le registre d'usage général DATA1
     
    call I2C_ACK_master_to_slave
    call I2C_read
    movwf DATA2 ; les 8 bits lus sont transférés dans le registre d'usage général DATA2
    call I2C_ACK_master_to_slave
    call I2C_read
    movwf DATA3 ; les 8 bits lus sont transférés dans le registre d'usage général DATA
    call I2C_ACK_master_to_slave
    call I2C_read
    movwf DATA4 ; les 8 bits lus sont transférés dans le registre d'usage général DATA4
    call I2C_ACK_master_to_slave
   call I2C_read
   movwf DATA5 ; les 8 bits lus sont transférés dans le registre d'usage général DATA5
    call I2C_ACK_master_to_slave
    call I2C_read
    movwf DATA6 ; les 8 bits lus sont transférés dans le registre d'usage général DATA6
     
    call I2C_NOACK
     
    call I2C_stop


I2C_idle
        bsf STATUS , RP0 ; passage en banque 1
        bcf STATUS , RP1 ; passage en banque 1
I2C_idle0
        btfsc SSPCON2 , ACKEN
        goto I2C_idle0 ; le bit ACKEN n'est pas nul
        btfsc SSPCON2 , RCEN
        goto I2C_idle0 ; le bit RCEN n'est pas nul
        btfsc SSPCON2 , PEN
        goto I2C_idle0 ; le bit PEN n'est pas nul
        btfsc SSPCON2 , RSEN
        goto I2C_idle0 ; le bit RSEN n'est pas nul
        btfsc SSPCON2 , SEN
        goto I2C_idle0 ; le bit SEN n'est pas nul
        btfsc SSPSTAT , R_W
        goto I2C_idle0 ; le bit R_W n'est pas nul
        bcf STATUS , RP0 ; passage en banque 0
        bcf STATUS , RP1 ; passage en banque 0
        return


 
I2C_start
    call I2C_idle ; on attend que le bus I2C soit libre
    bsf STATUS , RP0 ; passage en banque 1
    bcf STATUS , RP1 ; passage en banque 1
    bsf SSPCON2 , SEN ; SEN = 1 (lancement d'une opération Start)
    bcf STATUS , RP0 ; passage en banque 0
    bcf STATUS , RP1 ; passage en banque 0
    return


I2C_read
        
        call I2C_idle ; on attend que le bus I2C soit prêt
        bsf STATUS , RP0 ; passage en banque 1
        bcf STATUS , RP1 ; passage en banque 1
        bsf SSPCON2 , RCEN ; on lance la réception
I2C_read0
        btfsc SSPCON2 , RCEN 
        goto I2C_read0 ; on attend la fin de la réception
        bcf STATUS , RP0 ; passage en banque 0
        bcf STATUS , RP1 ; passage en banque 0
        movf SSPBUF ,0
        return


I2C_stop
    call I2C_idle ; on attend que le bus I2C soit prêt
    bsf STATUS , RP0 ; passage en banque 1
    bcf STATUS , RP1 ; passage en banque 1
    bsf SSPCON2 , PEN ; PEN = 1 (lancement d'une opération Stop)
    bcf STATUS , RP0 ; passage en banque 0
    bcf STATUS , RP1 ; passage en banque 0
    return
    
I2C_write    
    call I2C_idle ; on attend que le bus I2C soit prêt
    movwf SSPBUF
    call I2C_ACK_slave_to_master    
    return



I2C_Repeated_Start
    call I2C_idle ; on attend que le bus I2C soit prêt
    bsf STATUS , RP0 ; passage en banque 1
    bcf STATUS , RP1 ; passage en banque 1
    bsf SSPCON2 , RSEN ; RSEN = 1 (lancement d'une opération Repeated Start)
    bcf STATUS , RP0 ; passage en banque 0
    bcf STATUS , RP1 ; passage en banque 0
    return


I2C_ACK_slave_to_master    
    call I2C_idle ; on attend que le bus I2C soit prêt
    bsf STATUS , RP0 ; passage en banque 1
    bcf STATUS , RP1 ; passage en banque 1
I2C_ACK_slave_to_master0
    btfsc SSPCON2 , ACKSTAT
    goto I2C_ACK_slave_to_master0 ; on attend la réception du bit ACK
    bcf STATUS , RP0 ; passage en banque 0
    bcf STATUS , RP1 ; passage en banque 0
    return

I2C_NOACK 
    call I2C_idle ; on attend que le bus I2C soit prêt
    bsf STATUS , RP0 ; passage en banque 1
    bcf STATUS , RP1 ; passage en banque 1
    bsf SSPCON2 , ACKDT ; ACKDT = 1
    bsf SSPCON2 , ACKEN ; ACKEN = 1 (lancement d'une opération Acknowledge)
    bcf STATUS , RP0 ; passage en banque 0
    bcf STATUS , RP1 ; passage en banque 0
    return

I2C_ACK_master_to_slave
    call I2C_idle ; on attend que le bus I2C soit prêt
    bsf STATUS , RP0 ; passage en banque 1
    bcf STATUS , RP1 ; passage en banque 1
    bcf SSPCON2 , ACKDT ; ACKDT = 0
    bsf SSPCON2 , ACKEN ; ACKEN = 1 (lancement d'une opération Acknowledge)
    bcf STATUS , RP0 ; passage en banque 0
    bcf STATUS , RP1 ; passage en banque 0
    return



END
```


----------



## marvin villalobos (Nov 17, 2013)

Hola amigos del foro. Nuevamente estoy por aquí para molestarlos una vez mas disculparan pero creo que con esto termino, eso creo jeje.
Estoy haciendo un proyectito de control de semáforos de dos fases con tiempo real ds1307.
Las funciones que le estoy pidiendo hacer a mi pic16f877a es que por medio de una interrupción b.0 se pueda entrar a un menú de configuración y se pueda variar el tiempo de la fase 1, y de la fase 2.
Además que ajuste en horas y minutos; la hora de intermitencia, hora de apagado y hora de encendido.
Bueno les cuento que cuando configuro el tiempo de fase 1 y 2 , el programa me funciona correctamente, pero con respecto a la igualación de hora de int , hora apag, hora de encendido no me funciona.
En mi programa que adjunto está en la etiqueta contexto ya que creo que es porque cuando ajusto dichos términos están en sistema dec y el tiempo real en sistema hex.
¿Alguien pude revisar mi código que esta en pbp, y decirme que es lo que esta pasando? 
Les agradecería bastante amigos del Foro.


----------



## Meta (Nov 17, 2013)

Hola:







http://pic16f84a.org/proteus.html#Proteus_Capitulo_24

Un saludo.


----------



## marvin villalobos (Feb 15, 2014)

Hola amigos de este foro magnifico.
Antes que nada quisiera saludarlos muy atentamente por su foro que creo yo que es el mejor de todos, y eso gracias a sus moderadores y sabios, expertos electrónicos.
Bien, estoy haciendo un reloj con alarma, claro el reloj es con un RTC DS1307 que encontré en este foro gracias a cesar_8k;_ https://www.forosdeelectronica.com/posts/188954/ _Le estoy agregando un menú para configurar la hora de alarma y el minuto de alarma, y ademas le estoy agregando una sentencia para que cuando se cumpla esta me active el led que está en el pin 02 (RA3), pero ahí va el problema que no va, no obedece, ¿No sé si está mal propuesta la sentencia o me falta agregar otra dirección?
Es por eso que necesito su ayuda amigos, a ver si me dan una luz, les agradecería de antemano. Adjunto mi circuito en isis y mi programación en PICBasic Pro.


----------



## D@rkbytes (Feb 15, 2014)

marvin villalobos dijo:


> Bien, estoy haciendo un reloj con alarma, claro el reloj es con un RTC DS1307 que encontré en este foro gracias a cesar_8k;_ https://www.forosdeelectronica.com/posts/188954/ _Le estoy agregando un menú para configurar la hora de alarma y el minuto de alarma, y ademas le estoy agregando una sentencia para que cuando se cumpla esta me active el led que está en el pin 02 (RA3), pero ahí va el problema que no va, no obedece, ¿No sé si está mal propuesta la sentencia o me falta agregar otra dirección?


El problema que debes tener, es al comparar sistema decimal con sistema decimal codificado en binario (BCD).
Que es el sistema con el que trabaja el RTC DS1307.

Voy a adjuntar un ejemplo no terminado del programa que mencionas para que tengas una idea de cómo realizar la comparación con el sistema BCD.
A este programa le falta agregar la configuración de la alarma. (Es para que tengas una idea.)

Tal vez con este programa puedas terminar el que por ahora no te funciona.

Nota:
El programa está escrito con PICBasic Pro X 3 de MicroCode Studio X (Para obtener el archivo *.cof)
Pero también se incluye la palabra de configuración para PBP 2.6XX y el código es compatible.

Suerte.


----------



## marvin villalobos (Feb 27, 2014)

Hola Amigo Darkbytes, antes que nada te agradezco por el apoyo que me das con tu programación.

Estuve queriendo entender un poco mas , pero admito que Ud, es un genio, mire con respecto a la conversión del sistema hex a bcd, no casi me entra, pero mas o menos voy así como mi código adjunto, espero , estar cerca de lo que quiero, le agradecería si por ahí le da una chequeadita.

¡Estoy experimentando la conversión primero con las eehoras_al , a ver si mas o menos es asi?...
Ah dígame si es necesario cambiar mi esquema como Ud, lo ha hecho para trabajar mejor o no?

GRACIAS


----------



## D@rkbytes (Mar 2, 2014)

marvin villalobos dijo:


> Estoy experimentando la conversión primero con las eehoras_al.
> ¿A ver si mas o menos es así?


El problema en tu programa es que todas la variables involucradas deben tener el mismo formato.
Una forma fácil de lograr esto es usando variables espejo.
Esto es que una variable llevará un conteo decimal mientras la otra será convertida a BCD a partir del valor que lleva la variable de conteo.
La desventaja de usar esta técnica es que se consume mucha memoria y para lograr el programa completo que incluya la configuración de la hora de alarma, ya no alcanzará con el PIC16F628A.
Pero no se me ocurre una forma fácil de lograr este objetivo de una manera más sencilla.
Por lo tanto para realizar el programa usando la técnica del ejemplo que adjunto cambié al 16F88.
No adjunto el programa completo porque lo escribí en PICBasic de Proton IDE y las instrucciones son algo diferentes.
Pero adjunto un ejemplo para que puedas entender como cambiar y establecer la hora.
Usando la función de conversión de este programa ya podrás mantener las variables con el mismo formato BCD que usa el RTC DS1307 y posteriormente podrás realizar la comparación de las variables para la hora de alarma y la hora que regresa el DS1307 sin problemas.
El programa que adjunto no está muy comentado porque está fácil de entender.  


marvin villalobos dijo:


> ¿Dígame si es necesario cambiar mi esquema como Ud, lo ha hecho para trabajar mejor o no?


Si optas por utilizar la técnica que empleé para la conversión, usar las resistencias pull-up internas para las líneas SDA y SCL, más actualizar la hora por medio del pin de salida de onda cuadrada del DS1307, si tendrás que cambiar el diseño y cómo el programa completo requerirá mas memoria, tendrás que cambiar al 16F88.

Espero que este ejemplo que adjunto te pueda servir para realizar tu proyecto.

Suerte.


----------



## marvin villalobos (Mar 26, 2014)

Hola amigo Darkbytes, estuve analizando el proyecto ayuda que me pasaste, y bueno parece que por fin logre comprender un poco sobre la conversión de dec a bcd pasando por bin, aquí le dejo mi modificación del reloj con alarma y tiempo real ds1307 y lcd 16x2, ah! Cambie pic 16f88 por un pic 16f877, ah si no fuera mucha molestia, podría explicarme porque cuando está funcionando mi reloj tiempo real en el lcd se aprecia el tiempo que transcurre asi: 10:10:10 ,pero solo por momentos, ah otra cosita quisiera que lo revise a ver si es normal que mi declaración eeprom 0,[6,0]  , read 0, hora_al (pause 10) y read 1, min_al (pause 10) vallan dentro del bucle programa. no habrá ningún problema?
Por favor, Gracias
Adjunto firmware y simulación en isis proteus.


----------



## D@rkbytes (Mar 27, 2014)

marvin villalobos dijo:


> ¿Podría explicarme por qué cuando está funcionando mi reloj tiempo real en el lcd se aprecia el tiempo que transcurre así: 10:10:10? pero solo por momentos.
> Ah, otra cosita, quisiera que lo revise a ver si es normal que mi declaración eeprom 0,[6,0]  , read 0, hora_al (pause 10) y read 1, min_al (pause 10) vallan dentro del bucle programa. ¿No habrá ningún problema?


Posiblemente al mostrarse 10:10:10 se deba a incompatibilidad de formatos.
Prueba haciendo depuraciones del programa usando como debug la salida serial sobre las variables que tengas duda, ya que PBP 2.60x no puede crear archivos *.cof y así dar un seguimiento al problema.

No te recomiendo que la escritura de la memoria EEPROM la estés realizando dentro del bucle principal del programa.
Recuerda que se trata de un reloj y que estarás de esa forma escribiendo  en la memoria cada segundo por mucho tiempo, así pronto se dañará la  memoria.
Si solo vas a escribir un valor constante, realiza esa escritura antes de entrar al bucle del programa.

Saludos.


----------



## marvin villalobos (Mar 27, 2014)

Hola amigo Darkbytes, queria agradecerle por su ayuda prestada por medio de este magnifico foro; a la vez quisiera postear el programa fuente del reloj, para que lo revise, a ver si es así como funcionaria mejor con las variables antes mencionadas y la eeprom fuera del bucle programa.
https://www.forosdeelectronica.com/f24/reloj-ds1307-arranca-practica-79541-post899549/#post899549
Ademas quisiera hacerle otra consulta, ah este reloj_alarma quisiera agregarle otras funciones,como encendido de leds de manera alternada,el programa que adjunto se llama programa sem y mi pregunta seria si se puede aumentar este programa sem como lo presento ahí con (pauses 1000) dentro del programa del reloj o quizás hay que utilizar alguna interrupcion? adjunto esquemas en proteus y programa fuente en pbp.
Gracias...


----------



## D@rkbytes (Mar 31, 2014)

marvin villalobos dijo:


> a este reloj_alarma quisiera agregarle otras funciones, como encendido de leds de manera alternada, el programa que adjunto se llama programa sem y mi pregunta sería, ¿si se puede aumentar este programa sem como lo presento ahí con (pauses 1000) dentro del programa del reloj o quizás hay que utilizar alguna interrupción?


No entiendo bien que es lo que quieres hacer con el programa de fases, pero no debes agregar retardos tan largos dentro del programa.
Recuerda nuevamente que se trata de un reloj y que si incluyes retardos vas a tener lecturas desincronizadas.

Una posible forma de hacerlo, sería con el TMR1 y que desborde cada segundo, pero se necesita el oscilador externo con cristal de 32768Hz, y éste va conectado a los pines RC0/T10S0 y RC1/T10SI.

El procedimiento que te menciono está por aquí: _*Temporizador con TMR1*_

Suerte.
https://www.forosdeelectronica.com/...c-picbasic-pro-20658/index124.html#post789960


----------



## marvin villalobos (Abr 2, 2014)

Claro Amigo Darkbytes, quisiera insertar este (programa sem) a mi reloj, dicho sea de paso lo adjunto solo el programa sem en isis, y eh entendido que tendria que ser con interrupciones tmr.


Eh ido a la dirección que ud, me envio ( Temporizador con TMR1, arriba) sobre interrupciones y Ud, me recomienda cambiar el oscilador por otro de 32768, para mas presición pero le pregunto, podria hacer interrupción con el mismo cristal de mi proyecto que es de 20 mhz? si ? ya que me conformaria con este si es que me aproximara lo mas cerca a la frec de 1 mhz?

Le agradezco su ayuda amigo Darbytes, si es que me enviara a una direccion que pueda hacerme el ciclo que hacen mis dos fases que estan en isis con interrupciones?
Gracias


----------



## D@rkbytes (Abr 2, 2014)

marvin villalobos dijo:


> He ido a la dirección que ud, me envió ( Temporizador con TMR1, arriba) sobre interrupciones y Ud, me recomienda cambiar el oscilador por otro de 32768, para mas precisión pero le pregunto, podría hacer interrupción con el mismo cristal de mi proyecto que es de 20 mhz? si ? ya que me conformaría con este si es que me aproximara lo mas cerca a la frec de 1 mhz?


No tienes que cambiar el cristal de 20MHz, tienes que poner otro cristal de 32768Hz.


D@rkbytes dijo:


> se necesita el oscilador externo con cristal de 32768Hz, y  *éste va conectado a los pines RC0/T10S0 y RC1/T10SI*.


Así que, no tienes porque cambiar el cristal de 20MHz por otro de 32768Hz.
Este otro oscilador será el que se sincronizará externamente con el TMR1 para obtener 1Hz.
¿No sé si quisiste decir 1Hz en vez de 1MHz.?


marvin villalobos dijo:


> ¿si es que me enviara a una dirección que pueda hacerme el ciclo que hacen mis dos fases que están en isis con interrupciones?


Lo que tienes que hacer, es incluir tus rutinas dentro de la rutina que atiende la interrupción por desborde del TMR1 y realizar conteos para ir cambiando la fases.
Sólo recuerda que no debes usar retardos, únicamente conteos y cada conteo avanzará una vez por segundo.

Mira bien los ejemplos del enlace que puse, ahí verás como sincronizar el timer para obtener 1Hz.

También puedes usar la salida que genera el DS1307 y hacer uso de la interrupción por RB0.

Suerte.


----------



## marvin villalobos (Abr 13, 2014)

Hola amigo Darkbytes, estuve analizando su programa de tmr1 con crystal externo de 32768, pero aun no logro masticar bien el programa, estuve intentando interrumpir con tm0 y bueno mi led rojo  enciende, mi led amarillo también , mi led verde también, pero no! regresa al inicio para volver hacer la secuencia, Que estara pasando verdad? Adjunto mi programita y mi esquema,en isis.


----------



## D@rkbytes (Abr 15, 2014)

marvin villalobos dijo:


> Hola amigo Darkbytes, estuve analizando su programa de tmr1 con crystal externo de 32768, pero aun no logro masticar bien el programa, estuve intentando interrumpir con tm0 y bueno mi led rojo  enciende, mi led amarillo también , mi led verde también, pero no! regresa al inicio para volver hacer la secuencia


Te adjunto un ejemplo usando el TMR1 para que entiendas sobre los conteos que te mencioné.
Así de esta forma solo tienes que hacer conteos basados en segundos.
Por ejemplo, si quieres un retardo de 3 minutos: 3 x 60 = 180 segundos.
Entonces cargas las constantes del programa con los segundos que requieras para el encendido de los LED.

Usando este método puedes generar las secuencias sin que afecten al programa principal.

Suerte.


----------



## marvin villalobos (May 8, 2014)

Hola amigos Darbytes todo este tiempo estuve queriendo hacer funcionar el programita antes mencionado mostrado es decir 16F628A TMR1 1Seg para semáforo con pic 16f877a pero no me sale nada , ya estoy varios dias en esto , seguro que alguna interrupción de 16f628a es distinta con 16f877a. ¿por que?


----------



## D@rkbytes (May 8, 2014)

marvin villalobos dijo:


> seguro que alguna interrupción de 16f628a es distinta con 16f877a. ¿por que?


Nop, la configuración de registros es la misma, lo que debes tener en cuenta, es que en el 16F877A, el cristal va conectado en los pines 15 y 16 (RC0 y RC1)
Para convertir los pines en entradas digitales, en el 16F628A se configura el registro CMCON y en el 16F877A es el registro ADCON1, obviamente también cambia la palabra de configuración.

De ahí en fuera, lo demás para hacer funcionar ese programa es lo mismo.


----------



## marvin villalobos (Jun 14, 2014)

Hola amigo darkbytes otra vez por aqui por este foro despues de un tiempo ausente, quisiera agradecerte por tus ayudas antes mencionadas poor este foro.
Mira estoy queriendo ya plasmar el reloj que me enseñastes al principio de este foro con pic 16f628a, lcd 16x2, y rtc 1607 con battery de 3v, speaker de telefono fijo, entonces, lo que pasa es que estoy queriendo acondicionarlo en una cajita especial pequeña en donde no cabe un transformador pequeño y lo estoy haciendo con una fuente directa de 220v,diodos puente de 1A, zener 12v, (adjunto imagen de la fuente), se que es *muy peligrosa *pero doy fe que soy *muy cuidadoso *con ello, queria saber si ud, aprueba mi diseño de tarjeta con fuente s/n trafo, ademas queria saber si tiene algun afecto en el trabajo del rtc (efectos de retrazo o adelanto),lcd,pic,rele ademas si trabajaria bien con ese relay de 12v o es mejor un triac y un moc? por favor amigo darkbytes gracias por su respuesta.
Adjunto imagenes de mi proyecto
Gracias


----------



## D@rkbytes (Jun 14, 2014)

No sé si ya probaste el esquema de la fuente de poder "fuente.png" lo digo por qué no pusiste la capacidad del diodo Zener.

Tienes únicamente un diodo Zener de 5V. y no especificas los Watts de trabajo, el capacitor de 0.22uF está bien, el de filtraje deberías aumentarlo a unos 470uF .
Debes calcular y poner una resistencia para limitar la corriente de consumo, o adiós diodo Zener y todo lo demás.

Lo demás lo veremos después.


----------



## marvin villalobos (Jun 16, 2014)

La fuente de la imagen (la fuente .png) trae un diodo zener de 5v, pero a este dido zener quiero sustituirlo por otro Diodo zener de 12v para levantar el rele, y de la misma por medio de un resistor de 0.47 ohm al regulador 7805, sin alterar los valores de los demás componentes de la fuente antes mencionada, no se si estaré haciendo bien.
El watiaje del zener seria de mas  o menos 1.2 watts.



Con respecto a la resistencia que protega al zener te refieres a esta verdad?


----------



## D@rkbytes (Jun 16, 2014)

marvin villalobos dijo:


> Con respecto a la resistencia que proteja al Zener, te refieres a esta ¿verdad?


Sip.
Para no salirse del tema, mira éstos otros o busca; *Fuente de poder sin transformador

* *Fuente de voltaje sin transformador 20 mA*

*Cálculo de fuente de alimentación sin transformador de 1A*

Saludos.


----------



## marvin villalobos (Jun 17, 2014)

Amigo Darkbytes y con respecto a los demas componentes su funcionamiento ¿afectan? cambio el rele x un triac o esta bien ahi el diseño?


----------



## D@rkbytes (Jun 17, 2014)

marvin villalobos dijo:


> Amigo D@rkbytes y con respecto a los demás componentes su funcionamiento ¿afectan? ¿cambio el rele por un triac o está bien ahí el diseño?


En ambos casos está bien, pero todo depende lo que quieras controlar.
Si no necesitas alta velocidad de conmutación, el relevador está bien mientras la fuente pueda con todo.
Así que necesitas hacer un cálculo aproximado sobre el consumo total del circuito para saber por qué optar.


----------



## jmpl (Sep 16, 2014)

Hola amigos acudo a ustedes por varias dudas que tengo en el proyecto que estoy realizando, siempre agradecido por que en este foro y sus participantes he aprendido mucho y siempre me han prestado ayuda  

Es primera vez que trabajo con el i2c y este ds1307, pero me he documentado bastante y he estado luchando con el codigo..

Mi programa consiste en configurar un ds1307 con un pic16f877a, configuro la hora actual por medio de programacion... sin lcd ni teclado ni nada... teniendo el pic ubicado en el tiempo, hora actual dia, mes, año y todo eso... quiero hacer unas alarmas para encender un timbre escolar... el timbre lograra encenderse por lo menos 5 segundos, a las 8am, 10am  4pm.. esta se ubicara en el puerto C,1.
 Este se encender todo el año.. menos los días sábado y domingo y en el mes de agosto que es seguro que el colegio esta de vacaciones.. por que el inicio y final de clases varia cada año asi que pensé que cuando se fuera de vacaciones solo desconectaran el pic(su alimentacion) y que siga trabajando el ds1307, y cuando regresen conecten el pic(por medio de un switch) y asi pueda encender el timbre normal mente...

El led que coloque es para checar a cada rato si el reloj esta activo(funcionando) si no esta el led en portc,0 encenderá, por si deja de funcionar la cosa.. se que es el ds1307. 

Pero tengo varios dias y noches luchando con el código pero aun no me da lo que quiero.

Como hacer para que cuando enciendan el pic saber si el reloj ya esta trabajando(ya configurado) por que si hay un apagon el pic configurara una hora que no es y cuando regresen de vacaciones. ?

una pregunta tonta.. cuando configuro el rtc, para escribir los segundos, minutos, etc, es decir  sus registros, tengo que enviar los datos en binario y cuando los leo están en bcd???... o yo le envio datos en bcd(al reloj) y el me envia datos en  bcd. ???????

Leyendo el hilo del tema me di cuenta que cuando leo los registros y los guardo en las variables para luego comparar si es la hora y dia correcto para encender el timbre podría ser mi error.. sera cierto??.. y como hago para comparar 2 números en bcd ?. O sera que tengo que llevar ese bcd a binario para comparar después??

no lo trabajo con interrupciones por que como soy principiante nunca he trabajado con ellas.. seria mejor hacer el programa con interrupciones?

Adjunto mi esquema en proteus y el codigo. Espero que puedan ayudarme

Gracias de atemano...


----------



## D@rkbytes (Sep 16, 2014)

jmpl dijo:


> El led que coloqué es para checar a cada rato si el reloj esta activo(funcionando) si no está, el led en portc,0 encenderá.
> Por si deja de funcionar la cosa, sé que es el ds1307.


Para eso puedes utilizar el pin de salida de onda cuadrada (SQW/OUT) del DS1307.
Debes inicializarlo con el comando para que se obtenga una señal de onda cuadrada por ese pin.


jmpl dijo:


> ¿Cómo hacer para que cuando enciendan el pic, saber si el reloj ya está  trabajando (ya configurado) porque si hay un apagón el pic configurará  una hora que no es.
> ¿Y cuando regresen de vacaciones?


Si no quieres usar LCD eso se complica, pero si el DS1307 tiene pila no se deben perder los datos iniciales.
También puedes usar una conexión RS-232 para ajustar y verificar la hora.
Puedes usar un FT232RL para trabajar con RS-232 y comunicarte con una LAPTOP o PC por USB.


jmpl dijo:


> Una pregunta tonta. ¿Cuando configuro el rtc para  escribir los segundos, minutos, etc, es decir  sus registros, tengo que  enviar los datos en binario y cuando los leo están en bcd o yo le  envio datos en bcd (al reloj) y el me envía datos en  bcd?


Eso viene en la hoja de datos del DS1307, tanto envío como recepción de datos son en BCD.


jmpl dijo:


> Leyendo el hilo del tema me di cuenta que cuando leo los registros y los  guardo en las variables para luego comparar si es la hora y día  correcto para encender el timbre ¿Podría ser mi error? ¿Será cierto? ¿Y  cómo hago para comparar 2 números en bcd?
> O será que tengo que llevar  ese bcd a binario para comparar después?


Para eso tienes que usar rutinas de conversión de decimal a BCD y viceversa.
Mira más ejemplos por el foro, pues existen programas en ensamblador para el DS1307.


jmpl dijo:


> No lo trabajo con interrupciones porque como soy principiante nunca he  trabajado con ellas.
> ¿Sería mejor hacer el programa con  interrupciones?


Claro que sería mejor que trabajaras el programa con interrupciones.
De esa forma puedes actualizar la hora cada segundo usando el pin SQW/OUT y la interrupción por RB0.

Suerte.


----------



## jmpl (Sep 16, 2014)

Gracias por responder, algo puedo rescartar del codigo que adjunte?,quisiera saber que tiene malo ese código, no se si lo revisaste... me desvelare tratando que funcione, si no comenzare desde cero haciendo con interrupciones y a documentarme bastante.. 

Gracias


----------



## D@rkbytes (Sep 17, 2014)

jmpl dijo:


> ¿Algo puedo rescatar del código que adjunté?
> Quisiera saber que tiene malo ese código, ¿no sé si lo revisaste?
> Me desvelaré tratando que funcione, si no, comenzaré desde cero haciéndolo con interrupciones y a documentarme bastante.


Lo que puedes rescatar y posteriormente modificar si lo piensas reescribir, son las rutinas principales.
Como la inicialización del RTC y las que creas necesarias.

Lo que veo que tienes que corregir, son las rutinas donde regresas con goto en vez de return.
Trata de darle una mejor estructura al programa para que tú mismo logres una mejor comprensión.


----------



## jmpl (Sep 21, 2014)

Hola yo nuevamente neciandolos jajja

Me puse manos a la obra y leyendo mas en san google, viendo mas ejemplos, logre que me funcionara el reloj con interrupción por Rb0, configuro la hora mediante el programa y funciona perfectamente y hasta con ayuda de un ejemplo muestro el tiempo del reloj en una lcd 

Pero ahora tengo un problema con las alarmas, es que cuando debería de encenderme el timbre no enciende,  simule un circuito con un rele, para  encender una lampara en proteus que seria el timbre. 1 = timbre apagado, 0=timbre encendido. por unos 6 o 7 segundos

escribí un codigo para poner el portD,0 encendido cuando sean las 8, 10horas, y 16horas, en punto, pero no se porque no funciona.

Si alguien me podria echar una mano con esto si no es mucha molestia estaría agradecido

adjunto lo que llevo hasta hora


----------



## Miembro eliminado 356005 (Sep 23, 2014)

jmpl dijo:


> Como hacer para que cuando enciendan el pic saber si el reloj ya esta trabajando(ya configurado) por que si hay un apagon el pic configurara una hora que no es y cuando regresen de vacaciones. ?


Alimenta al DS1307 con una pila de botón.



jmpl dijo:


> una pregunta tonta.. cuando configuro el rtc, para escribir los segundos, minutos, etc, es decir  sus registros, tengo que enviar los datos en binario y cuando los leo están en bcd???... o yo le envio datos en bcd(al reloj) y el me envia datos en  bcd. ???????


Todo debe estar en BCD. Consulta la página 8 de la hoja de datos.



jmpl dijo:


> como hago para comparar 2 números en bcd ?. O sera que tengo que llevar ese bcd a binario para comparar después??


Exactamente igual que si fuera en binario, pero es más claro si en tu programa escribes los números constantes en hexadecimal. Por ejemplo, para escribir 12 en BCD sería H'12'.


----------



## jmpl (Sep 25, 2014)

Gracias a todos por su ayuda me ayudo a comprender un poco mas la cosa.. ya pude lograr hacer funcionar perfectamente mi codigo.. ahora no lo veo como cosa de otro mundo jajjaj..

Gracias


----------



## gatito11 (Ene 16, 2015)

¿Qué tal compañeros? Necesito de su ayuda.

Les explico:
Estoy haciendo un reloj digital con un DS1307, y pues todo va bien hasta este código:


```
#include <16F887.h>
#fuses NOWDT,NOBROWNOUT,INTRC,NOPUT,NOWRT,NOPROTECT,NOLVP
#use delay(clock=4000000)
//#use rs232(baud=1200,xmit=pin_c6, rcv=pin_c7, bits=8)
#include <LCD.c>
#BYTE TRISA=0X85
#BYTE PORTA=0X05
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
//#use fast_io(D)                     ///   se este configurando cada vez que usamos
//#use fast_io(E)                     ///   alguna instruccion de entrada o salida
#byte portc = 0x07                     /// se definen direcciones de memoria
#byte portd = 8
#include "ds1307.c"     // Funciones usadas para acceder a los registros del DS1307

// Variables usadas:
//float valor_=80,valor2_=80,dat_in;
//float valor1f_,valor2f_;
int sec, min, hrs;
char nombre[10];

      void main() {
         ds1307_init (DS1307_OUT_32_KHZ);//ds1307_init (DS1307_OUT_ENABLED |  DS1307_OUT_32_KHZ);      ///se inicializa el ds1307
         bit_clear(TRISA,0);
//         port_b_pullups (true) ;
         enable_interrupts(INT_RDA);
         set_tris_B(0x00);
         set_tris_A(0x00);
         portA=0x00;
         set_tris_c (0x18) ;    // PIN_C4 Como entrada
//         set_tris_d (0x00) ;
         enable_interrupts(GLOBAL);
         lcd_init();
         ds1307_set_date_time (16, 01, 15, 4, 17, 19, 00); /// se escribe en el dispositivo
         /// la hora deseada
         WHILE(1) {
                  if((hrs==00)&&(min==00)&&(sec==00)){
                     lcd_init();
                     }
                  delay_ms (150) ;
                  ds1307_get_time (hrs, min, sec);   /// se obtiene la hora
                  ds1307_get_day_of_week(nombre);
                  lcd_gotoxy (1,1) ;
                  lcd_putc("Time:");
                  lcd_gotoxy (7,1);
                  printf(lcd_putc,"%02u:%02u:%02u",hrs,min,sec);
                  lcd_gotoxy (2,2);
                  printf(lcd_putc,"%s",nombre);
                  delay_ms(100);
                
                }               
          }
```
Se supone que de esa forma ya configuras el DS1307
Ya tiene el cristal y ya tiene la batería de 3.3V.
Y pues para que no se reconfigure el reloj con los valores que tiene el PIC cada vez que lo conecto de nuevo, pues apago el PIC y lo reprogramo.
Es el mismo código, solo que le quito la siguiente linea:

*ds1307_set_date_time (16, 01, 15, 4, 17, 19, 00); /// se escribe en el dispositivo
         /// la hora deseada*

Y cuando lo vuelvo a conectar, pues el reloj no sigue funcionando, aparece otra fecha y hora, es como si se hubiera reseteado.

¿Qué puedo hacer para no tener ese problema?


----------



## nitsuga2585 (Ene 17, 2015)

si se te resetea cuando le sacas la alimentacion del micro es porque no se esta alimentando de la pila externa, o capaz la pila externa no tiene carga, medila y fijate si tiene el minimo voltaje que necesita el reloj


----------



## gatito11 (Ene 18, 2015)

pues no se  a ciencia cierta si se resetea, o al menos no lo creo porque la bateria es nueva de 3.1v, pero  bueno te diré que es lo que pasa, yo primero cargo un programa con la hora y fecha por decir la hora actual, ya que veo que lo despliega en pantalla, apago el pic, quito la linea que en mensajes anteriores describí, vuelvo a programar el pic, y pues ya aparece 00:00 martes, no logro entender porque pasa esto, voy a checar lo de la bateria, o alguna otra cosa que este pasando por alto, o si quitando esa linea se supone deberia estar funcionando el reloj perfectamente??


----------



## nitsuga2585 (Ene 18, 2015)

yo te pasaria un codigo pero esta en c18, y uso visual studio para configurar la hora y mostrarla, trata de hacer un programa en el que cuando inicies te muestre la hora y fecha y que tenga una opcion para configurar la hora. es decir cuando inices que te muestre la hora y tener la opcion de que si queres cambiarle la hora. yo los problemas que tenia era que si o si necesitas modificarle un dato al reloj para que ande y luego mantiene esa hora o fecha si tiene la pila puesta. proba si la polaridad de la pila corresponde a la del ds, por ahi tenes la pila al reves. otra no se me ocurre.

if((hrs==00)&&(min==00)&&(sec==00)){
                     lcd_init();
                     }
esta linea que tenes dice que si la hora es 00:00:00 ahi inicia el lcd? si tiene otra hora no la inicia??


----------



## gatito11 (Ene 18, 2015)

esa linea la puse por el hecho de que cuando cambia de dia puede que el dia siguiente sea nombre mas corto y al cambiar de dia pasaría esto,

son las :
11:59
Miercoles

cambia a las:
00:00
jueves*les*

por eso inicio la pantalla a las 00:00 de todos los dias para que no haya problemas con la impresión


----------



## nitsuga2585 (Ene 18, 2015)

ok. otra se me ocurre que hagas un paso a paso en el proteus, armas el circuito y en vez de cargar el archivo .hex carga el archivo .cof inicia la simulacion en pausa y vas paso a paso viendo que hace tu codigo, en la barra de menu esta debug ahi tenes varias opciones, ver paso a paso el codigo tambien como se van modificando los registros. y si no bueno suerte jaja


----------



## gatito11 (Ene 27, 2015)

despues de varios pruebas descubrí que es la bateria, aunque la bateria es de 3.2 v, tiene una caida de voltaje algo notable cuando se apaga el circuito, pero al conectarla con una fuente de 3.3v el reloj funcionó correctamente sin problemas


----------



## nitsuga2585 (Ene 29, 2015)

bueno tuve razon al principio ajaj, buenisimo que hayas solucionado el problema


----------



## anthony123 (Jun 21, 2015)

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 pero todas dan el mismo problema. ¿Alguien lo ha tenido?

Adjunto código y librería:

*CÓDIGO DEL PIC*

```
#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.


----------



## Daniel Meza (Jun 21, 2015)

Hola, no he revisado minuciosamente tu código pero lo que puede estar pasando es que estés confundiendo entre los dos registros de día que tiene el DS1307: uno para el día como tal 1:30-31 y otro para el día de la semana 1-7. 


```
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();
```

El código pasado lo copié de la librería, allí está la variable "dow" (day of week) y la otra "day".

Por cierto, veo que usas muchas sentencias "if" para ajustar los datos del RTC, esto no es necesario pues la misma lógica del integrado corrige los contadores.

Saludos compañero.


----------



## anthony123 (Jun 22, 2015)

Hola que tal? Primero que nada, gracias por tu respuesta.

Lo de la variable día de la semana (dow, en el driver) no creo que sea lo que suceda porque mando a imprimir es day, día del mes.

Estuve preguntando en otros foros y en el de CCS me comentaron que un problema puede ser que estoy usando las mismas variables locales del driver como globales. 

Lo que me extraña es que en todos los códigos que he visto, lo realizan así.

Sigo buscando soluciones.

Saludos!


----------



## anthony123 (Jun 27, 2015)

Les adjunto un video del funcionamiento extraño:







Saludos


----------



## Minato Uchiha (Jun 27, 2015)

Hola! Antes que nada soy nuevo en este foro y me gustaría que supieran que es simplemente fenomenal tanto conocimiento colectivo, realmente me impresiona todo esto y ciertamente aquí se aprende con solo pasearse un momento.

Luego de lo anterior quisiera que me ayudasen con algo. Soy un estudiante y no domino del todo el lenguaje C así que pido paciencia.

Para obtener la nota de periodo en mi instituto debemos realizar un proyecto, he elegido un reloj calendario utilizando un DS1307 y un pic 16f876a así que me conseguí el proyecto en internet y decidí realizarlo. El problema está en que simulé todo en proteus y me salió, pero cuando lo armé en la protoboard no me apareció nada. No se si el problema está  en el programa ya que he armado el circuito 3 veces ya y como aparece en el proteus y nada, solo aparecen dos lineas.

Les ruego encarecidamente que me ayuden. Adjunto los programas, librería el esquema y una foto para que vean lo que me aparece. Espero que puedan ayudar y de antemano se los agradezco.


----------



## D@rkbytes (Jun 27, 2015)

Minato Uchiha dijo:


> El problema está en que simulé todo en proteus y me salió, pero cuando lo armé en la protoboard no me apareció nada.
> No sé si el problema está  en el programa ya que he armado el circuito 3 veces ya y como aparece en el proteus y nada, sólo aparecen dos líneas.


Si ya revisaste todo y mencionas que lo has armado 3 veces, seguramente el PIC o la pantalla están dañados, porque armé el circuito que subiste, y si funciona.
Aquí una foto del circuito "funcionando": 

Tiene problemas con el formato de las horas, pero al menos podrás ver que si se muestran datos.

Primero verifica que puede estar dañado o mal conectado y después corrige el problema del formato.

Algo por lo que puedes empezar a revisar, son las conexiones de la pantalla.

Suerte.


----------



## Minato Uchiha (Jun 28, 2015)

D@rkbyte, gracias por atenderme. Lo he vuelto a armar y nada. Revisé las conexiones y todas están como debería, lo revisé 3 veces con lentitud y calma.

He visto la imágen y puedo notar que utilizas un _capacitor y dos resistencias en el pin 3 del ds1307, ademas de un cristal pequeño_. Yo utilizo un cristal de 4MHz para el ds y no pongo el capacitor ni las resistencias. Además quisiera saber de cuanto son las resistencias que le pusiste al pin 5 y 6 del ds.

Como te dije lo estoy haciendo exactamente igual a la simulación y no se si los valores de los elementos que uso influyan grandemente en el funcionamiento del reloj. Lo unico que me falta por verificar es el pic y el LCD.

Gracias por tu ayuda.


----------



## D@rkbytes (Jun 28, 2015)

Minato Uchiha dijo:


> Yo utilizo un cristal de 4MHz para el ds y no pongo el capacitor ni las resistencias.


El DS1307 usa un cristal de 32768 Hz. (32.768 KHz.) No uno de 4 MHz.

​Las resistencias pull-up son necesarias porque se usa comunicación I2C.
​


Minato Uchiha dijo:


> Además quisiera saber de cuanto son las resistencias que le pusiste al pin 5 y 6 del ds.


Son de 4.7 KΩ y son las que en el esquema se muestran como RPU (Resistencias Pull-Up)
El capacitor que usé es de 100 nF. (Opcional) Lo puse en el pin 3 (VBat) y también una batería de Li-Ion

Te recomiendo que siempre leas la hoja de datos de cada componente que llegues a usar.

*DS1307 Datasheet*

Suerte.​


----------



## marcosmcl (Abr 22, 2016)

Necesito ayuda. Mi proyecto hace que al tener un 0 en el pin RB0, encienda un led y viceversa.
Por otro lado, incorpora un driver para el manejo I2C de un DS1307.
Resulta que detecta bien el pin RB0, si no pongo ninguna función del driver.
Si pongo la función ds1307_init() ya no atiende el pin RB0 , si añado las demás funciones, trabaja bien el DS1307, pero me queda deshabilitada la detección input.

Adjunto el driver, programa y simulación en Proteus.

```
/////////////////////////////////////////////////////////////////////////////// 
///                               DS1307.C                                   /// 
///                     Driver for Real Time Clock                           /// 
///                                                                          /// 
/// ds1307_init() - Enable oscillator without clearing the seconds register -/// 
///                 used when PIC loses power and DS1307 run from 3V BAT     /// 
///               - Disable squarewave output                                /// 
///                                                                          /// 
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   /// 
///                                                                          /// 
/// ds1307_get_date(day,mth,year,dow)               Get the date             /// 
///                                                                          /// 
/// ds1307_get_time(hr,min,sec)                     Get the time             /// 
///                                                                          /// 
//////////////////////////////////////////////////////////////////////////////// 

#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_write(0xD1);      // RD from RTC 
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307 
   i2c_stop(); 
   seconds &= 0x7F; 

   delay_us(3); 

   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value 
   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x07);      // Control Register 
   i2c_write(0x80);     // Disable squarewave output pin 
   i2c_stop(); 

} 

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, 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_write(bin2bcd(dow));      // REG 3 
  i2c_write(bin2bcd(day));      // REG 4 
  i2c_write(bin2bcd(mth));      // REG 5 
  i2c_write(bin2bcd(year));      // REG 6 
  i2c_write(0x80);            // REG 7 - Disable squarewave output pin 
  i2c_stop(); 
} 

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow) 
{ 
  i2c_start(); 
  i2c_write(0xD0); 
  i2c_write(0x03);            // Start at REG 3 - Day of week 
  i2c_start(); 
  i2c_write(0xD1); 
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3 
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4 
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5 
  year = bcd2bin(i2c_read(0));            // REG 6 
  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)); 
}
```

Ahora el programa, el cual al levantarle los " // " en FUNCION 1, FUNCION 2, " /**/ " en FUNCION DISPLAY, presenta la hora, y cada 30 segundos aproximadamente, la fecha.

```
#include <16F886.h>
#include <string.h>
#include <stdlib.h>
#fuses INTRC_IO,NOWDT,MCLR,NOLVP,NOPROTECT //ordenes para el programado
#use delay(clock=4M)    //especifica los 4MHz CLK_INTERNO
#include <ds_1307V2.c>
#use RS232(BAUD=9600, BITS=8 ,PARITY=N, XMIT=PIN_C6, RCV=PIN_C7, STREAM=RED) //Configuracion de Rs232
#Use Fast_Io(A)   //Optimizamos E/S del PORTA
#Use Fast_Io(B)    //Optimizamos E/S del PORTB
#Use Fast_Io(C)    //Optimizamos E/S del PORTC 



#DEFINE LED_SENSOR PIN_C0       // LED DE SENSOR


#DEFINE SENSOR_IR1 PIN_B0    //DATO RECIBIDO IR1
#DEFINE SENSOR_IR2 PIN_B1    //DATO RECIBIDO IR2
#DEFINE SENSOR_IR3 PIN_B2    //DATO RECIBIDO IR3
#DEFINE SENSOR_IR4 PIN_B3    //DATO RECIBIDO IR4


int ir1_1=1,ir2_2=1,dia,hora,minuto,segundo,mes,anio,nomdia;

void main()
{  SET_TRIS_A (0XF0);    //(0XF0); //   1111 0000   4 altos ENTRADAS 4 bajos SALIDAS Y 
   SET_TRIS_B (0x1F) ;    //(0X0F); //   0001 1111   3 bajos SALIDAS 5 ALTOS ENTRADAS    
   PORT_B_PULLUPS(0x0F);// pullup a las entradas
   SET_TRIS_C (0x84);     // 1000 0100    

   // desactivo el comparador y el ADC
   setup_comparator(NC_NC_NC_NC);
   SETUP_ADC(ADC_OFF);
   // Desactivo el SPI
   SETUP_SPI( SPI_SS_DISABLED);

//______________________________________________________________

 //  ds1307_init();//se inicializa el ds1307           // FUNCION 1


//ds1307_set_date_time(21,4,16,4,10,46,30);     // FUNCION 2


while(TRUE)
{

if(input(SENSOR_IR1)==0)   // B0 SENSOR IR1
    {ir1_1=0;}
    else
    {ir1_1=1;} 


if(ir1_1==0)// ¿SIGUEN ACTIVO el SENSOR?
    output_high(LED_SENSOR);  // SENSOR ACTIVO   
   else 
     output_low(LED_SENSOR);  // SENSOR INACTIVO       


   delay_ms(1000);
   
/*   //FUNCION DISPLAY
   ds1307_get_time(hora,minuto,segundo);    //   Get the time 
 
   fprintf(RED,"{%02d:%02d:%02d}\r",hora,minuto,segundo); 
   
   if(segundo==30||segundo==59)
   {
 
      ds1307_get_date(dia,mes,anio,nomdia);
      fprintf(RED,"{fecha :%02d/%02d/%02d}\r",dia,mes,anio);
   }  
 */  
   fprintf(RED,"OK\r");  
}
}
```


----------



## D@rkbytes (Abr 22, 2016)

Si usas el pin RB0 es mejor que uses esa interrupción, pero debes activar la salida de señal de onda cuadrada del RTC DS1307 en la librería, que también debes configurar para generar 1 Hz.
Así, cada vez que ocurra la interrupción puedes tomar las lecturas y actuar sobre el LED.
Con eso liberas el bucle del programa que te servirá para realizar otras acciones.


----------



## marcosmcl (Abr 25, 2016)

Después de liar concienzudamente con los puertos, se hizo la luz, espero que a alguien le sirva. Al configurar los puertos con #Use fast_io(X), permite trabajar con los pines I/O y un puerto serial.
En cuanto se hace uso de un segundo puerto serial, el resto de pines I/O queda inutilizados.
Bastaba con borrar el #Use fast_io(X) para que por defecto tomara el #Use standar_io(X) o para verlo mejor, prescindir de esas directivas y recurrir a las sentencias de nuestro assembler elemental asi:
#BYTE TRISA=0X85
#BYTE TRISB=0X86
#BYTE TRISC=0X87
#BYTE PORTA=0X05
#BYTE PORTB=0X06
#BYTE PORTC=0X07
.
.
.
void main()
{  PORT_B_PULLUPS(0x0F);// pullup a las entradas
   // desactivo el comparador y el ADC
   setup_comparator(NC_NC_NC_NC);
   SETUP_ADC(ADC_OFF);
   // Desactivo el SPI
   SETUP_SPI( SPI_SS_DISABLED);

//______________________________________________________________

TRISA=0XF0;
PORTA=0X00;          // Para determinar el estado inicial
TRISB=0X1F;
TRISC=0X84;
  ds1307_init();//se inicializa el ds1307
.
.
.


----------



## arturkick (May 27, 2016)

D@rkbytes dijo:


> Saludos.
> Si alguna librería la vas a utilizar en varios proyectos, puedes agregarla dentro de la carpeta  Drivers.
> Así ya no tienes que copiar la o las librerías dentro de cada carpeta de proyecto.
> Esta carpeta se encuentra en el directorio de instalación del PCWHD Compiler de CCS
> ...


Buen día. Tengo una pregunta algo similar.
He estado tratando de poder modificar la hora del DS1307 para un proyecto que quiero hacer, después de tanto batallar por fin lo logré.

El problema es que ahora después de modificarle la fecha, el reloj funciona bien pero después de un rato dejándolo simulando, el reloj pone valores extraños (comenzando por el año)

Ya no sé dónde esté el error. He checado la librería del DS1307 y está bien.
No sé si tenga que añadir algo más. (El problema solamente me sucede con la fecha)

Espero puedan ayudarme a ver mi error.
Muchas gracias.

Adjunto código en C de CCS y la simulación.


----------



## D@rkbytes (May 27, 2016)

Olvidaste incluir la librería "DS1307.c" que es donde puede estar el error, y también la librería "Flex_LCD.c", aunque ésta última no es muy importante porque se puede usar la librería "lcd420.c" que viene con el compilador.


----------



## arturkick (May 28, 2016)

D@rkbytes dijo:


> Olvidaste incluir la librería "DS1307.c" que es donde puede estar el error, y también la librería "Flex_LCD.c", aunque ésta última no es muy importante porque se puede usar la librería "lcd420.c" que viene con el compilador.



Es cierto, una disculpa, aqui adjunto los archivos. 
No eh modificado nada en la librería, solo eh copiado los comandos para enviar info al ds1307 y reescribir sus datos pero tal vez este pasando algo por alto, gracias por responder darkbytes, buen inicio de fin de semana


----------



## D@rkbytes (May 28, 2016)

Hay bastantes problemas con el programa, tantos, que en la simulación se muestran las advertencias continuamente.
Mira las siguientes imágenes:

Advertencias en ISIS
​
Advertencias del Compilador


Las primeras se deben a que estás comparando valores menores a 0 usando variables sin signo. "Unsigned"
Las restantes se deben a que estas ingresando retardos en la rutina interrupción externa y usando instrucciones que también los usan.

Todas esas estructuras que usas en la rutina de interrupción, las debes usar en otras subrutinas o dentro del bucle principal.
Y usar el servicio de interrupción, para establecer cambios en banderas, incremento de variables, etc.
Pero no usarlo para procesar rutinas completas y mucho menos con retardos.

Si yo lo compilo, ni siquiera me muestra datos la pantalla.
Y eso se debe a que uso una versión más actual del compilador, de la que tú tienes.
Ahora PIC C Compiler es más estricto en cuanto a la inicialización de instrucciones nativas.

Entonces deberás corregir esos problemas y separar las rutinas.
También te recomiendo que te bases en el programa del post #10
Y para el cambio de hora y fecha, puedes usar la rutina de éste post: Arduino UNO + RTC​


----------



## arturkick (May 28, 2016)

TSSSSS, Muchisimas gracias Darkbytes, intentare todo lo que me dices para sacar adelante el programa, checare principalmente lo de los mensajes de error ya que sinceramente en algunos no sabia por que razon me los arrojaba, actualizare mi versio del compilador e intentare lo mencionado, muchas racias por tus utiles consejos, ya me has ayudado anteriormente y de verdad agradezco mucho tus aportes, en caso de tener otro error espero me puedas aconsejar, muchas gracias


----------



## miguelus (May 28, 2016)

Buenas noches.

Hace un par de meses que he empezado con este tema de los PIC.

Lo primero que he hecho ha sido un Reloj basado en el DS1307.

Este proyecto está sacado del libro...

	   "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
	  E. Palacios, F. Remiro y L. López.
 	  Editorial Ra-Ma.  www.ra-ma.es

En el proyecto viene la Librería (muy documentada) para manejar el DS1307

No se si las normas del Foro permiten publicarla, en el libro no he visto nada que lo impida, es más, invita a modificar todos los archivos que vienen como ejemplo.

Si crees que puede ser de utilidad, y si está permitido, la publicaría.

Sal U2


----------



## D@rkbytes (May 28, 2016)

miguelus dijo:


> Buenas noches.
> 
> Hace un par de meses que he empezado con este tema de los PIC.


Eso es muy bueno, me da mucho gusto que te introduzcas al mundo de los microcontroladores.



miguelus dijo:


> Lo primero que he hecho ha sido un Reloj basado en el DS1307.
> 
> Este proyecto está sacado del libro...
> 
> ...


Muy buen libro y bien explicado para iniciarse con los PIC, en lenguaje ensamblador.



miguelus dijo:


> No sé si las normas del Foro permiten publicarla, en el libro no he visto nada que lo impida, es más, invita a modificar todos los archivos que vienen como ejemplo.
> 
> Si crees que puede ser de utilidad, y si está permitido, la publicaría.


El libro que ya va en su 3a edición, no se puede publicar porque contiene derechos de autor y aún están a la venta.
Sin embargo, el mismo autor muestra los ejemplos públicamente y también se pueden descargar.
*Microcontrolador PIC16F84. Desarrollo de proyectos*

Ahí también se muestran las modificaciones que se deben realizar para que las simulaciones en Proteus  funcionen.


----------



## miguelus (May 28, 2016)

Buenas noches 

D@rkbytes, gracias por la aclaración.

Seguiré leyendo el libro, en ocasiones lo veo algo espeso, pero sigo adelante 

Sal U2


----------



## arturkick (Jun 4, 2016)

D@rkbytes dijo:


> Hay bastantes problemas con el programa, tantos, que en la simulación se muestran las advertencias continuamente.
> Mira las siguientes imágenes:
> 
> Advertencias en ISIS
> ...



!!HOLA NUEVAMENTE, BUENOS DIAS!!
Darkbytes eh modificado mi código según tus recomendaciones, hice los siguientes cambios:

-actualicé mi compilador (ccs) a una versión mas reciente
-las variables las puse tipo signed para que no me arrojara advertencias de valores menores a cero
-elimine la interrupción que tenia la rutina de modificación de hora y toda esa rutina la puse dentro del bucle principal (while).

Con estas modificaciones el compilador ya no me arroja todas las advertencias que me arrojaba pero al simular después de un corto tiempo sigo teniendo el error de que aparecen valores extraños en la hora y la fecha.

Después de esto intente colocar tu código ejemplo (está adjunto en la carpeta) pero no pude colocarlo bien ya que ahi tienes una función para escribir y leer el ds1307 que no enconté pero aparte de eso no entiendo porque se modifican los valores del ds1307, no eh modificado su rutina
adjunto imagenes, librerias y codigo con simulacion.
MUCHAS GRACIAS


----------



## D@rkbytes (Jun 4, 2016)

Yo pienso que el problema se encuentra en la rutina de conversión a BCD, pero no está incluida la librería de esa rutina.
También sigue faltando la librería flex_lcd.

La rutina para leer el DS1307 está dentro de la librería DS1307.c
De hecho tiene las rutinas básicas que se requieren.


----------



## roberttorres (Jun 4, 2016)

Buenas arturkick
Estuve analizando tu código , y veo que lo estas complicando demasiado, ya en tu librería ds1307.c tienes todas las funciones de leer y escribir la rtc, solo la tienes que llamar desde tu programa principal.
por ejemplo:

```
#include <16f887.h>
#fuses XT,noprotect,nomclr
#use delay(clock=4M)
#include <DS1307.c>
#use standard_io(B)
#use standard_io(D)
#define LCD_ENABLE_PIN  PIN_B0                                    ////
#define LCD_RS_PIN      PIN_B1                                    ////
#define LCD_RW_PIN      PIN_B2                                    ////
#define LCD_DATA4       PIN_B4                                    ////
#define LCD_DATA5       PIN_B5                                    ////
#define LCD_DATA6       PIN_B6                                    ////
#define LCD_DATA7       PIN_B7  
#include <LCD420.c>
void main (void){ 
   signed int sec2,min2,hora2,dia2,mes2,anio2,dow2; //se establece la fecha inicial a mostrar por medio del valor de las variables
   ds1307_init(); //inicia la rtc ds1307 (funciones de la libreria)
   lcd_init();// inicia la lcd
 while(true){  
   delay_ms(1000);
   ds1307_get_date(dia2,mes2,anio2,dow2);//funcion de la libreria para leer dia, mes , año, dia almacenada en la rtc.
   ds1307_get_time(hora2,min2,sec2);//funcion de la libreria para leer hora, minutos, segundos almacenadas en la rtc
   lcd_gotoxy(13,1);//posicion en el lcd
   printf(lcd_putc,"\%02d:\%02d:\%02d",hora2,min2,sec2);
   lcd_gotoxy(1,1);
 printf(lcd_putc,"%02u/%02u/20%02d",dia2,mes2,anio2);
}
}
//PD: esta funcion sirve para guardar los datos en la rtc:
//ds1307_set_date_time(dia2,mes2,anio2,dow2,hora2,min2,sec2);
```


----------



## FELIPESANCHEZ (Jun 6, 2016)

hola tengo una duda a cerca si se puede modificar la fecha, la hora desde hyperterminal (comunicacion serial) estoy atorado y no se que puedo hacer, entiendo que para cambiar fecha, hora es necesario modificar en la libreria dando valor a las variables de hora, min, sec, day, daw,month, year, pero no se como podria cambiar dichos valores desde una comunicacion serial


----------



## D@rkbytes (Jun 6, 2016)

Establece un menú de opciones por RS-232 en el cual se pidan los datos de fecha y hora.
Para eso no es necesario modificar la librería, únicamente pasa los datos obtenidos a las rutinas de la librería.


----------



## FELIPESANCHEZ (Jun 7, 2016)

*S*i, perd*ó*n*.* *D*espu*é*s de postear vi que no es necesario modificar toda la librer*í*a, simplemente modificando esta parte del programa se puede*.*

*ds1307_set_date_time(7,6,16,3,9,20,00);*

*A*hora lo que pretendo es hacer lo siguiente:

*ds1307_set_date_time(day2,mth2,year2,dow2,hr2,min2,sec2);*

*L*o que ya n*o* me queda claro*,* es si est*á* b*ie*n que los declare como int8.
*Y* que si del puerto serial es posible enviar valores enteros, o es mejor pasarlos de ASCII.
*¿Có*mo me aconsejan que haga la asignaci*ó*n de los valores*,* con un for, o mediante un arreglo*?*


----------



## D@rkbytes (Jun 7, 2016)

Repito, no tienes que modificar la librería, sólo tienes que pasarle parámetros.

Si la rutina te pide los datos como byte = *int *= *int8*, debes proporcionarlos como byte.

```
void ds1307_set_date_time([B]BYTE[/B] day, [B]BYTE[/B] mth, [B]BYTE[/B] year, [B]BYTE[/B] dow, [B]BYTE[/B] hr, [B]BYTE[/B] min, [B]BYTE[/B] sec)
```
Por RS-232 no se puede enviar un valor superior a 255 = 8 Bits = 1 Byte.
Se pueden enviar valores superiores, pero en partes (Bytes) que después integrarás para obtener el valor.
Por lo tanto, todo lo que envías por RS-232 es en ASCII.
Si envías el número 255, (como entero) realmente se envía como ASCII. 255 en ASCII = *ÿ*
Si lo envías como cadena, se envía () O sea, el equivalente de cada carácter en ASCII.

Para la asignación de valores puedes usar un arreglo o variables únicas.
Para la estructura de recepción, puedes usar un bucle while, que posiblemente use bucles for.


----------



## arturkick (Jun 23, 2016)

D@rkbytes dijo:


> Yo pienso que el problema se encuentra en la rutina de conversión a BCD, pero no está incluida la librería de esa rutina.
> También sigue faltando la librería flex_lcd.
> 
> La rutina para leer el DS1307 está dentro de la librería DS1307.c
> De hecho tiene las rutinas básicas que se requieren.



HOLA buenos días, gracias por responder,por carga de trabajo me pause un poco con este programa pero ya volviendo, me puse a intentar con las instrucciones propias de la librería ds1307 y cuando quiero modificar los datos (hora, minuto, día, año, mes) si se modifican pero solo funciona bien por unos pocos segundos pues después me arroja datos muy extraños, realmente me eh bloqueado en ese paso, otra cosa que hice fue hacerlo con una memoria externa (no necesario pero por desesperación  ) y para que te comento; mejor regrese a lo mismo. quiero que este programa sea un aporte, así que cuando quede (después de añadirle otras funciones) lo subiré al foro. Una disculpa por haber olvidado incluir algunos archivos, ahora si los adjunto, quedo pendiente y AGRADEZCO MUCHO TU AYUDA



			
				arturkick dijo:
			
		

> HOLA buenos días, gracias por responder,por carga de trabajo me pause un poco con este programa pero ya volviendo, me puse a intentar con las instrucciones propias de la librería ds1307 y cuando quiero modificar los datos (hora, minuto, día, año, mes) si se modifican pero solo funciona bien por unos pocos segundos pues después me arroja datos muy extraños, realmente me eh bloqueado en ese paso, otra cosa que hice fue hacerlo con una memoria externa (no necesario pero por desesperación  ) y para que te comento; mejor regrese a lo mismo. quiero que este programa sea un aporte, así que cuando quede (después de añadirle otras funciones) lo subiré al foro. Una disculpa por haber olvidado incluir algunos archivos, ahora si los adjunto, quedo pendiente y AGRADEZCO MUCHO TU AYUDA



aqui dejo los archivos correspondientes


----------



## D@rkbytes (Jun 23, 2016)

Me parece que debes tener más cuidado al programar, ya que tienes varios problemas.


 En la rutina "temperatura" no estás defiendo el canal a usar. Hace falta: setup_adc_ports(sAN2);
Sigues comparando una variable sin signo con un valor menor a 0: if(menu<0)menu=6;
Debes ver que parte de tu programa genera contenciones lógicas en los pines RD4, RD5, RD6 y RD7


Todo esto puede provocar que el microcontrolador no opere correctamente y por consecuencia fallen las rutinas del DS1307.

Te sugiero que realices pruebas independientes de tus rutinas y cuando las tengas funcionando sin problemas, las incluyas a tu programa principal.​


----------



## arturkick (Jun 23, 2016)

D@rkbytes dijo:


> Me parece que debes tener más cuidado al programar, ya que tienes varios problemas.
> 
> 
> En la rutina "temperatura" no estás defiendo el canal a usar. Hace falta: setup_adc_ports(sAN2);
> ...


muchas gracias, ya anteriormente había probado por separado las cosas y funcionaban pero con esto que me dices me doy cuenta de que vengo arrastrando esos problemas sin haberme dado cuenta en su momento, tendre mas cuidado y voy a verificar entonces la estructura de mi programa, muchas gracias nuevamente y si ya lo puedo realizar todo de una vez pues estaré subiéndolo.
lo que no entiendo es a que te refieres con "contenciones lógicas" en los pines?, a que se debe o que lo causa?, la verdad quise investigar acerca de ello pero no encontré referencias(excepto una tuya donde explicas un problema con el programa de una lavadora entro del foro ). !!!!!!MUCHAS GRACIAS POR LA AYUDA DARKBYTES  ¡¡¡¡


----------



## D@rkbytes (Jun 23, 2016)

arturkick dijo:


> Lo que no entiendo es a que te refieres con "contenciones lógicas" en los pines.
> ¿A qué se debe, o qué lo causa? La verdad quise investigar acerca de ello pero no encontré referencias (excepto una tuya donde explicas un problema con el programa de una lavadora entro del foro )


Una contención lógica es cuando dos o más terminales (pines) entran en corto circuito.
Esto sucede más en sistemas bidireccionales, cuando ambas se comportan como salidas y sus niveles lógicos son opuestos.

En tu programa lo que puede estar causando esa falla, es la librería que estás usando para la pantalla.
Al no cumplir con los tiempos adecuados de I/O (Entrada y salida) para el bus de datos, entran en colisión.

Solución: Modificar los tiempos de I/O, o usar la librería que viene con el compilador. "lcd420.c"


----------



## arturkick (Jun 24, 2016)

D@rkbytes dijo:


> Una contención lógica es cuando dos o más terminales (pines) entran en corto circuito.
> Esto sucede más en sistemas bidireccionales, cuando ambas se comportan como salidas y sus niveles lógicos son opuestos.
> 
> En tu programa lo que puede estar causando esa falla, es la librería que estás usando para la pantalla.
> ...



Gracias, modificare eso de la librería, incluso supongo que también se podría solucionar con la instrucción -fast_io-, no se; intentare y lo solucionare, muchas gracias y estaré al pendiente con nuevas.


----------



## D@rkbytes (Jun 24, 2016)

arturkick dijo:


> Incluso supongo que también se podría solucionar con la instrucción -fast_io-, no sé.


La instrucción "fast_io(_puerto_)", sirve para indicarle al compilador que utilice el puerto cómo se defina con la instrucción "set_tris__puerto()_"

Por ejemplo, si tengo: *#use* *fast_io(b)
*// _Defino los pines que serán entradas y salidas._
*set_tris_b(0b11111000);* // _RB2, RB1 y RB0 como salidas._

Si después escribo, *output_b(0xFF);* // _Únicamente se pondrán en 1 los bits declarados como salidas.
_Si no se hubiera declarado "fast_io(_puerto_)", todo el puerto B se pondría en 1, aunque se haya declarado con "set_tris_b(_valor_);", que <RB7:RB3> sean entradas.

De esa forma el compilador respetará los pines definidos como entradas o salidas usando la instrucción "set_tris_x(_valor_)"​


----------



## arturkick (Jun 24, 2016)

D@rkbytes dijo:


> La instrucción "fast_io(_puerto_)", sirve para indicarle al compilador que utilice el puerto cómo se defina con la instrucción "set_tris__puerto()_"
> 
> Por ejemplo, si tengo: *#use* *fast_io(b)
> *// _Defino los pines que serán entradas y salidas._
> ...


gracias por el conocimiento d@rkbytes, entonces no es como yo creía, definitivamente veré como manejo eso de la flex lcd ya que la librería propia del compilador (lcd420) trae definido el pin RB0 para usarlo con la lcd y yo queria usarlo para hacer interrupción, creo que la librería de lcd420 no se puede modificar como la libreria de lcd 16x2 utilizando #define y reasignar los pines o si?


----------



## D@rkbytes (Jun 24, 2016)

arturkick dijo:


> Creo que la librería de lcd420 no se puede modificar como la librería de lcd 16x2 utilizando #define y reasignar los pines. ¿O sí?


Si se puede modificar, yo ya lo he hecho y por aquí en el Foro podrás encontrar cómo se hace.


----------



## arturkick (Jun 25, 2016)

D@rkbytes dijo:


> Si se puede modificar, yo ya lo he hecho y por aquí en el Foro podrás encontrar cómo se hace.



muchas gracias D@RKBYTES, lo checare


----------



## degeldeacuario (Ago 1, 2016)

Hola, buenas tardes,

Estoy diseñando un reloj  con calendario y múltiples alarmas basado en el libro de microcontroladores pic de Carlos A Reyes. El relog es lo de menos por que esta copiado del libro y funciona. Se me esta complicando mucho con el tema de las alarmas. Estoy usando un pic 16f628a el cual se encarga de traducir los datos de un ds1703 y los compara con los datos guardados en una memoria 24lc04b los cuales son cofigurables.
Hasta ahora estoy comparando únicamente segundos para ver resultados rápidos. por ahora la comparación funciona y no tuve que convertir variables ni nada pero tengo este problema...
Por ejemplo: mientras seteo los segundos estos cuentan en exadecimal y por ejemplo si seteo 0A que seria el equivalente a 10, la comparación entre la memoria y el reloj no funciona, pero si seteo 10 que en exadecimal seria 16 me hace la comparación entre 10 hexadecimal del ds1703 y 16 (10) exadecimal de la memoria y se activa la alarma, lo cual no le encuentro sentido, pero estaba buscando la forma de que para modificar la variable de alarma poner un contador que cada vez que cuente 10 pulsos de seteo me sume 6 puntos para saltar del 09 al 10 sin problema. pero no pude, y ya estoy trabajando a prueba y error por que me quede sin ideas.
una vez que solucione esto la idea es replicarlo hasta que no de mas la memoria del 24lc04b por lo menos 100 veces.
Les dejo el adjunto con mi proyecto y un código desordenado por que ya no se que inventar
Aclaro que estuve revisando el proyecto de D@rkbytes y me parece muy bueno, pero no me quiero alejar mucho de lo que estoy haciendo, a no ser que no me quede otra opción :cabezon:


----------



## D@rkbytes (Ago 1, 2016)

Necesitas convertir a BCD los datos que comparas, para que tengan el mismo formato.
No sé para qué son tantas variables, no las veo necesarias para lo que requieres.
En dado caso, puedes usar arreglos, por ejemplo: Hora Var Byte[23]

Por lo que veo hasta ahora del programa, (que no es mucho) yo si optaría por modificarlo para incluir las rutinas de conversión.


----------



## degeldeacuario (Ago 2, 2016)

Hola d@rkbytes
Ahora estoy leyendo "basic para microcontroladores pic"
Ya leí sobre los array que es para guardar muchos datos diferentes en la misma variable dentro del microcontrolador, no se si se podrá aplicar a una memoria externa, tengo que probar y después les cuento.
Pero por eso puse tantas variables de horas y minutos, en el libro que estaba usando de guia no explica esto de los array, en total quiero que se puedan configurar 36 alarmas diferentes 
Como explique el programa es poco, porque estoy probando la comparación y por eso programe únicamente los segundos para ver un resultado rápido, acá si te voy a tener que hacer caso entonces y poner el conversor, lo que no me queda claro por ejemplo, es que el ds1703 guarda los datos en exadecimal pero volviendo a la cuenta los datos de este saltan por ejemplo de 09 a 10 y no de 09 a 0A como en la memoria. lo que había hecho era que los datos de la memoria me los muestre el display con DEC2 pero al momento de comparar no me funcionaba ni comparando por ejemplo 10 con 10(0A) ni con 10(16) como explique en el mensaje anterior. Por eso el código por ahora quedo como esta escrito en el archivo.
Pero bueno.

Para no explicar tanto me parece que tengo que contar mi objetivo.

Lo que quiero hacer es un reloj calendario (hecho), que tenga la opción de configurar múltiples alarmas y guardarlas en una memoria externa(No terminado).

Gracias por la ayuda, saludos


----------



## D@rkbytes (Ago 2, 2016)

El asunto es que el DS1307 no usa formato hexadecimal, si fuera así no habría problema entre formatos.
Para el microcontrolador es igual un 10 que un 0x0A, porque lo entenderá en binario, 0b1010

El DS1307 usa el BCD (Decimal codificado en binario), donde cada dígito decimal es codificado con una secuencia de 4 bits.

Usa la rutina de conversión del post #19 y tendrás ese problema resuelto.


----------



## degeldeacuario (Ago 2, 2016)

Gracias D@rkbytes excelente, ya pude igualar el tipo de variables y ahora puedo hacer la comparación correctamente.
Ahora voy a seguir con los array a ver hasta donde llego.
Bueno gracias por esta mano, ahora tengo que seguir con una alarma completa y después con las 36 alarmas configurables para terminar.
Gracias nuevamente.


----------



## degeldeacuario (Oct 10, 2016)

Buenas a todos,

Después de 2 meses volví a a retomar mi proyecto (aclaro que sigo experimentando) :estudiando:
Las variables array creo que ya las tengo dominadas (todavía no probé guardarlas en una memoria externa)
Volví a cambiar todo mi proyecto. pero volví a trabarme en el tema de la conversión y comparación.


```
CMCON = 7

DEFINE  I2C_SCLOUT  1    ;para que no necesite resistencia pull-up en SCL

DEFINE  LCD_DREG        PORTA         ; define pines del LCD  B4  a  B7 
DEFINE  LCD_DBIT          0      ; empezando desde el Puerto B4 hasta el B7 
DEFINE  LCD_RSREG       PORTB    ;define el puerto B para conectar el bit RS 
DEFINE  LCD_RSBIT         3      ;este es el puerto B3 
DEFINE  LCD_EREG        PORTB    ;define el puerto B para conectar el bit Enable 
DEFINE  LCD_EBIT          1      ;este es el puerto B2

DS1307  con %11010000
SCL     var PORTB.7        ; pin señal de reloj I2C
SDA     var PORTB.6        ; pin de datos I2C

Hrtc var byte
Mrtc var byte
Srtc var byte

Hbcd var byte
Mbcd var byte
BCDIn   Var Byte
BCDOut  Var Byte
BinHold Var Byte

Cuenta var byte
Hora var byte[24]
Minuto var byte[24]


    Hora[0]=00
    Hora[1]=01
    Hora[2]=02
    Hora[3]=03
    Hora[4]=04
    Hora[5]=05
    Hora[6]=06
    Hora[7]=07
    Hora[8]=08
    Hora[9]=09
    Hora[10]=10
    Hora[11]=11
    Hora[12]=12
    Hora[13]=13
    Hora[14]=14
    Hora[15]=15
    Hora[16]=16
    Hora[17]=17
    Hora[18]=18
    Hora[19]=19
    Hora[20]=20
    Hora[21]=21
    Hora[22]=22
    Hora[23]=23
    
    Minuto[0]=00
    Minuto[1]=02
    Minuto[2]=04
    Minuto[3]=06
    Minuto[4]=08
    Minuto[5]=10
    Minuto[6]=12
    Minuto[7]=14
    Minuto[8]=16
    Minuto[9]=18
    Minuto[10]=20
    Minuto[11]=22
    Minuto[12]=24
    Minuto[13]=26
    Minuto[14]=28
    Minuto[15]=30
    Minuto[16]=32
    Minuto[17]=34
    Minuto[18]=36
    Minuto[19]=38
    Minuto[20]=40
    Minuto[21]=42
    Minuto[22]=46
    Minuto[23]=48
        
lcdout $fe, 1

Inicio:

    for cuenta = 0 to 24
        LCDOut $FE,$80,"Alarma ",dec2 hora[cuenta],":", dec2 minuto[cuenta]
            
            I2CRead SDA,SCL,DS1307,0,[srtc]        
            I2CRead SDA,SCL,DS1307,1,[mrtc]
            I2CRead SDA,SCL,DS1307,2,[hrtc]
        
        LCDOut $FE,$C0,"Hora: ",Hex2 hrtc,":",Hex2 mrtc,":",Hex2 srtc," "
        
        BCDIn = hrtc
        GoSub DecToBCD
        hrtc = BCDOut
        BCDIn = mrtc
        GoSub DecToBCD
        mrtc = BCDOut
            
            if hora[cuenta] = hrtc then
                high porta.7
                pause 1000
            endif 
            
            pause 300
    next cuenta
        pause 300
    goto inicio

DecToBCD:
    BinHold = BCDIn
    BinHold = (BinHold Dig 1) * $10 + (BinHold Dig 0)
    BCDOut = BinHold
    Return

end
```

Probé convertir las alarmas a bcd y no me funciono, probé con las horas a bcd y tampoco me funciono.
La verdad... doy un paso para adelante y 4 para atrás :cabezon:
Adjunto el archivo que estoy usando para simular.
Sigue estando todo muy verde. ene este momento quiero resolver el tema de la comparación nada mas

Al final volví a convertir las alarmas. pero tuve que agregar 2 variables mas en el conversor para después usarlas para comparar Esta nueva etapa ya me quedo funcionando


----------



## degeldeacuario (Ene 11, 2017)

Buenas,

Por suerte ya tengo el reloj terminado y funcionando, todo como se describe arriba y con alguna pequeñas mejoras de interfaz.
Como había comentado antes, ahora estoy experimentando con la memoria eeprom del módulo de reloj rtc que en este caso viene con una memoria 24C32n.

Como siempre me estoy apoyando en el libro "microcontroladores pic - programación en basic".
Bueno yendo al grano programó el ejemplo que viene en el libro de como escribir y leer una memoria eeprom (en este caso 24lc04b)
En este caso puedo escribir y leer perfectamente una cadena de texto, pero lamentablemente no puedo escribir y leer números (trate de entender el datasheet pero esta en ingles) pero bueno, tengo la satisfacción de que escribe y lee algo.

Paso a la memoria 24c32a (proteus no tiene la memoria 24c32n) Y en este caso me devuelve todos caracteres negros, tambien lei el datasheet para ver que podia comparar con el del 24lc04b, lo único que me llamo la atencion es que el bit de control cambia para la lectura y escritura, así que cree dos constantes, una para escribir y la otra para leer pero no surtió ningún efecto (lo raro es que el 24lc08b tampoco lo alteró y funcionó como describo en el párrafo anterior) así que también descarte esta opción.

Hasta ahora lei:
"Manual original del pic basic compiler pro" traducido al español por Luis Frino
https://www.forosdeelectronica.com/f24/escribir-leer-eeprom-externa-15824/
https://www.forosdeelectronica.com/f24/usar-eeprom-pics-23626/
https://www.forosdeelectronica.com/f24/programa-eeprom-24xxx-ser-leida-pic-96291/
que me llevo a
https://www.forosdeelectronica.com/f24/matriz-leds-7x80-animada-18135/
En este caso el usuario *cevollin* logra leer desde una memoria 24c32a sin problemas (pero en el código "Basic" no veo nada sobre escritura pero si sobre lectura) simule el circuito y funciona perfecto.
 A mi circuito por ejemplo le faltaban las resistencias de 10KΩ que puso cevollin en las patas sda y scl, se las puse pero en el circuito no surtió efecto. Asi que decidi dejarlo como en el ejemplo del libro que tengo de guia 4,7KΩ en la pata sda.

Ahora bien, ¿que quiero hacer? guardar mis alarmas en esta memoria (esto a futuro)
Ahora quiero poder escribir y leer en la memoria 24c32a texto y números.
Y me gustaria saber en que le estoy errando después de haber leído tanto:cabezon:

Este es el codigo que estoy usando:

```
DEFINE   I2C_SCLOUT  1    ;para que no necesite resistencia pull-up en SCL 

DEFINE  LCD_DREG        PORTB         ; define pines del LCD  B4  a  B7 
DEFINE  LCD_DBIT          0      ; empezando desde el Puerto B4 hasta el B7 
DEFINE  LCD_RSREG       PORTB    ;define el puerto B para conectar el bit RS 
DEFINE  LCD_RSBIT         5      ;este es el puerto B3 
DEFINE  LCD_EREG        PORTB    ;define el puerto B para conectar el bit Enable 
DEFINE  LCD_EBIT          4      ;este es el puerto B2
 
escribir   CON   %10100000        ;escribir en eeprom 24c32a
lectura    con   %10100000        ;leer desde eeprom 24c32a
PinSCL     VAR   Portb.7          ;pin señal de reloj I2C 
PinSDA     VAR   Portb.6          ;pin de datos I2C 
dato       VAR byte               ;variable para almacenar dato leído
 
Inicio: 
LCDOUT $fe,1," Grabando..."       ;limpiar y sacar el texto en LCD 
PAUSE 1000 
 
I2CWRITE PinSDA,PinSCL,escribir,0,["1"]      ;guarda la H en posición 0 
    PAUSE 100                                       ;pause para la grabación 
I2CWRITE PinSDA,PinSCL,escribir,1,[2]      ;guarda la O en posición 1 
    PAUSE 100                                       ;pause para la grabación 
I2CWRITE PinSDA,PinSCL,escribir,2,[$3]      ;guarda la L en posición 2 
    PAUSE 100                                       ;pause para la grabación 
I2CWRITE PinSDA,PinSCL,escribir,3,["a"]      ;guarda la A en posición 3 
    PAUSE 100                                      ;pause para la grabación 
 
LCDOUT $fe,1,"Leer memoria"      ;limpiar y sacar el texto en LCD 
 
PAUSE 1000 
LCDOUT $FE,1                                ;limpiar pantalla del LCD 
 
leer:                                         ;programa para leer la memoria serial. 
 
I2CREAD PinSDA,PinSCL,lectura,0,[dato]      ;leer la mem. 0 y guardar en dato
    LCDOUT, dato                           ;mostrar dato en el LCD
    PAUSE 1000                                ;esperar 1 seg. 
I2CREAD PinSDA,PinSCL,lectura,1,[dato]      ;leer la mem. 1 y guardar en dato 
    LCDOUT, dato                            ;mostrar dato en el LCD 
    PAUSE 1000                                ;esperar 1 seg. 
I2CREAD PinSDA,PinSCL,lectura,2,[dato]      ;leer la mem. 2 y guardar en dato 
    LCDOUT, dato                            ;mostrar dato en el LCD 
    PAUSE 1000                                ;esperar 1 seg. 
I2CREAD PinSDA,PinSCL,lectura,3,[dato]      ;leer la mem. 3 y guardar en dato 
    LCDOUT, dato                            ;mostrar dato en el LCD
    PAUSE 1000
;*************estas lineas son unicamente para la simulacion**************
LCDOUT $fe,1,"fin de lectura"               ;limpiar y sacar el texto en LCD 
 
PAUSE 1000 
LCDOUT $FE,1                                ;limpiar pantalla del LCD  
goto inicio
;*************estas lineas son unicamente para la simulacion**************

END
```

Dejo todas las capturas del funcionamiento del circuito:
Primero con el 24lc04b donde se ve que no me reconoce los números.
Segundo con el 24c32a donde me devuelve todos caracteres negros.
Tercero en el debug las primeras 8 líneas son de escritura y lectura del 24lc04b y el segundo grupo de 8 son los datos de escritura y lectura del 24c32a.

Bueno espero no haber molestado a nadie, D@rkbytes por favor, decime si hago un tema nuevo por esto o sigo aca. En el caso de que tenga que hacer un tema nuevo por favor no me borren el mensaje asi lo copio a un post nuevo.

Desde ya muchas gracias por evacuar mis dudas


----------



## D@rkbytes (Ene 11, 2017)

No es lo mismo escribir caracteres cómo letras, que números cómo enteros decimales.
O sea, no es lo mismo "1" que 1
El número 1 entre comillas es cómo texto, y sin comillas equivale al ASCII 49

Por ejemplo:
Si guardas el número 255 sin comillas, y después quieres verlo en LCD, verás un cuadro negro.
Si lo guardas con comillas ("255") se ocuparán 3 bytes, porque equivale a una cadena de texto.
Así que dependiendo de la forma en que debe interpretarse el dato, así debe ser leído y también procesado.

Para visualizar el 255 cómo texto, se usa un formateo de datos.
*Dato = 255*
*I2CWrite SDA, SCL, $A0, 0, [Dato]   ; Escribir 255 en la posición 0 de la EEPROM.
Dato = 0 ; Limpiar la variable "Dato" (Sólo para comprobar lectura)
**I2CRead* *SDA, SCL, $A0, 0, [Dato]* *; Leer la posición 0 de la EEPROM.
LCDOut $FE, $80, "Dato = ", Dec3 Dato ; Mostrar el dato leído en pantalla.
*
*Dec3* hace el formateo de decimal a cadena de texto, y de esa forma podrá ser visualizado en pantalla.
Cuando son letras no hay problema y ya no se usa *DecX* (Donde X equivale a la cantidad de dígitos)
Para mostrar números también se puede usar el comodín *#
*Ejemplo:
*LCDOut $FE, $80, "Dato = ", #Dato*
Pero de esa forma el número será mostrado sin formato, y si la variable cambia de valor, se montará el nuevo resultado sobre el valor anterior, lo cual puede causar confusiones de interpretación.


----------



## degeldeacuario (Ene 11, 2017)

Gracias D@rkbytes, siempre salvandome

Probe ahora el formateo tal cual me dijiste y funciono perfectamente en el 24lc04b

Ahora en el 24c32a lo único que hace es mostrarme 255 por cada carácter. Para mi le tengo que estar errando en alguna declaración de escritura en esta memoria, ya que la lectura la realiza pero por lo visto la escritura no. No se, ¿que te parece? ya puse las resistencias de pull up como cevollin y nada. y en las páginas y manuales que lei no dice mas nada aparte de la declaración de la función que obviamente es siempre la misma en PBP 
Pensaba que era un problema de simulación, pero lo descarto totalmente porque al fin de cuentas la memoria 24lc04b esta funcionando perfectamente ahora.

Gracias nuevamente


----------



## D@rkbytes (Ene 11, 2017)

Las memorias nuevas o vírgenes, vienen por defecto con 255 en todas sus locaciones.
Eso se debe tener en cuenta al momento de leer una dirección, porque puedes tomar como válido un 0xFF en lugar del dato adecuado.
Así que no esperes leer otra cosa si la memoria no ha sido grabada.
Eso no quiere decir que no se pueda tomar como válido un valor de 255, pero eso lo determinarás tú.

PD: Las resistencias pullup si son necesarias, coloca resistencias de 4.7 KΩ


----------



## degeldeacuario (Ene 11, 2017)

D@rkbytes ya puse la resistencia pull up que faltaba en el pin SCK y sigo sin resultados en la memoria 24c32a.
Te adjunto mi simulación de proteus y el archivo HEX, ¿podrias hacerme el favor de verificarlos? esta todo tal cual las imágenes e incluyen las mejoras que me recomendaste. ¿Quiero saber que es lo que se me está escapando?
_En la simulación hay una selectora para leer cada memoria a gusto, no es parte del proyecto original ni siquiera el 24lc04b, están únicamente para probar el código sin interrupciones._

La memoria 24lc04b sigue funcionando sin problemas


----------



## D@rkbytes (Ene 11, 2017)

Las memorias del tipo 24LC32 en adelante, son memorias Smart y se direccionan con un puntero Word. (16 Bits)
Así que no puedes leer o escribir ambas por el mismo procedimiento que una Estándar. (P.E. 24LC04)


----------



## degeldeacuario (Ene 15, 2017)

Buenas gente,

Ya pude leer y escribir en la memoria 24C32a.
Después voy a publicar un tutorial en pic basic pro, para que les sirva de guía a los que puedan llegar a tener este problema, ya que me costó bastante conseguir esta información y al final era realmente sencillo 
Gracias por la orientación


----------



## dcsalg (May 15, 2017)

Hola, estoy tratando de hacer funcionar en Proteus el Pic con el reloj DS1307 y un LCD. El LCD lo controlo con un PCF8574, donde al principio utilizaba tanto el DS1307 como el control del PCF8574 en el mismo I2C pero no funciono el display muestra valores 00:00:00  00/00/00 pense porque estaban ambos en el mismo I2C , entonces cambia y coloque el display en el I2C numero 2 dado que el pic tiene 2 I2C pasa exactamente lo mismo. a mi me gustaria controlar ambas cosas en un mismo I2C perop nose porque el display Funciona pero el DS1307 no. Me podrian Ayudar es seguro tema de programacioon pero no le encuentro el error. Adjunto los Dos Archivos ZIP uno del CCS y el otro del proteus. El Archivo FSC01.zip es el programa en C con CCS, y testeo01.zip es el de proteus.
En el programa el clock esta en 4MHZ hay que pasarlo a 8MHZ que es la frecuencia que utilizare.  Gracias


```
#include <18F46K22.h>
#device ADC=10
#device  *=16


#fuses NOWDT

#use delay(internal=8MHz)
#use STANDARD_IO( C )
#use STANDARD_IO( B )

#use i2c(Master, I2C1,slow, STREAM=I2COM1) //,sda=SDA1,scl=SCL1)
#use i2c(Master,FAST, I2C2, STREAM=I2COM2) //,sda=SDA1,scl=SCL1)



#ZERO_RAM

unsigned int fh=0;

/******************************* MODULO LCD I2C ***************************************/
//#use i2c(Master, Fast, I2C1, force_hw)  
#define clear_lcd       (printf(lcd_putc_i2c,"\f"))       //MACRO BORRA LCD
#define send_lcd(dat)   (printf(lcd_putc_i2c,dat))    //MACRO ESCRIBE LCD
#define PCF8574A                 // tipo de modulo que se utiliza           
#define A2_A1_A0 0B111           // direccion del modulo (A2 A1 A0) PCF8574A/PCF8574.
#define LCD20X4                  // tipo de display a utilizar o  LCD 16x2
#include <lcd_i2c_pcf8574_DCS.c>
/**************************************************************************************/

#include <DS1307_dcs.c>


#INT_TIMER0
void  TIMER0_isr(void) 
{
   fh++;
   set_timer0(6);
}

void main()
{
   
   ds1307_init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);
   
   ds1307_set_date_time(15,03,17,1,20,00,50);   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //|RTCC_8_BIT);      //64,0 us overflow
   set_timer0(6);
      
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   
   lcd_init_i2c();   //Inicializa lcd i2c 
   
   while(TRUE)
   {
      
      if(fh>4) { 
         disable_interrupts(INT_TIMER0); 
         fh=0;
         ds1307_get_date(day,month,yr,dow);
        ds1307_get_time(hrs,min,sec);
        lcd_gotoxy_i2c(1,1);
        printf(lcd_putc_i2c,"%02u/%02u/%02u       %02u:%02u",day,month,yr,hrs,min);
         enable_interrupts(INT_TIMER0);
      }
      
   }

}
```


----------



## D@rkbytes (May 15, 2017)

Para simular correctamente el bus I2C en proteus, debes establecer que las resistencias pull-up sean digitales.
En tu esquema son las resistencias R11 y R12

Cambia sus propiedades y verás que todo debe funcionar, incluso por el mismo bus I2C.


----------



## dcsalg (May 16, 2017)

Uh Gracias!!!! aprendi algo nuevo, no sabia eso de proteus, no es como en la vida real que pones las resistencias en I2C y funcionan? uyo habia pensado que si. Yo porque no tengo aun el display, porque si lo pronbaba en protoboard seguramente no tendria problemas capaz.  Muchgas Gracias!!!


----------



## ShangriLa (May 26, 2018)

Hola, buenas noches, tengo un problema con mi codigo, y es que no se por que, no recibe la señal por bluetooth, estoy simulandolo en proteus con un virtual terminal, pero no importa lo que mande, no lo lee, se queda estancado en esa parte del codigo esperando el numero, no se que problema pueda haber


```
#include <16F877A.h>
#FUSES XT, NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8 )
#include <lcd.c>
#include <ds1307.c>                                        //Libreria para reloj en tiempo real ds1307
#include <stdlib.h>                                        //Libreria stdlib
#include <math.h>                                          //Libreria math
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#BYTE TRISB = 0X86
#BYTE PORTB=0X06
#BYTE TRISA = 0X85
#BYTE PORTA=0X05
#int_RDA
char valor;
 RDA_isr()
 {
 valor=getc;
 }
int sec;                           //Da de alta lo senteros sec,min,hrs,day,month,yr,dow etc
int min;
int hrs;
int8 seg, seg1, seg2;             //Segundos
int8 min3, min1, min2;            //Minutos
int8 hrs3, hrs1, hrs2;            //Horas
int8 sem, sem1, sem2;             //Semanas
int8 dia, dia1, dia2;             //Dias
int8 mes, mes1, mes2;             //Meses
int8 a, a1, a2;                   //Años
int8 i,j;       

void main(){                      //Programa principal
   TRISB=0x00;
   TRISA=0xFF;
                       //Declara el caracter k
   int8 unidad;  //idk cosa del display
   char data[6];                  //Declara el caracter data con 6 digitos
   char data2[8];                 //Declara el caracter data2 con 8 dígitos
   byte const DISPLAY[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
   ds1307_init ();                //se inicializa el ds1307
 
   set_tris_a (0xff) ;           //Declara porta como salida,d como entrada, b como entrada, c y e mixto
   set_tris_d (0x00) ;
   set_tris_b (0x00) ;
   set_tris_c (0x04) ;
   set_tris_e (0x01) ;
   port_b_pullups (true) ;       //Activa resistencia pull up
   lcd_init ();                  //inicializamos lcd
enable_interrupts(int_RDA);
enable_interrupts(GLOBAL);
inicio:
 data[0]=0;                      //Declara los valores iniciales de todas las variables en 0
 data[1]=0;
 data[2]=0;
 data[3]=0;
 data[4]=0;
 data[5]=0;
 data2[0]=0;
 data2[1]=0;
 data2[2]=0;
 data2[3]=0;
 data2[4]=0;
 data2[5]=0;
 data2[6]=0;
 data2[7]=0;
 
 seg=0, seg1=0, seg2=0;
 min3=0,min1=0, min2=0;
 hrs3=0,hrs1=0,hrs2=0;
 sem=0, sem1=0, sem2=0;
 dia=0, dia1=0, dia2=0;
 mes=0, mes1=0, mes2=0;
 a=0, a1=0, a2=0;
 i=0, j=0;
 printf(lcd_putc, "\f");                     // Limpiar LCD




 while (TRUE){                               //Ciclo infinito

  lcd_gotoxy(1,1);                           //Indica posicion en que se mostrara el mensaje
  printf(lcd_putc, "\fInserte hr:mi:seg");   //Pide escribir la hora  en la lcd
   lcd_gotoxy(1,2);                           //Indica posicion en que se mostrara el mensaje
  printf(lcd_putc, "no sale %c",valor);   //Pide escribir la hora  en la lcd
  delay_ms(700);                             //Retardo 700ms
   while(i<=5){                              //Mientras i es menor o igual a 5
    valor=getc();                           // Lee el teclado
    data[i]=valor;                              // Valor data[i]= caracter introducido por teclado
     i++;                                    // Incrementar i
     lcd_gotoxy(1,1);                        //Indica posicion donde se mostrara el mensaje
     printf(lcd_putc, "Inserte hra:mi:seg");  //Pide  escribir la hora
     lcd_gotoxy(1,2);                        //Indica la posicion donde se mostrara el mensaje
     printf(lcd_putc,"%c%c:%c%c:%c%c",data[0],data[1],data[2],data[3],data[4],data[5]);  //Muesta la hora segun lo seleccionado en el teclado   
     delay_ms(500);                          //Retardo 500 ms
              
           }
  ////////////////////////////////////Lo mismo para la fecha, solo ultiliza los valores en data2 y con j
  delay_ms(700);       
    hrs1= data[0] - 48;   // Convertir data[0] de ASCII a valor numérico
    hrs2= data[1] - 48;   // Convertir data[1] de ASCII a valor numérico
    min1= data[2] - 48;   // Convertir data[2] de ASCII a valor numérico
    min2= data[3] - 48;   // Convertir data[0] de ASCII a valor numérico
    seg1= data[4] - 48;
    seg2= data[5] - 48;
    hrs3= ((hrs1*10)+ hrs2);    //Convierte los numeros individuales en su valor combinado, es decir al teclear 12 son valores separados 1,2 no 12 aqui hacemos q 1,2 sea 12
    min3= ((min1*10)+ min2);
    seg= ((seg1*10)+ seg2);
    printf(lcd_putc, "\f");            //Borra lo mostrado en la lcd
////////////////////////////////////////////////////////////////////////////////   
   ds1307_set_date_time (dia, mes , a, sem, hrs3, min3 , seg); // Guarda en el reloj la hora que se establece con el teclado 
   WHILE (1){                          //Ciclo infinito
      delay_ms (100) ;                 //Retardo 100ms
      ds1307_get_time (hrs, min, sec);   //se obtiene la hora
      lcd_gotoxy (1, 2) ;               //Indica la posicion donde se mostrara el mensaje
      printf (lcd_putc, " %02d:%02d:%02d  ", hrs,min,sec); ///se despliegan los datos   
      PORTB=DISPLAY[unidad];
      delay_ms(50);
      PORTA=0b011111;
      unidad=hrs1; //hora 1 en display izquierda
      delay_ms(50);
       PORTA=0b101111;
      unidad=hrs2;//hora 2 en display derecha
      delay_ms(50);
       PORTA=0b110111;https://www.forosdeelectronica.com/threads/reloj-con-ds1307-no-arranca-en-la-pr%C3%A1ctica.79541/page-6
      unidad=min1;//min1 en display izquierda
      delay_ms(50);
       PORTA=0b111011;
      unidad=min2;//min2 en display derecha
      delay_ms(50);
       PORTA=0b111101;
      unidad=seg1;//seg 1 en display izquierda
      delay_ms(50);
       PORTA=0b111110;
      unidad=seg2;//seg 2 en display derecha
      delay_ms(50);
   }
  
}
}
```


----------



## D@rkbytes (May 26, 2018)

ShangriLa dijo:


> no importa lo que mande, no lo lee, se queda estancado en esa parte del codigo esperando el numero


Veo el código bastante conflictivo y con muchas cosas innecesarias.

Adjunto un ejemplo que te puede servir.
El programa original fue realizado por el amigo Shawn Johnson para el compilador BoostC
Hace algún tiempo me dí a la tarea de migrarlo a PCWHD Compiler de CCS.

Nota: El retardo de 50 mS. que estás usando para multiplexar los displays, es excesivo, con 1 o 2 mS. sería suficiente.


----------



## crazysound (Ago 15, 2018)

Buenas tardes D@rkbytes, por que veo sos un experto en esto de la programación..!! 
Voy a pedir un poco de ayuda .. Soy técnico electrónico pero con poco conocimiento en este campo..

He descargado un reloj con pic16f628, programado en C (lenguaje que conozco un poco), y quiero modificarlo para usarlo con el pic16f876a que tiene un puerto más, para poder usarlo con salidas de alarma p.e. 
No se por qué no funciona. Adjunto la simulación, el código fuente y el hex.. Desde ya muchas gracias..!!


----------



## D@rkbytes (Ago 15, 2018)

crazysound dijo:


> Buenas tardes @D@rkbytes, por que veo sos un experto en esto de la programación..!!
> Voy a pedir un poco de ayuda .. Soy técnico electrónico pero con poco conocimiento en este campo..


Saludos. Siento mucho no poder colaborar en este momento, ya que me cambié de ciudad y aún estamos montando el taller.
Mañana instalan el Internet en el local y ya con eso podré usar mi computadora.
Sin embargo, aún quedan muchas cosas por hacer que me mantienen muy ocupado.

Mientras tanto, esperemos que otros miembros del Foro te puedan brindar ayuda, ya que aquí existen muchas personas que también tienen amplios conocimientos en programación.


----------



## roberttorres (Ago 16, 2018)

crazysound dijo:


> No se por qué no funciona. Adjunto la simulación, el código fuente y el hex.. Desde ya muchas gracias..!!


Yo no soy experto, solo un hobista, el problema que he notado es en la simulación, en la edición de propiedades del microcontrolador solo debes de destildar la opcion "Attach hierarchy module" y ya funciona.


----------



## crazysound (Ago 16, 2018)

Graaaaandeeee roberttorresss..... funciona!!!!! 

Ahora qué significa??

Gracias roberrtorres y D@rkbytes por responder..!

Otra consulta muchachos... fíjense que la pata 10 del pic aparece como si no funcionara.. Me faltará algo en la programación? Acuérdense que está hecho para el 16f628..


----------



## D@rkbytes (Ago 16, 2018)

crazysound dijo:


> Otra consulta muchachos... fíjense que la pata 10 del pic aparece como si no funcionara.. Me faltará algo en la programación? Acuérdense que está hecho para el 16f628


El pin 10 del PIC16F876A es la salida de reloj del oscilador a cristal y únicamente si esa opción está configurada en los fuses.
No tiene otra función de E/S porque ese PIC no tiene oscilador interno.


----------



## crazysound (Ago 16, 2018)

Hola d@rkbytes, con esto es suficiente?: #use delay(clock=4000000)

Saludos..


----------



## D@rkbytes (Ago 16, 2018)

No, te falta definir el tipo de oscilador en los fuses.
XT para un cristal de hasta 4 MHz y HS desde 4 hasta 20 MHz.
#fuses XT

En PIC C de CCS se puede definir más sencillo de esta forma:
#use delay(crystal = 4 MHz)
Con eso el compilador establece el fuse XT_OSC automáticamente.

Si requieres otras cosas como las protecciones de código y EEPROM, lo declaras en los fuses.


----------

