Autor Tema: Problemas con el timerkeeper DS1302  (Leído 2248 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Roger_Fernandez

  • PIC10
  • *
  • Mensajes: 18
Problemas con el timerkeeper DS1302
« en: 03 de Agosto de 2004, 17:21:00 »
Hola!
Tengo un problema tratando de utilizar el timerkeeper de Dallas DS1302.
He tratado de seguir las indicaciones de las hojas de datos pero no he ten ido éxito. No se si el problema será de software o de hardware.
Les explico como lo he hecho. Utilizo para comandar el Timerkeeper un PIC 16F628.
La conexión física la realice de la siguiente manera:

Pin 1: Masa.
Pin 2: Cristal.
Pin 3: Cristal.
Pin 4: Masa.
Pin 5: Pin RB7 del PIC (RESET).
Pin 6: Pin RB6 del PIC (IO).
Pin 7: Pin RB5 del PIC (SCLK).
Pin 8: 5 V.

Seleccione esta forma de conexión siguiendo la recomendación de la Nota de Aplicación 82: Using the Dallas Trickle Charge Timekeeper de Dallas. En ella explica las distintas formas de conexión, dependientes del uso o no de batería de respaldo. Yo utilice la opcion 2B, que corresponde a la alimentación simple sin batería de respaldo. En mi circuito tengo una alimentación permanente sobre el timerkeeper que proviene de una batería grande. El resto del circuito tiene una alimentación que es posible desconectar, dejando solo el timerkeeper en funcionamiento.


El hardware aparentemente es muy simple y no debería tener problemas. Ahora explico el software.
La idea es tomar la fecha y la hora desde la PC, colocar estos datos en 8 bytes de la memoria RAM y mediante una rutina escribir los valores en el timerkeeper.
Luego, cuando se produzca un determinado suceso, se lee los datos del timerkeeper y se los coloca en la memoria RAM, para luego escribirlos en una memoria serial EEPROM.
Para ello disponemos de 8 bytes definidos en la memoria RAM:

;Bloque de memoria desde 70h hasta 77h
;Utilizado para almacenar la Fecha y la Hora

         cblock 70h
         Segundo         
         Minuto         
         Hora
         Dia            
         Mes   
         DiaSemana         
         Ano   
         ProteccionEscritura      
   endc

Defino los puertos y los pines del PIC relacionados con el Timerkeeper

Puerto_Timer      equ 06h

SCLK            equ 05h
IO            equ 06h
RESET         equ 07h

La rutina Escribir_TimerKeeper escribe los datos en el timerkeeper de a uno, es decir direccionando cada registro individualmente.
La rutina Escribir_TimerKeeper_Burst escribe los datos en el timerkeeper en forma secuencial.
Las rutinas Leer_TimerKeeper y Leer_TimerKeeper_Burst funcionan de manera similar, pero con la lectura.

La frecuencia de clock que uso esta dentro de lo establecido. Igualmente probé con una frecuencia menor con igual resultado.
Creo haber respetado los tiempo de los flancos. El tiemerkeeper recepta los datos con el flanco ascendente del clock y los transmite con el flanco descendente.

 

Compare mi código con algunos que conseguí en internet y es básicamente similar.  

La siguiente parte del código es cuando tomo los datos de la PC.

         btfss       PIR1,RCIF   ;Espero que llege el byte
       goto       $-1
       movf       RCREG,W
       movwf   Segundo   ;Cargo el byte en la memoria RAM
             
       btfss       PIR1,RCIF   ;Espero que llege el byte
       goto       $-1
       movf       RCREG,W
       movwf   Minuto      ;Cargo el byte en la memoria RAM
                   
       btfss        PIR1,RCIF   ;Espero que llege el byte
       goto        $-1
       movf        RCREG,W
       movwf    Hora      ;Cargo el byte en la memoria RAM
                   
       btfss        PIR1,RCIF   ;Espero que llege el byte
       goto        $-1
       movf        RCREG,W
       movwf    Dia      ;Cargo el byte en la memoria RAM
                   
       btfss        PIR1,RCIF   ;Espero que llege el byte
       goto        $-1
       movf        RCREG,W
       movwf    Mes      ;Cargo el byte en la memoria RAM
   
       btfss       PIR1,RCIF   ;Espero que llege el byte
       goto       $-1
       movf        RCREG,W
       movwf    Ano      ;Cargo el byte en la memoria RAM

          call    Escribir_TimerKeeper_Burst

y para recuperar los datos del timerkeeper hago lo siguiente:

   call    Leer_TimerKeeper_Burst   ;Leo datos del timerkeeper

   movf        Puntero_Memoria_Low,W    ; Direccion de EEPROM
   movwf    Addressl
   movf        Puntero_Memoria_Hi,W
   movwf    Addressh
      
   movf        Dia,W            ;Dato a guardar      
   movwf    Dato

   call        Escribir_Byte      ;Escribo dato en la EEPROM
   …………………..

Cuando trato de leerlo recibo el byte 80h para todos los registros, es decir, segundos = 80h, Mes = 80h .
Las distintas notas de aplicación hacen bastante hincapié en la calidad y la capacitancia que debe tener el cristal del timerkeeper. En la casa donde lo compre, no tenían datos acerca de la capacitancia del cristal. Sin embargo, me parece que si llegara a fallar el cristal, no debería influir en la parte de comunicación, es decir en la trasferencia de datos, sino simplemente en que el reloj no ‘correría’, o no incrementaría la hora.
He probado con tres DS1302 por lo que descarto que estén defectuosos, ha no ser que halla venido toda una partida mala, cosa bastante improbable o que se estén quemando apenas los coloco, lo que también seria extraño, ya que aparentemente la conexión física es correcta.

Ahora transcribo las rutinas del timerkeeper propiamente dichas:

RegistroTK: Registro utilizado para la transferencia de datos.
ContadorBitsTK: Contador de bit para la transmisión.

;***************************************************

Escribir_TimerKeeper

   bcf            Puerto_Timer,SCLK
   call            retardo_5u
   bcf            Puerto_Timer,IO
   bsf            Puerto_Timer,RESET
   call            retardo_3u

   movlw   b"10001110"   ; Transmito Byte de Control
   movwf   RegistroTK         
                              
   call           Transmitir_Byte

   movlw   b"00000000"   ; Desactivo la protecc. escritura
   movwf   RegistroTK

   call            Transmitir_Byte


   movlw   b"10000000"   ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

         movf          Segundo,W
   movwf   RegistroTK

         call             Transmitir_Byte

   movlw   b"10000010"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

         movf       Minuto,W
   movwf   RegistroTK

         call       Transmitir_Byte

   movlw   b"10000100"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte
 
         movf           Hora,W
   movwf   RegistroTK

          call           Transmitir_Byte

   movlw   b"10000110"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

        movf           Dia,W
   movwf   RegistroTK

           call             Transmitir_Byte

   movlw   b"10001000"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

         movf          Mes,W
   movwf   RegistroTK

           call            Transmitir_Byte

   movlw   b"10001100"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

          movf           Ano,W
   movwf   RegistroTK

         call             Transmitir_Byte

   movlw   b"10010000"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

         movlw        b"00000100"           ; Deshabilito el Trickle Charger
   movwf   RegistroTK

           call           Transmitir_Byte

   movlw   b"10001110"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

         movlw        b"10000000"               ; Pongo contra escritura
   movwf   RegistroTK

   call           Transmitir_Byte

   bcf           Puerto_Timer,SCLK
   call           retardo_3u
   bcf           Puerto_Timer,RESET

          return

;***************************************************

Leer_TimerKeeper

   bcf            Puerto_Timer,SCLK
   call            retardo_5u
   bcf            Puerto_Timer,IO
   bsf            Puerto_Timer,RESET

   call            retardo_3u

   movlw   b"10000001"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

         call             Recibir_Byte                   ; Leo el segundo
         movf          RegistroTK,W
           movwf       Segundo

   movlw   b"10000011"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

           call             Recibir_Byte                   ; Leo el minuto
           movf          RegistroTK,W
           movwf       Minuto


    movlw   b"10000101"      ; Transmito Byte de Control
    movwf   RegistroTK

    call            Transmitir_Byte

           call             Recibir_Byte                   ; Leo la hora
           movf          RegistroTK,W
           movwf       Hora


    movlw   b"10000111"      ; Transmito Byte de Control
    movwf   RegistroTK

    call           Transmitir_Byte

           call            Recibir_Byte                   ; Leo el dia
           movf         RegistroTK,W
           movwf       Dia

   movlw   b"10001001"      ; Transmito Byte de Control
   movwf   RegistroTK

   call            Transmitir_Byte

        call            Recibir_Byte                  ; Leo el mes
            movf          RegistroTK,W
           movwf       Mes


   movlw   b"10001101"      ; Transmito Byte de Control
   movwf   RegistroTK

   call           Transmitir_Byte

           call           Recibir_Byte                   ; Leo el año
          movf          RegistroTK,W
        movwf      Ano

   bcf           Puerto_Timer,IO
   bcf           Puerto_Timer,SCLK
   call           retardo_3u
   bcf           Puerto_Timer,RESET

         return

;***************************************************

Escribir_TimerKeeper_Burst

   bcf            Puerto_Timer,SCLK
   call            retardo_5u
   bcf            Puerto_Timer,IO
   bsf            Puerto_Timer,RESET

   call            retardo_5u


   movlw   b"10001110"      ; Transmito Byte de Control
   movwf   RegistroTK         
                              
   call            Transmitir_Byte

   movlw   b"00000000"   ; Desactivo la protecc escritura
   movwf   RegistroTK

   call            Transmitir_Byte


   movlw   b"10111110"      ; Transmito Byte de Control
   movwf   RegistroTK         
                              
   call            Transmitir_Byte

   movf            Segundo,W
   movwf   RegistroTK   
      
   call            Transmitir_Byte

   movf             Minuto,W
   movwf   RegistroTK   
      
   call            Transmitir_Byte

   movf            Hora,W
   movwf   RegistroTK   
      
   call            Transmitir_Byte

   movf            Dia,W
   movwf   RegistroTK   
      
   call            Transmitir_Byte

   movf            Mes,W
   movwf   RegistroTK   
      
   call            Transmitir_Byte

   movf            DiaSemana,W
   movwf   RegistroTK   
      
   call           Transmitir_Byte

   movf            Ano,W
   movwf   RegistroTK   
   
   call            Transmitir_Byte

   movlw   b"10000000"               
   movwf   RegistroTK

   call            Transmitir_Byte

   bcf            Puerto_Timer,IO
   bcf            Puerto_Timer,SCLK
   call            retardo_3u
   bcf            Puerto_Timer,RESET

   return

; ************************************************

Leer_TimerKeeper_Burst

   bcf            Puerto_Timer,SCLK
   call            retardo_5u
   bcf            Puerto_Timer,IO
   bsf            Puerto_Timer,RESET

   call            retardo_5u

   movlw   b"10111111"      ; Transmito Byte de Control
   movwf   RegistroTK         
                              
   call            Transmitir_Byte

   Banco1               
   bsf            Puerto_Timer,IO      ; I/O como entrada
   Banco0

   movlw   08h
   movwf   ContadorBytesTK

   movlw   Segundo
   movwf   FSR
               
LeerOtroByte
      
   movlw   08h         ; Carga la cantidad de bit a recibir
   movwf   ContadorBitsTK

   clrf            RegistroTK      ; Limpia el Registro de recepcion

   bcf            STATUS,C      ; Limpia el bit de Acarreo
   rrf            RegistroTK,F
   bcf            Puerto_Timer,SCLK
   call            retardo_3u           ;Delay para bit de dato.   
   btfsc        Puerto_Timer,IO        ;¿El bit recibido es 0 o 1?
   bsf            RegistroTK,7        ; El bit recibido es 1
   bsf            Puerto_Timer,SCLK   
   call            retardo_3u         ;Delay para bit de dato.
   decfsz   ContadorBitsTK,F  ;¿Se recibieron todos los datos?
   goto   $-9                     ; Se recibe el siguiente bit

   movf            RegistroTK,W
   movwf   INDF
   incf            FSR,F
      
   decfsz   ContadorBytesTK,F
   goto            LeerOtroByte

   call            retardo_3u

   Banco1            
   bcf            Puerto_Timer,IO      ; Pin I/O como salida
   Banco0

   bcf            Puerto_Timer,IO
   bcf            Puerto_Timer,SCLK
   call            retardo_3u
   bcf            Puerto_Timer,RESET
      
   return
   
;**************************************************

Transmitir_Byte
   
         movlw   08h
   movwf   ContadorBitsTK

   bcf            Puerto_Timer,SCLK
   call            retardo_3u
   rrf            RegistroTK,F      ; roto al carry bit.
   btfsc            STATUS,C
   bsf            Puerto_Timer,IO      ; IO --> 1         
   btfss            STATUS,C
   bcf            Puerto_Timer,IO      ; IO --> 0
   call            retardo_3u
   bsf            Puerto_Timer,SCLK    ; Valido el dato puesto en IO
   call            retardo_3u      
   decfsz   ContadorBitsTK,F                  
   goto            $-.11

   bcf            Puerto_Timer,IO      ; IO --> 0
         return   

;***************************************************

Recibir_Byte
   
   Banco1               
   bsf            Puerto_Timer,IO      ; I/O como entrada
   Banco0

   movlw   08h         ; Carga la cantidad de bit a recibir
   movwf   ContadorBitsTK

   clrf            RegistroTK      ; Limpia el Registro de recepcion

   bcf            STATUS,C         ; Limpia el bit de Acarreo
   rrf            RegistroTK,F
   bcf            Puerto_Timer,SCLK
   call            retardo_3u         ; Delay para bit de dato.   
   btfsc            Puerto_Timer,IO      ; ¿El bit recibido es 0 o 1?
   bsf            RegistroTK,7      ; El bit recibido es 1
   bsf            Puerto_Timer,SCLK   
   call            retardo_3u          ; Delay para bit de dato.
   decfsz   ContadorBitsTK,F    ; ¿Se recibieron todos los datos?
   goto   $-9                       ; Se recibe el siguiente bit

   Banco1               
   bcf            Puerto_Timer,IO        ; I/O como salida
   Banco0
          return

;************************************************


Si alguien tiene experiecia con ese integrado le agradezco desde ya cualquier ayuda.

Saludos.

Roger. --  Carlos Paz.  Cordoba.  Argentina






 

anything