No se si esta es la forma mas apropiada para publicar, moderadores... a su dispocision!
Este es un codigo para ds1307 basado en un ejemplo que esta colgado en el foro. (genialmente descrito y comprensible) jamas hubiera entendido el funcionamiento i2c 1307 si no fuera por este codigo.
dogflu66 un grosso, estoy aprendiendo mucho de tus aportes. Gracias!!!!!
dogflu66 es el autor y yo me permiti hacer unas reformas optimizando el codigo en las rutinas de "antirebote" de los pines de ajuste de parametros del reloj.
'********************************** PIC Entrenadora BASIC (PicEBasic)******************************
''MICRO: PIC16f88A
'FECHA/AUTOR: 11/10 - By COS (intervencion by GATRUCA)
'Version 2010?¿
'DESCRIPCION: Muestra en el display la fecha y la hora en formato de 24 horas
'***************************************************************************************************
Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 4
Define LCD_RSREG = PORTD
Define LCD_RSBIT = 0
Define LCD_EREG = PORTD
Define LCD_EBIT = 2
Define LCD_RWREG = PORTD
Define LCD_RWBIT = 1
Define LCD_COMMANDUS = 2000
Define LCD_DATAUS = 50
Define LCD_INITMS = 39
Lcdinit
Symbol sda = PORTC.3 'asignamos nombre al pin que hara de SDA del puerto I2C
Symbol scl = PORTC.4 'asignamos nombre al pin que hara de SCL del puerto I2C
Symbol s1 = PORTD.3 'se asigna nombre a el pin que aumenta el valor
Symbol fc = PORTD.5 'tecla funcion ingresa a programa u cambia parametro
Dim aux_4h As Byte 'contendra el nibble alto del dato leido por el I2C
Dim aux_4l As Byte 'contendra el nibble bajo del dato leido por el I2C
Dim i As Byte 'variable indice
Dim reg(7) As Byte 'contendra los valores finales de fecha y hora en el sistema decimal
Dim flash_1 As Bit 'controla el parpadeo de los digitos del lcd, activo a 1
Dim dato As Byte 'indica la direccion del RTC a cambiar de valor
Dim flag_1 As Bit 'activa la rutina de ajuste del reloj, activo a 1
Dim aux_ajuste As Byte 'variable auxiliar para la rutina de ajuste
dato = 7 'fuera de ajuste o modo normal de trabajo del reloj, de 0 a 6 modo ajuste
flash_1 = 0 'parpadeo off por defecto
flag_1 = 0 'ingreso a programacion reloj off por defecto
WaitMs 500 'espera 0.5
Lcdcmdout LcdClear
main:
If fc = 1 And flag_1 = 0 Then 'modo ajuste
flag_1 = 1 'activa rutina de ajuste
Endif
If flag_1 = 1 Then Gosub ajuste_reloj 'saltamos a la rutina de ajuste
Gosub lee_hora 'lee la fecha y hora del reloj
Gosub print_lcd 'actualiza los datos del reloj en el display
WaitMs 100
Goto main
End
ajuste_reloj: 'rutina de ajuste del reloj
If fc = 1 Then 'detecta tecla fc
While fc = 1 'eliminacion de rebotes (se queda haciendo nada mientras fc = 1
WaitUs 1
Wend
dato = dato + 1 'seleciona el dato a ser modificado
If dato > 7 Then dato = 0 '8 posiciones de estadio
If dato > 6 Then flag_1 = 0 'termina programacion reloj
Endif
While s1 = 1 'deteca tecla S1 y eliminacion de rebotes
If dato < 7 Then 'limita la direcciones de trabajo del reloj
Gosub lee_hora 'lee los datos de los registros del RTC y los pasa a decimal, elimina los bit de control
aux_ajuste = reg(dato) 'hace una imagen del valor del registro a modificar
aux_ajuste = aux_ajuste + 1 'incrementa el dato a modificar que fue seleccionado
If dato = 2 And aux_ajuste > 23 Then aux_ajuste = 0 'acota horas
If dato = 0 Or dato = 1 Then 'acota segundos y minutos
If aux_ajuste > 59 Then aux_ajuste = 0
Endif
If dato = 3 And aux_ajuste > 7 Then aux_ajuste = 1 'acota el dia de la semana
If dato = 4 And aux_ajuste > 31 Then aux_ajuste = 1 'acota el dia del mes
If dato = 5 And aux_ajuste > 12 Then aux_ajuste = 1 'acota el mes
If dato = 6 And aux_ajuste > 99 Then aux_ajuste = 1 'acota el año, año maximo 2030
If aux_ajuste > 49 And aux_ajuste < 60 Then 'Decimal a BCD
aux_ajuste = aux_ajuste - 50
aux_ajuste.4 = 1
aux_ajuste.6 = 1
Endif
If aux_ajuste > 39 And aux_ajuste < 50 Then 'Decimal a BCD
aux_ajuste = aux_ajuste - 40
aux_ajuste.6 = 1
Endif
If aux_ajuste > 29 And aux_ajuste < 40 Then 'Decimal a BCD
aux_ajuste = aux_ajuste - 30
aux_ajuste.4 = 1
aux_ajuste.5 = 1
Endif
If aux_ajuste > 19 And aux_ajuste < 30 Then 'Decimal a BCD
aux_ajuste = aux_ajuste - 20
aux_ajuste.5 = 1
Endif
If aux_ajuste > 9 And aux_ajuste < 20 Then 'Decimal a BCD
aux_ajuste = aux_ajuste - 10
aux_ajuste.4 = 1
Endif
If aux_ajuste < 10 Then aux_ajuste = aux_ajuste 'Decimal a BCD
If dato = 0 Then aux_ajuste.7 = 0 'restaura el bit de configracion, activa el oscilador del reloj
If dato = 2 Then aux_ajuste.7 = 0 'restaura el bit, no lo utiliza el RTC
If dato = 2 Then aux_ajuste.6 = 0 'restaura el bit de configuracion, reloj 24h
I2CWrite sda, scl, 0xd0, dato, aux_ajuste 'actualiza el dato ya modificado
Endif
Gosub print_lcd 'permite ver el valor del parametro cuando estamos dentro del bucle
Gosub parpadeo 'ver el pametro parpadeando cuando dentro del bucle
WaitMs 50
'el tiempo de espera puede acelerar o retardar
'la repeticion de incremento de los parametros
Wend
Gosub parpadeo 'ver el pametro parpadeando cuando estamos fuera del bucle
Return
parpadeo:
If dato >= 0 And dato < 7 And flag_1 = 1 Then
If flash_1 = 1 Then 'selecciona si el dato a modificar es visible o no
flash_1 = 0 'dato es visible
Else
flash_1 = 1 'dato no es visible
Endif
Endif
Return
lee_hora: 'lee la hora del RTC en formato BCD y la pasa a decimal
i = 0 'variable indice, asigna los datos de forma ordenada, leidos del RTC
While i <= 6 'se repite el codigo comprendido entre while y wend, mientras i sea menor o igual a 6
I2CRead sda, scl, 0xd0, i, reg(i) 'lectura de la direccion de memoria indicada del RTC, formato BCD
aux_4l = reg(i) And %00001111 'eliminamos los bit de configuracion del RTC y dejamos solo el nibble bajo
If i = 0 Then aux_4h = reg(i) And %01110000 'segundos, borrado de bit configuracion y almacena nibble alto
If i = 1 Then aux_4h = reg(i) And %01110000 'minutos, almacena nibble alto
If i = 2 Then aux_4h = reg(i) And %00110000 'horas, borrado de bit configuracion y almacena nibble alto
If i = 3 Then aux_4h = reg(i) And %00000000 'dia_semana, almacena nibble alto
If i = 4 Then aux_4h = reg(i) And %00110000 'dia_mes, almacena nibble alto
If i = 5 Then aux_4h = reg(i) And %00010000 'mes, almacena el nibble alto
If i = 6 Then aux_4h = reg(i) And %11110000 'año, almacena el nibble alto
aux_4h = ShiftRight(aux_4h, 4) 'convierte el nibble alto en bajo
reg(i) = (aux_4h * 10) + aux_4l 'fusiona los nibbles alto y bajo en una sola variable en formato decimal
i = i + 1 'incrementa la variable indice con cada repeticion del bucle While/Wend
Wend 'fin del bucle y salta a While
Return
print_lcd: 'rutina de escritura en el lcd
Lcdcmdout LcdLine1Home 'cursor del lcd a la izquierda en la linea 1
Lcdout " " ' espacios para centrar la hora
If dato = 2 And flash_1 = 1 Then 'control final del parpadeo de los digitos de la hora
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(2) < 10 Then Lcdout "0" 'si horas es inferior a 10 escribe el cero delante
Lcdout #reg(2) 'escribe la hora
Endif
Lcdout ":" 'escribe el separador
If dato = 1 And flash_1 = 1 Then 'control final del parpadeo de los digitos de los minutos
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(1) < 10 Then Lcdout "0" 'si minutos es inferior a 10 escribe el cero delante
Lcdout #reg(1) 'escribe los minutos
Endif
Lcdout ":" 'escribe el separador
If dato = 0 And flash_1 = 1 Then 'control final del parpadeo de los digitos de los segundos
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(0) < 10 Then Lcdout "0" 'si segundos es inferior a 10 escribe el cero delante
Lcdout #reg(0), " " 'escribe los segundos
Endif
Lcdcmdout LcdLine2Home 'cursor del lcd a la izquierda en la linea 2
If dato = 3 And flash_1 = 1 Then 'control final del parpadeo de los digitos del dia semana
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(3) = 1 Then Lcdout "Dom." 'asigna el literal al dia de la semana
If reg(3) = 2 Then Lcdout "Lun."
If reg(3) = 3 Then Lcdout "Mar."
If reg(3) = 4 Then Lcdout "Mie."
If reg(3) = 5 Then Lcdout "Jue."
If reg(3) = 6 Then Lcdout "Vie."
If reg(3) = 7 Then Lcdout "Sab."
Endif
Lcdout " " 'escribe separador para justificar la fecha
If dato = 4 And flash_1 = 1 Then 'control final del parpadeo de los digitos del dia del mes
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(4) < 10 Then Lcdout "0" 'si dia del mes es inferior a 10 escribe cero
Lcdout #reg(4) 'escribe el dia del mes
Endif
Lcdout "/" 'escribe el separador
If dato = 5 And flash_1 = 1 Then 'control final del parpadeo de los digitos de los meses
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(5) < 10 Then Lcdout "0" 'si mes es inferior a 10 escribe cero
Lcdout #reg(5) 'escribe el mes
Endif
Lcdout "/20" 'separador y los dos primeros digitos del año de 4 digitos
If dato = 6 And flash_1 = 1 Then 'control final del parpadeo de los digitos de los años
Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
Else
If reg(6) < 10 Then Lcdout "0" 'si año es inferior a 10 escribe primero el cero
Lcdout #reg(6) 'escribe el año
Endif
Return
Utilizar while wend como interrupcion es una buena opcion de antirebote para cualquier menu y ajuste de parametros.