TODOPIC
Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: standard en 07 de Mayo de 2007, 15:54:42
-
Saludos
Después de revisar el protocolo I2C y el datasheet del ds1307 me encuenttro con algunas dudas ya que es mi primera experiencia con las interrupciones; les cuento:
La idea era programar un algoritmo ( en ASM; mira que me ha costado) para 16F877 que calculara a las 0:00 locales las horas de amanecer y ocultación del sol. La idea que tenía era guardar esas horas y que el reloj cada minuto le pasara la hora al micro, que comparara y que actuara. Pero me he dado cuenta que el reloj siempre actúa como esclavo, y no le puede informar cuando cambia la hora. Se puede hacer algo?
Otra duda: El micro funcina a 20MHz y el reloj a 32.768 kHz, ¿pero sólo cuando están en comunicación I2C, no?
ultima pregunta: frecuencia = 20 MHz -> periodo = 5*10^8 sg.
El stopwatch me pone 11831318 cycles, luego tiempo = 5*10^8 * 11831318 = 0.5915659 sg
pero en time me pone 2.366264 sg. ¿esto por qué es?
gracias
-
me he dado cuenta que el reloj siempre actúa como esclavo, y no le puede informar cuando cambia la hora. Se puede hacer algo?
La comunicación depende 100% del micro, se puede usar la salida de frecuencia que tiene el 1307 y configurarla para 1 Hz, con esta señal se podría generar interrupción en el programa cada 1 segundo, pero igual cada que se genere la interrupción tendrías que leer la hora.
El micro funcina a 20MHz y el reloj a 32.768 kHz, ¿pero sólo cuando están en comunicación I2C, no?
El microcontrolador funciona siempre a 1/4 de la frecuencia del cristal, el 1307 siempre esta funcionando con su cristal de 32768, ambos están trabajando aún cuando no hay comunicación.
frecuencia = 20 MHz -> periodo = 5*10^8 sg.
En esto estas equivocado, con un cristal de 20MHz la frecuencia real del micro es 20/4 = 5MHz, el periodo es el inverso de la frecuencia, o sea 1/5MHz = 0.2uS (microsegundos)
El stopwatch me pone 11831318 cycles, luego tiempo = 5*10^8 * 11831318 = 0.5915659 sg
pero en time me pone 2.366264 sg. ¿esto por qué es?
Por el mismo error que tienes calculando el periodo, si multiplicas 11831318 * 0.2uS te va a dar el tiempo.
saludos.
-
Hola standard
Otra duda: El micro funcina a 20MHz y el reloj a 32.768 kHz, ¿pero sólo cuando están en comunicación I2C, no?
En ningún momento del funcionamiento se relacionan entre sí los clocks del PIC y del DS1307. Cada cual vive en su mundo.
El DS1307, hace trabajar al RTC y escrine en la RAM del mismo a una determinada velocidad definida internamente a través del cristal de 32768Khz. y el PIC, lee esa RAM, a través del I2C a otra distinta (100Khz. ó 400Khz.)
Por ese motivo, puedes usar en el PIC la frecuencia de cristal que quieras, por el motivo que el bus I2C tiene una velocidad independiente de la frecuencia del cristal usado.
Espero se haya entendido.
Saludos
Mario
-
saludos y gracias por responder:
El tema de los relojes me ha quedado claro y aunque tardará cuatro veces lo que pensaba, no me importa demasiado.
En cuanto a la idea de interrumpir cada segundo, te refieres a esta patilla
SQW/OUT (Square Wave/ Output Driver) – Cuando está activada, el bit SQWE a 1, el pin SQW/OUT extrae una de las cuatro frecuencias de onda cuadrada (1 Hz, 4 kHz, 8 kHz, 32 kHz). El pin SQW/OUT es de tipo colector abierto necesitando una resistencia pull-up externa. SQW/OUT operará indistintamente con VCC o VBAT aplicada.
Vale, dónde la conectaría?
Si Los eventos que provocan que el bit de señalización de interrupción SSPIF se ponga a 1 (la interrupción sólo se producirá si está activada ) son:
- La condición de START.
- La condición de STOP.
- La transferencia de un byte de datos (transmitido o recibido).
- El pulso de reconocimiento ACK* a una transmisión.
- La repetición de la condición de START.
qué interrupción generaría SQW?
muchas gracias
-
En cuanto a la idea de interrumpir cada segundo, te refieres a esta patilla
SQW/OUT (Square Wave/ Output Driver)
Si, me refería a usar esa salida del DS13007 configurada para 1Hz, pero no usando la interrupción del I2C sino la interrupción externa, cada segundo el micro serían interrumpido por la señal de 1Hz y en ese momento se haría el llamado a las funciones de comunicación con el DS1307. Esto porque lo que entendí que querías es que el DS1307 le informará al micro que la hora ha cambiado sin necesidad de hacer todo el proceso de comunicación y esta sería una forma de hacerlo.
Pero no te compliques mucho con esto, si lo vez medio enredado la comunicación con el DS13007 no tiene que ser manejada por interrupción, puedes simplemente hacer el programa para que se comunique con el DS13007 cada xx tiempo.
Una pregunta: en que lenguaje estas programando?
saludos.
-
Saludos. lo que he intentado ha sido lo siguiente:
{configurar RTC}
{escribir RTC reg control}
{leer RTC hora primera vez}
{habilitar interrupción INTF}
{algoritmo interrumpido cada segundo}
las rutinas son de picmouse en http://www.todopic.com.ar/foros/index.php?topic=13748.0 (http://www.todopic.com.ar/foros/index.php?topic=13748.0)
vector interrupciones
RESET_VECTOR ORG 0x000 ; processor reset vector
nop
goto start ; go to beginning of program
INT_VECTOR ORG 0x004 ;localización del vector interrupción
BANCO_1
movwf wtemp ;guarda w en registro temporal
swapf STATUS,w ;guardar STATUS
clrf STATUS
BANCO_1
movwf stattemp
movf PCLATH,w ;guardar PCLATH
movwf pclathtemp
BANCO_0
btfss INTCON,INTF
goto fin_inte
bsf PCLATH,3
bsf PCLATH,4
call ds1307_leer
bcf PCLATH,3
bcf PCLATH,4
fin_inte bcf INTCON,INTF
BANCO_1
movf pclathtemp,w
movwf PCLATH ;recuperar PCLATH
swapf stattemp,w
movwf STATUS ;recuperar STATUS
swapf wtemp,f
swapf wtemp,w ;recuperar w
BANCO_0
retfie ;retorno de interrupción
programa principal
start bcf PCLATH,3
bcf PCLATH,4
conds1307 BANCO_0 ;configurar RTC
movlw b'00011000'
movwf TRISC ;configurar SDA y SCA
BANCO_1
movlw .49 ;(20*10^6/4*10^5)-1 =49
movwf SSPADD
movlw b'10000000'
movwf SSPSTAT
movlw b'00101000'
BANCO_0
movwf SSPCON
movlw 0x00
movwf TRISB ;INT como entrada
BANCO_1
movlw b'00010000'
movwf datoi2c ;dato para registro control RTC
movlw 0x07
movwf diri2c ;dirección del registo control RTC
bsf PCLATH,3
bsf PCLATH,4
call escri_ds ;escribir en RTC
call leer_ds ;hacer primera lectura RTC
bsf INTCON,GIE ;activa las interrupciones
bsf INTCON,INTF ;activa interrupción externa
bsf PCLATH,3
bcf PCLATH,4
{resto algoritmo}
rutinas para leer y escribir(en página 3)
ds1307_leer BANCO_1
clrf diri2c ;dirección 0
call leer_ds
movf datoi2c,w
BANCO_0
movwf segundo ;guardar segundo
movlw 0x01 ;dirección 1
BANCO_1
movwf diri2c
call leer_ds
movf datoi2c,w
BANCO_0
movwf minuto ;guardar minuto
movlw 0x02 ;dirección 2
BANCO_1
movwf diri2c
call leer_ds
movf datoi2c,w
BANCO_0
movwf hora ;guardar hora
movlw 0x03 ;dirección 3
BANCO_1
movwf diri2c
call leer_ds
movf datoi2c,w
BANCO_0
movwf segundo ;guardar en segundo, no es útil para mí
movlw 0x04 ;dirección 4
BANCO_1
movwf diri2c
call leer_ds
movf datoi2c,w
BANCO_0
movwf dia ;guardar dia
movlw 0x05 ;dirección 5
BANCO_1
movwf diri2c
call leer_ds
movf datoi2c,w
BANCO_0
movwf mes ;guardar mes
movlw 0x06 ;dirección 6
BANCO_1
movwf diri2c
call leer_ds
movf datoi2c,w
BANCO_0
movwf año ;guardar año
return
leer_ds BANCO_1 ;enviar secuencia de START
bsf SSPCON2,SEN ;bit SEN comienza secuencia
btfsc SSPCON2,SEN
goto $-1 ;permiso para escribir en DS1307
BANCO_0
movlw 0xD0 ;Carga el dato a enviar
movwf SSPBUF ;dirección esclavo + 0(bit escritura)
BANCO_1
btfsc SSPSTAT,R_W ;si es 0, se ha completado transmisión
goto $-1
btfsc SSPCON2,ACKSTAT ;Solo continua si llaga el ACK
goto stopI2C ;1=no reconocido, reinicia comunicación
movf diri2c,w ;dirección a W
BANCO_0
movwf SSPBUF ;dirección donde se va a leer
BANCO_1
btfsc SSPSTAT,R_W ;si es 0, se ha completado transmisión
goto $-1
btfsc SSPCON2,ACKSTAT ;Solo continua si llaga el ACK
goto stopI2C ;1=no reconocido, reinicia comunicación
bsf SSPCON2,RSEN ;bit RSEN para reiniciar la secuencia
btfsc SSPCON2,RSEN
goto $-1 ;Permiso para comunicación
BANCO_0
movlw 0xD1
movwf SSPBUF ;esclavo + 1(bit lectura)
BANCO_1
btfsc SSPSTAT,R_W ;si es 0, se ha completado transmisión
goto $-1
btfsc SSPCON2,ACKSTAT ;Solo continua si llaga el ACK
goto stopI2C ;1=no reconocido, reinicia comunicación
bsf SSPCON2,RCEN ;RCEN a 1 para recibir datos
btfsc SSPCON2,RCEN ;si se ha recibidotodo el byte sigue
goto $-1
BANCO_0
movf SSPBUF,w ;dato a W
BANCO_1
movwf datoi2c ;guardar dato en datoi2c
bsf SSPCON2,ACKDT ;Activa el NACK
bsf SSPCON2,ACKEN ;Envía el NACK
btfsc SSPCON2,ACKEN
goto $-1 ;continua cuando finaliza envío
stopI2C bsf SSPCON2,PEN ;condición STOP
btfsc SSPCON2,PEN
goto $-1 ;se asegura que haya acabado
BANCO_0
return
escri_ds BANCO_1 ;enviar secuencia de START
bsf SSPCON2,SEN ;bit SEN comienza secuencia
btfsc SSPCON2,SEN
goto $-1 ;permiso para escribir en DS1307
BANCO_0
movlw 0xD0 ;Carga el dato a enviar
movwf SSPBUF ;dirección esclavo + 0(bit escritura)
BANCO_1
btfsc SSPSTAT,R_W ;si es 0, se ha completado transmisión
goto $-1
btfsc SSPCON2,ACKSTAT ;Solo continua si llaga el ACK
goto stopI2C2 ;1=no reconocido, reinicia comunicación
movf diri2c,w ;dirección a W
BANCO_0
movwf SSPBUF ;dirección donde se va a escribir
BANCO_1
btfsc SSPSTAT,R_W ;si es 0, se ha completado transmisión
goto $-1
btfsc SSPCON2,ACKSTAT ;Solo continua si llaga el ACK
goto stopI2C2 ;1=no reconocido,reinicia comunicación
movf datoi2c,w
BANCO_0
movwf SSPBUF ;pasar dato a SSPBUF
BANCO_1
btfsc SSPSTAT,R_W ;si es 0, se ha completado transmisión
goto $-1
btfsc SSPCON2,ACKSTAT ;Solo continua si llaga el ACK
goto stopI2C2 ;1=no reconocido,reinicia comunicación
stopI2C2 BANCO_1
bcf PIE1,SSPIE
bsf SSPCON2,PEN ;condición STOP
btfsc SSPCON2,PEN
goto $-1 ;se asegura que haya acabado
BANCO_0
return
Dudas:En la fórmula de SSPADD que hay que poner en Fosc: 20MHz o 4Mhz?
por qué la finalizar la rutina de escribir si que tiene en cuenta el bit PIE1 y en la de leer no?
En el datasheet del reloj, para leer no pone nada de escribir una dirección, sin embargo después de direccionar al esclavo la rutina sí lo hace. Supogo que funcionará, no?
He descargado proteus lite 6.9 Esta conexión se podría simular?
Gracias
-
hola, hola:
una pregunta: como calculo el valor del SSPADD? no me queda claro...
-
Baudios = FOSC / (4*(SSPADD+1))
SSPADD = (FOSC /4*Baudios)-1
(20*10^6/4*10^5)-1 =49
FOSC=20*10^6 o 5*10^6 (no estoy seguro)
Baudios = 10 Khz
-
muchísimas gracias...