Buscador
YoReparo.com La Web 

Regístrate gratis para participar de los foros, o si ya estás registrado haz login.

problema con ds 1307

comentario del autor Lun Dic 10, 2007 7:45 pm
   
Hola a todos.. tengo un gran problema con un montaje que estoy haciendo. No logro poner a funcionar un reloj Ds 1307 con un pic 16f877. Abajo escribo el codigo que utilizo para ello. Está basado en una nota de aplicacion para uso de protocolo i2c de microchip.
Solo hago algunas variaciones para el baud rate pues el pic usa un cristal de 4 Mhz y no de 10 como en la nota de aplicacion (AN976: I2c y EEprom).
Al final de todo solo veo en el display (lcd 2x16) ????????
Si alguien me puede ayudar les agradeceria en el alma!!

a continuacion el codigo

Nota: los registros y pines que se incluyen corresponden a
una aplicacion que si me funciona y un fichero con las subrutinas del LCD

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
;
; RELOJ DS 1307, CRISTAL 32.768 KHz
;
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LIST P=16F877


__CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF


;---------------------------------------------------
; Port C pin descriptions
; SCL bit = 3 ;SALIDA RELOJ I2C
; SDA bit = 4 ;SALIDA DATOS I2C
; Tx bit = 6 ;SALIDA DATOS RS232
; Rx bit = 7 ;ENTRADA DATOS RS232
;----------------------------------------------------
; 4MHz crystal is being used
;
;*******************RAM register definitions**********************
datai equ 20h ; Data input byte buffer
datao equ 21h ; Data output byte buffer
bytecount equ 22h ; Counter for byte loops
pollcnt equ 23h ; Counter for polling loops
loops equ 24h ; Delay loop counter
loops2 equ 25h ; Delay loop counter
LCD_TEMP equ 26h ; Posiciones auxiliares en el banco 0
DELAY equ 27h ; para temporizar
X_DELAY equ 28h ; para temporizar
AUX equ 29h ; para guardar temporalmente
DIRH equ 2ah
DIRL equ 2bh
CounterA equ 2ch
CounterB equ 2dh
CounterC equ 2eh
XmtReg equ 2fh
I2C_Banderas equ 30h
Segundo equ 31h
Minuto equ 32h
Hora equ 33h
DiaSemana equ 34h
Dia equ 35h
Mes equ 36h
Anho equ 37h
W_TEMP equ 38h ;almacén temporal para el registro W
ST_TEMP equ 39h ;almacén temporal para el registro STATUS
PCLATH_TEMP equ 3ah ;almacén temporal del registro PCLATH
BCD0 equ 3bh ;(DECENAS:UNIDADES)
BCD1 equ 3ch ;(MILLARES:CENTENAS)
BCD2 equ 3dh ;(0:DECENAS DE MIL)
FACTOR1 equ 3eh ;Uno de los factores del producto
FACTOR2 equ 3fh ;Otro de los factores del subprograma producto
SUMA_ALTO equ 40h ;Posición que almacena la parte alta de FACTOR1 desplazado a la izq.
SUMA_BAJO equ 41h ;almacenará la parte baja de FACTOR1 desplazado a la izquierda
CONTADOR equ 42h ;Para el subprograma de multiplicación, cuenta sumas parciales
BIN_ALTO equ 43h ;Parte alta del valor medido en binario
BIN_BAJO equ 44h ;Parte baja del periodo en binario
TMP equ 45h ;otra variable auxiliar



;*******************Macro definitions*****************************

WRITE_ds equ b'11010000' ; Control byte for write operations
READ_ds equ b'11010001' ; Control byte for read operations



;*******************Include file**********************************
include "p16f877.inc" ; Include file for a PIC16F877
errorlevel -302 ; Suppress message 302 from list file
;**********************************************************

LCD_DATA EQU PORTD ;DATOS se conecta a PORTD
LCD_DATA_TRIS EQU TRISD ;
LCD_CTRL EQU PORTE ;CONTROL se conecta a PORTE
LCD_CTRL_TRIS EQU TRISE ;

LCD_LINE0 EQU 0x000 ;dirección comienzo línea superior DDRAM del LCD
LCD_LINE1 EQU 0x040 ;dirección comienzo línea inferior DDRAM del LCD

; También se deben definir los Bits de control:


LCD_E EQU 2 ; Enable será el bit 1 del PORTE
LCD_RW EQU 1 ; Read/Write bit 2 del PORTE
LCD_RS EQU 0 ; RS será el bit 3 del PORTE

; En STATUS

CARRY equ 0
CERO equ 2

;*****************************************************************
org 0x000 ; Set the reset vector
goto start ; Go to the beginning of main
include "volt2.ASM" ; Solo contiene subrutinas para el LCD
;*******************Begin Main Program****************************

;---------------------------------------------------------------


start
call Init ; Initialize device

;- CARGA INICIAL DEL DS1307------;
movlw 00h ;
movwf Segundo ;Segundos inician en 00
movlw 42h ;
movwf Minuto ;Minutos inician
movlw 08h
movwf Hora ;Hora inicia en 08
movlw 02h ;
movwf DiaSemana ;Dia 2 equivale a lunes
movlw 03h ;
movwf Dia ;Dia 03
movlw 12h
movwf Mes ; Mes 12 equivale a dic.
movlw 07h
movwf Anho ; Año 2007
clrf PORTC
; goto display
;-----------------------------------------------------------------------
call BSTART ;
movlw WRITE_ds ; Pbra control modo Escritura
movwf datao
call TX
movlw 0 ; Se indica la direcc. 0h.
movwf datao
call TX
movlw b'00000000' ; activa bit7 del reg 00 (enable reloj).
movwf datao
call TX
call BSTOP ; Termina de enviar datos.

bsf PORTC,5
call PDelay

call BSTART ;
movlw WRITE_ds ; Pbra control modo Escritura
movwf datao
call TX
movlw b'00000111' ; direccc. 07h.
movwf datao
call TX ; ctl de la señal cuadrada
movlw b'00010000' ; output pin 7. señal cuadrada de 1 Hz
movwf datao
call TX
call BSTOP ; Termina de enviar datos.

;------------------------------------------------------
;-inicializando el reloj ds1307-------------------------;

call BSTART ;
movlw WRITE_ds ; Pbra control modo Escritura
movwf datao
call TX ;
movlw 0x00 ; direccion inicial 00
movwf datao
call TX
movf Segundo,0 ; Pasa los segundos de la memoria del PIC16 al DS1307.
movwf datao
call TX
movf Minuto,0 ;
movwf datao
call TX
movf Hora,0
movwf datao
call TX
movf DiaSemana,0
movwf datao
call TX
movf Dia,0
movwf datao
call TX
movf Mes,0
movwf datao
call TX
movf Anho,0
movwf datao
call TX
call BSTOP ; Termina de enviar datos.
call PDelay

;--------------------------------------------------------------------------------
;----------------------------------------------------------
; lee y actualiza el reloj
;----------------------------------------------------------
RTC_LEE
call BSTART ;
movlw WRITE_ds ; modo escritura
call TX
movlw 0x00 ; a los segundos.
movwf datao
call TX
call BRESTART

movlw READ_ds ; Pbra control modo Lectura
movwf datao
call TX

call RX ; Lee los segundos.
movf datai,0
movwf Segundo ; Lo carga en el registro correspondiente.

call RX ;
movf datai,0 ;
movwf Minuto ;

call RX ;
movf datai,0
movwf Hora

call RX
movf datai,0
movwf DiaSemana

call RX
movf datai,0
movwf Dia

call RX
movf datai,0
movwf Mes
;------------------------------------------------------------
; GENERA UN NO ACK INDICANDO QUE ES EL ULTIMO BYTE A LEER
;------------------------------------------------------------
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKDT ; Select to send NO ACK bit genera un NO ACK(Generate NO ACK)
bcf STATUS,RP0 ; Select Bank 00

call RX ;Recibe el ultimo byte
movf datai,0
movwf Anho
call BSTOP ; Termina de leer datos.

bsf PORTC,5
;**********************************************************
display

movlw LCD_LINE1+1 ;Cargo en W la dirección de la línea 0
call LCDSDDA ;y coloco el puntero de la DDRAM del LCD ahí

movlw Segundo
movwf FSR
movlw 7
movwf CONTADOR
show
movf INDF,0 ;
andlw 0xF0
movwf AUX ;
swapf AUX,0 ;
addlw A'0' ;
call LCDPUTCHAR_4_2 ;
movf INDF,0 ;
andlw 0x0F
addlw A'0' ;
call LCDPUTCHAR_4_2 ;
incf FSR,1
decfsz CONTADOR,1
goto show



bcf PORTC,5

goto RTC_LEE


nop
goto $-1 ; Loop here forever

;_----------------------------------------------


;*******************Initialization subroutine*********************
; This routine initializes the MSSP module
; for I2C Master mode, with a 100 kHz clock.
;*****************************************************************
Init
bcf STATUS,RP1 ; Select Bank 01
bsf STATUS,RP0

movlw b'00001110' ;PORTA con RA0 analógica, resto como digitales
movwf ADCON1 ;referencia de 5V y resultado justificado
;a la izquierda: ADRESH_ADRESL
clrf LCD_DATA_TRIS ;Defino PORTD de salidas
movlw 0 ; b'11110001' En el PORTA las 3 salidas
movwf LCD_CTRL_TRIS ;para E, RS y R/W

movlw 0xCF ; Predivisor de 128 asociado al Watchdog ;///////// ;
movwf OPTION_REG

movlw b'10011111'
movwf TRISC ; Set PORTC to all inputs
clrf SSPSTAT ; Disable SMBus inputs
bsf SSPSTAT,SMP ; Disable slew rate control
movlw 9 ; Load 9 into WREG ((fosc/100khz)/4)-1 = 9
movwf SSPADD ; Setup 100 kHz I2C clock
clrf SSPCON2 ; Clear control bits
movlw b'00100100' ;Configuracion USART
movwf TXSTA ;y activacion de transmision
movlw .25 ;9600 baudios
movwf SPBRG

bcf STATUS,RP0 ; Select Bank 00
movlw b'11000001' ;Configuramos entrada por canal analógico 0 (RA0)
movwf ADCON0 ;y reloj RC interno de conversión TAD=4us típico
movlw b'00101000'
movwf SSPCON ; Enable SSP, select I2C Master mode
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bcf PIR2,BCLIF ; Clear Bit Collision flag
bsf RCSTA,SPEN ;se activa la USART
bcf PIR1,ADIF ;Pongo a 0 el flag de fin de conversión
call LCD_RST_P2P ;Reset software del módulo LCD
call LCDINIT_4 ;Inicializamos el LCD para definir funcionamiento
;interface de 4 bits y 2 líneas visibles
call LCDCLEAR ;Limpiamos pantalla al principio

retlw 0

;*******************Start bit subroutine**************************
; This routine generates a Start condition
; (high-to-low transition of SDA while SCL
; is still high.
;*****************************************************************
BSTART
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,SEN ; Generate Start condition
bcf STATUS,RP0 ; Select Bank 00
bstart_wait
btfss PIR1,SSPIF ; Check if operation completed
goto bstart_wait ; If not, keep checking

retlw 0

;*******************Restart bit subroutine**************************
; This routine generates a Repeated Start
; condition (high-to-low transition of SDA
; while SCL is still high.
;*****************************************************************
BRESTART
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,RSEN ; Generate Restart condition
bcf STATUS,RP0 ; Select Bank 00
brestart_wait
btfss PIR1,SSPIF ; Check if operation completed
goto brestart_wait ; If not, keep checking

retlw 0

;*******************Stop bit subroutine***************************
; This routine generates a Stop condition
; (low-to-high transition of SDA while SCL
; is still high.
;*****************************************************************
BSTOP
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,PEN ; Generate Stop condition
bcf STATUS,RP0 ; Select Bank 00
bstop_wait
btfss PIR1,SSPIF ; Check if operation completed
goto bstop_wait ; If not, keep checking

retlw 0

;*******************Data transmit subroutine**********************
; This routine transmits the byte of data
; stored in 'datao' to the serial EEPROM
; device. Instructions are also in place
; to check for an ACK bit, if desired.
; Just replace the 'goto' instruction,
; or create an 'ackfailed' label, to provide
; the functionality.
;*****************************************************************
TX
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
movf datao,W ; Copy datao to WREG
movwf SSPBUF ; Write byte out to device
tx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto tx_wait ; If not, keep checking
; bsf STATUS,RP0 ; Select Bank 01
; btfsc SSPCON2,ACKSTAT ; Check if ACK bit was received
; goto ackfailed ; This executes if no ACK received


retlw 0

;*******************Data receive subroutine***********************
; This routine reads in one byte of data from
; the serial EEPROM device, and stores it in
; 'datai'. It then responds with either an
; ACK or a NO ACK bit, depending on the value
; of 'ACKDT' in 'SSPCON2'.
;*****************************************************************
RX
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,RCEN ; Initiate reception of byte
bcf STATUS,RP0 ; Select Bank 00
rx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto rx_wait ; If not, keep checking


movf SSPBUF,W ; Copy byte to WREG
movwf datai ; Copy WREG to datai
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKEN ; Generate ACK/NO ACK bit
bcf STATUS,RP0 ; Select Bank 00
rx_wait2
btfss PIR1,SSPIF ; Check if operation completed
goto rx_wait2 ; If not, keep checking
retlw 0

;PIC Time Delay = 1,0000020 s with Osc = 4 MHz
PDelay
;return
movlw D'6' ;"6"
movwf CounterC
movlw D'24' ;D'24'
movwf CounterB
movlw D'168' ;D'168'
movwf CounterA
loop
decfsz CounterA,1
goto loop
decfsz CounterB,1
goto loop
decfsz CounterC,1
goto loop
return



END

juankah72

Reputación

sin valorar Mie Dic 12, 2007 6:54 pm
   
Yo lo tengo funcionando en pic basic pro en un proyecto bastante avanzado, use un 16f877A y un DS1307, no se si te sirve pero aca dejo un ejemplo que pone en hora el reloj si este no estaba en funcionamiento y te lo muestra en la patalla:
El reloj devuelve los valores en BCD y hay que transformarlos para mostrarlos en la pantalla:


Programa:


adcon1 = 7 'puerto A y puerto E digital'
define osc 4
define lcd_dreg portb 'data port'
define lcd_dbit 4 'start data bit 0-4'
define lcd_rsreg portb 'RS port rsgister select'
define lcd_rsbit 3 'RS bit'
define lcd_ereg portb 'Enable port'
define lcd_ebit 2 'Enable bit'
define lcd_bits 4 'Bus size 4-8'
define lcd_lines 2 'numero Lineas'
input porta
param var byte
param=1
f var byte
temp1 var byte
temp2 var byte
'Defincion reloj ds1307'
rtcseg var byte
rtcmin var byte
rtchor var byte
rtcdia var byte
rtcmes var byte
rtcano var byte
rtcsem var byte
rtccon var byte
rtc_sda var portb.1
rtc_scl var portb.0
'hasta aca ds1307 '
'Inicializa la hora 12:00:00 1-1-2000'
'Escribir segundos,minutos,horas,dia semana,dias,mes,año,control'
'i2cwrite rtc_sda,rtc_scl,$d0,$00,[$00,$00,$12,$2,$1,$1,$0,$90]'

loop:
if porta.0=0 then
param=param+1
if param>5 then param=1
pause 100
endif
if porta.1=0 or porta.2=0 then
select case param
case 1
temp1=rtchor
gosub bcdabin
rtchor=temp2
if porta.1=0 then
if rtchor>0 then rtchor=rtchor-1 'hora'
else
if rtchor<23 then rtchor=rtchor+1 'hora'
endif
temp1=rtchor
gosub binabcd
rtchor=temp2
case 2
temp1=rtcmin
gosub bcdabin
rtcmin=temp2
if porta.1=0 then
if rtcmin>0 then rtcmin=rtcmin-1 'minutos'
else
if rtcmin<59 then rtcmin=rtcmin+1 'minutos'
endif
temp1=rtcmin
gosub binabcd
rtcmin=temp2
case 3
temp1=rtcdia
gosub bcdabin
rtcdia=temp2
if porta.1=0 then
if rtcdia>1 then rtcdia=rtcdia-1 'dia'
else
if rtcdia<31 then rtcdia=rtcdia+1 'dia'
endif
temp1=rtcdia
gosub binabcd
rtcdia=temp2
case 4
temp1=rtcmes
gosub bcdabin
rtcmes=temp2
if porta.1=0 then
if rtcmes>1 then rtcmes=rtcmes-1 'mes'
else
if rtcmes<12 then rtcmes=rtcmes+1 'mes'
endif
temp1=rtcmes
gosub binabcd
rtcmes=temp2
case 5
temp1=rtcano
gosub bcdabin
rtcano=temp2
if porta.1=0 then
if rtcano>0 then rtcano=rtcano-1 'año'
else
if rtcano<99 then rtcano=rtcano+1 'año'
endif
temp1=rtcano
gosub binabcd
rtcano=temp2
end select
i2cwrite rtc_sda,rtc_scl,$d0,$00,[$00,rtcmin,rtchor,$2,rtcdia,rtcmes,rtcano,$90]
endif
i2cread rtc_sda,rtc_scl,$d1,$00,[rtcseg,rtcmin,rtchor,rtcsem,rtcdia,rtcmes,rtcano,rtccon]
lcdout $fe,1
lcdout "Hora:",hex2 rtchor,":",hex2 rtcmin,":",hex2 rtcseg," ",#param
lcdout $fe,$c0
lcdout "Fecha:",hex2 rtcdia,"-",hex2 rtcmes,"-20",hex2 rtcano
pause 100
goto loop

bcdabin:
temp2=((temp1>>4)&$0f)*10+(temp1&$0f)
return

binabcd:
temp2=temp1 dig 1
temp2=temp2<<4
temp2=temp2+temp1 dig 0
return







MoonBlack

moonblack

Reputación

comentario del autor Mie Dic 19, 2007 3:26 pm
   
Gracias por tu colaboración moonblack. La cuestion es que apenas he trabajado con ASM y poco entiendo C u otro lenguaje.Sin embargo, analizando un poco tu código veo que las instrucciones para el ds1307 no difieren en su escencia al código que yo tengo, pues las secuencias de inicializacion, escritura y lecturas son basicamente iguales...
Veré como puedo seguir revisando y comparando a ver si encuentro errores en mi código.

Gracias nuevamente....

juankah72

Reputación

sin valorar Mie Dic 19, 2007 4:43 pm
   
Efectivamente, sea el lenguaje que sea, los valores de parametros que hay que pasarle son los mismos, espero te sirva de algo.Suerte.


Moonblack

moonblack

Reputación



Hacer una pregunta

Reglamento / P+F

Foros

Miembros / Expertos