Autor Tema: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)  (Leído 44182 veces)

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

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #30 en: 24 de Noviembre de 2008, 21:06:13 »
hola
no consigo hacer funcionar el PIC16F877A con el DS1307
los fuentes son:

Código: QBasic/QuickBASIC
  1. 'ejemplo tomado del amigo xocas, modificado (gracias amigo)
  2. 'Pic 16f877A
  3.  
  4. Define CONF_WORD = 0x3f71
  5. Define CLOCK_FREQUENCY = 4
  6. Define LCD_LINES = 4
  7. Define LCD_CHARS = 20
  8.  
  9. '-------------------------------------Puertos del LCD-----------------------------------------------
  10. Define LCD_BITS = 4  'indicamos que el bus de datos del lcd sera de 8bit
  11. Define LCD_DREG = PORTB  'el bus de datos sera el puerto B
  12. Define LCD_DBIT = 4  '(0/4) indiferente en bus de 8 bits
  13. Define LCD_RSREG = PORTB  'el bit RS está en el puerto A
  14. Define LCD_RSBIT = 1  'se usa RA0 RS
  15. Define LCD_EREG = PORTB  'el bit E está en el puerto A
  16. Define LCD_EBIT = 2  'se usa RA1 para E
  17. Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  18. Define LCD_DATAUS = 100  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  19. Define LCD_INITMS = 100  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  20.  
  21. Lcdinit
  22.  
  23. '-----------------------------------Puerto I2C-----------------------------------------------------
  24. Symbol sda = PORTC.4  'asignamos nombre al pin que hara de SDA del puerto I2C
  25. Symbol scl = PORTC.3  'asignamos nombre al pin que hara de SCL del puerto I2C
  26. '***********************************DEFINICION DE VARIABLES**************************************
  27.  
  28. '--------------------------------------Variables Programa----------------------------------------
  29. DIM addr(7) AS Byte
  30. DIM DATA AS Byte
  31. DIM escribe AS Byte
  32.  
  33. DIM sec AS Byte
  34. DIM min AS Byte
  35. DIM hour AS Byte
  36. DIM day AS Byte
  37. DIM daym AS Byte
  38. DIM month AS Byte
  39. DIM year AS Byte
  40. DIM d_hi AS Byte
  41. DIM d_lo AS Byte
  42.  
  43. WaitMs 1000
  44.  
  45. 'bucle que escribe los datos iniciales en DS1307
  46. FOR addr = 0 TO 6
  47. escribe = LookUp(0x00, 0x15, 0x16, 0x01, 0x22, 0x06, 0x08), addr
  48. I2CWrite sda, scl, 0xd0, addr, escribe  'escribe los datos al DS1307
  49. NEXT addr
  50.  
  51. 'bucle para lectura de datos desde el DS1307
  52. LOOP:
  53. addr = 0
  54. I2CRead sda, scl, 0xd1, addr, sec
  55. addr = 1
  56. I2CRead sda, scl, 0xd1, addr, min
  57. addr = 2
  58. I2CRead sda, scl, 0xd1, addr, hour
  59. addr = 3
  60. I2CRead sda, scl, 0xd1, addr, daym
  61. addr = 4
  62. I2CRead sda, scl, 0xd1, addr, day
  63. addr = 5
  64. I2CRead sda, scl, 0xd1, addr, month
  65. addr = 6
  66. I2CRead sda, scl, 0xd1, addr, year
  67.  
  68. 'escribimos resultado en el lcd
  69. Lcdcmdout LcdClear
  70. Lcdcmdout LcdLine3Home
  71. Lcdout " Hora: "
  72. DATA = hour
  73. GOSUB PRINT
  74. Lcdout "."
  75. DATA = min
  76. GOSUB PRINT
  77. Lcdout "."
  78. DATA = sec
  79. GOSUB PRINT
  80. Lcdcmdout LcdLine4Home
  81. Lcdout "Fecha: "
  82. DATA = day
  83. GOSUB PRINT
  84. Lcdout "/"
  85. DATA = month
  86. GOSUB PRINT
  87. Lcdout "/0", #year
  88.  
  89. WaitMs 100
  90. GOTO LOOP
  91.  
  92. END                                              
  93.  
  94. 'subrutina de conversión
  95. d_hi = DATA / 16
  96. d_lo = DATA MOD 16
  97. IF d_hi < 10 THEN
  98. Lcdout #d_hi
  99. ELSE
  100. Lcdout "X"
  101. Endif
  102. IF d_lo < 10 THEN
  103. Lcdout #d_lo
  104. ELSE
  105. Lcdout "X"
  106. Endif
  107. RETURN


aqui otro ejemplo que tampoco me funciona:




Código: FreeBasic
  1. 'ejemplo tomado del amigo dogflu, modificado (gracias amigo)
  2. '= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  3. Define CONF_WORD = 0x3f71
  4. Define CLOCK_FREQUENCY = 4
  5. '---------------------------
  6. Define LCD_LINES = 4
  7. Define LCD_CHARS = 20
  8. '---------------------------
  9. ALLDIGITAL
  10.  
  11. '- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- puertos del lcd - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  12. Define LCD_BITS = 4  'indicamos que el bus de datos del lcd sera de 4bit
  13. Define LCD_DREG = PORTB  'el bus de datos sera el puerto B lo cambie
  14. Define LCD_DBIT = 4  'el bus de datos seran los 4 bit menos significativos del puerto A
  15. Define LCD_RSREG = PORTB  'el bit de nrol RS sera del puerto B
  16. Define LCD_RSBIT = 1  'se usara el RB7 como RS
  17. Define LCD_EREG = PORTB  'el bit de nrol E sera del puerto B
  18. Define LCD_EBIT = 2  'se usara el RB6 como E
  19. 'Define LCD_RWREG = PORTx  'el bit de nrol RW sera del puerto x(no se usa)
  20. 'Define LCD_RWBIT = n  'se usara el Rxn como RW (no se usa)
  21. Define LCD_COMMANDUS = 1000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  22. Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  23. Define LCD_INITMS = 50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  24. '-----------------------------------Puerto I2C-----------------------------------------------------
  25. Symbol sda = PORTC.4  'asignamos nombre al pin que hara de SDA del puerto I2C
  26. Symbol scl = PORTC.3  'asignamos nombre al pin que hara de SCL del puerto I2C
  27. '***********************************DEFINICION DE VARIABLES**************************************
  28. '--------------------------------------Variables Programa----------------------------------------
  29. Dim aux_4h As Byte  'contendra el nibble alto del dato leido por el I2C
  30. Dim aux_4l As Byte  'contendra el nibble bajo del dato leido por el I2C
  31. Dim i As Byte  'variable indice
  32. Dim reg(7) As Byte  'contendra los valores finales de fecha y hora en el sistema decimal
  33. '------------------------------------------ASIGNACIONES------------------------------------------
  34. '**************************************DEFINICION DE PUERTOS*************************************
  35. '----------------------ASIGNACION DE I/O y valores de inicio de las salidas---------------------
  36. 'ADCON1 = 0x07  'Los pin PORTA como I/O
  37. 'ansel = %00000000  'los pin I/O digitales
  38. 'CMCON = 0x07  'comparador a off
  39. 'osccon = 0x7e  'set intrc To 8mhz, se usara reloj interno a 8Mhz
  40. TRISA = 0x01  'Puerto A como salidas
  41. TRISB = 0x00  'puerto B como salidas
  42. TRISC = 0x00
  43. TRISD = 0x00
  44. TRISE = 0x00
  45. 'TRISA.4 = 1  'como entrada (RA4, adc)
  46. TRISA.0 = 1  'como entrada (RA0, tecla S1)
  47. 'TRISB.2 = 1  'como entrada (RA5, tecla S2)
  48. 'PORTB.3 = 1  'luz lcd a on (RB3)
  49. 'PORTC.7 = 1  'led amarillo a off
  50. 'PORTB.0 = 1  'led verde a off
  51. '**************************************Inicio Programa*********************************************
  52. Lcdinit 1  'inicializa el lcd sin cursor
  53. WaitMs 1000  'espera 1Seg
  54. Lcdout " 16f877A_LCD_RTC/I2C"  'escribe en el lcd
  55. Lcdcmdout LcdLine2Home  'seleciona la linea dos como proxima para escritura
  56. Lcdout "     Pruebas con I2C"  'escribe en el lcd
  57. WaitMs 3000  'espera 3Seg
  58. Lcdcmdout LcdClear
  59. '-------------------------------------inicializacion del reloj-------------------------------------
  60. '-------------------Aqui escribimos los valores para cargar al RTC---------------------------------
  61. If RA0 = 0 Then  'si la tecla S1 esta pulsada pasaremos los datos al reloj
  62. I2CWrite sda, scl, 0xd0, 0, 0x00  'segundos, escrito en hex, porque coincide en este caso con BCD del RTC
  63. I2CWrite sda, scl, 0xd0, 1, 0x59  'minutos
  64. I2CWrite sda, scl, 0xd0, 2, 0x23  'horas
  65. I2CWrite sda, scl, 0xd0, 3, 0x01  'dia de la semana
  66. I2CWrite sda, scl, 0xd0, 4, 0x31  'dia del mes
  67. I2CWrite sda, scl, 0xd0, 5, 0x12  'mes
  68. I2CWrite sda, scl, 0xd0, 6, 0x06  'año
  69. I2CWrite sda, scl, 0xd0, 7, 0x10  'salida a 1hz
  70. Endif
  71. '--------------------------------------Main Programa-----------------------------------------------
  72. main:
  73. Gosub print_lcd  'actualiza la hora
  74. WaitMs 100  'pausa de 100mSeg.
  75. Goto main
  76. End                                              
  77. '--------------------------------------FIN DEL MAIN---------------------------------------------
  78. '**************************************Subrrutinas**********************************************
  79. print_lcd:  'lee la hora del RTC, la pasa a decimal y la envia al lcd
  80. i = 0
  81. While i <= 6  'se repite el codigo comprendido entre while y wend, mientras i sea menor o igual a 6
  82. I2CRead sda, scl, 0xd1, i, reg(i)  'lectura de la direccion de memoria indicada del RTC, formato BCD
  83. aux_4l = reg(i) And %00001111  'eliminamos los bit de configuracion del RTC y dejamos solo el nibble bajo
  84. If i = 0 Then aux_4h = reg(i) And %01110000  'segundos, borrado de bit configuracion y almacena nibble alto
  85. If i = 1 Then aux_4h = reg(i) And %11110000  'minutos, almacena nibble alto
  86. If i = 2 Then aux_4h = reg(i) And %10110000  'horas, borrado de bit configuracion y almacena nibble alto
  87. If i = 3 Then aux_4h = reg(i) And %11110000  'dia_semana, almacena nibble alto
  88. If i = 4 Then aux_4h = reg(i) And %11110000  'dia_mes, almacena nibble alto
  89. If i = 5 Then aux_4h = reg(i) And %11110000  'mes, almacena el nibble alto
  90. If i = 6 Then aux_4h = reg(i) And %11110000  'año, almacena el nibble alto
  91. aux_4h = ShiftRight(aux_4h, 4)  'convierte el nibble alto en bajo
  92. reg(i) = (aux_4h * 10) + aux_4l  'fusiona los nibbles alto y bajo en una sola variable en formato decimal
  93. i = i + 1  'incrementa la variable indice con cada repeticion del bucle While/Wend
  94. Wend  'fin del bucle y salta a While
  95. Lcdcmdout LcdLine3Home  'cursor del lcd a la izquierda en la linea 1
  96. If reg(2) < 10 Then Lcdout "0"  'si horas es inferior a 10 escribe el cero delante
  97. Lcdout #reg(2), ":"  'escribe la hora y el separador
  98. If reg(1) < 10 Then Lcdout "0"  'si minutos es inferior a 10 escribe el cero delante
  99. Lcdout #reg(1), ":"  'escribe los minutos y el separador
  100. If reg(0) < 10 Then Lcdout "0"  'si segundos es inferior a 10 escribe el cerodelante
  101. Lcdout #reg(0)  'escribe los segundos
  102. Lcdcmdout LcdLine4Home  'cursor del lcd a la izquierda en la linea 2
  103. If reg(3) = 1 Then Lcdout "Dom"  'asigna el literal al dia de la semana
  104. If reg(3) = 2 Then Lcdout "Lun"
  105. If reg(3) = 3 Then Lcdout "Mar"
  106. If reg(3) = 4 Then Lcdout "Mie"
  107. If reg(3) = 5 Then Lcdout "Jue"
  108. If reg(3) = 6 Then Lcdout "Vie"
  109. If reg(3) = 7 Then Lcdout "Sab"
  110. Lcdout "/"  'escribe separador
  111. If reg(4) < 10 Then Lcdout "0"  'si dia del mes es inferior a 10 escribe cero
  112. Lcdout #reg(4), "/"  'escribe el dia del mes y el separador
  113. If reg(5) < 10 Then Lcdout "0"  'si mes es inferior a 10 escribe cero
  114. Lcdout #reg(5), "/"  'escribe el mes, separador y los dos primeros digitos del año de 4 digitos
  115. If reg(6) < 10 Then Lcdout "0"  'si año es inferior a 10 escribe primero el cero
  116. Lcdout #reg(6)  'escribe el año
  117. Return                                            
  118. End



solo muestran la inicializacion es decir

00:00:00    00/00/00

pero al ponerle un led al SDA y otro al SCL el led parpadea.
« Última modificación: 24 de Noviembre de 2008, 21:19:10 por pajaro »

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #31 en: 05 de Diciembre de 2008, 00:08:40 »
hola

al parecer segun simulacion del proteus el i2c siempre escribe por i2c .
no lee el leloj.

al parecer debe de ser u error del conpilador no difiere entre i2cREad y la instrucion i2c write

alguien tubo este problema con este compilador.

¿alguien le paso esto mismo?, ¿alguien conoce la solucion?


un saludo

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2312
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #32 en: 05 de Diciembre de 2008, 14:29:13 »
hola de nuevo pajaro, perdona que no me ha sido posible prestarte atención hasta ahora... te cuento:

-. no tengo en este momento ocasión de probarlo con un lcd de esas características porque el que tengo está ocupado con otras labores, pero debería funcionar independientemente si éste es de 20x4 o 16x2.
-. no pretendas que una configuración de 4bits te funcione en proteus, o al menos yo lo he descartado por completo.
-. no dejes nada al azar. el pic ha de hacer lo que tu quieres pero, sobre todo, no ha de hacer lo que no quieras. repasa configuración de registros para ello y activa o desactiva la/s funciones que te interesen.
en la siguiente imagen tienes una configuración probada en proteus. en la práctica la opción de usar tan solo 4bits funciona perfectamente:


en este enlace tienes todos los archivos necesarios para probarlo. hay un problema de refresco en el lcd que creo se debe a proteus, si lo tienes montado en la práctica debería funcionar ok.

-. una vez que consigas hacerlo funcionar en una configuración de 8bits pasarlo a 4bits no tiene misterio alguno.

y por último, no entiendo porque se te muestran eses datos... ¿no aparecen los textos 'hora', 'fecha', etc...?

un saludo
« Última modificación: 05 de Diciembre de 2008, 15:03:00 por xocas06 »

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #33 en: 07 de Diciembre de 2008, 19:34:14 »
Por lo pronto he probado este codigo de la EBasic en mi placa entrenadora para el 16F877A y funciona correctamente.
Este codigo es para hacer pruebas con una E2Prom, en este caso he usado la X24C04P.

Cuando pueda, hare las pruebas para el RTC.

Codigo:

Código: QBasic/QuickBASIC
  1. 'EJEMPLO MODIFICADO PARA TRABAJAR CON EL 16F877, PROBADO EN LA REALIDAD
  2. Define CONF_WORD = 0x3f32
  3. Define CLOCK_FREQUENCY = 20  'frecuencia de trabajo del PIC
  4. '***************** Placa Entrenadora (PIC EBadic) ***************************************
  5. 'NOMBRE:16F88_Pic_EBasic_EJEMPLO_28
  6. 'Descripcion: TEST DE LA PLACA EBasic_I2C (Led y 24LC04B)
  7. 'Micro: PIC16F88 / 8mhz reloj interno
  8. 'Fecha/Autor: 29/7/07, 30/12/07, By COS
  9. 'Version: 1.0
  10. 'Solo escribe o lee en el bloque "0" de la memoria
  11. 'Version: 1.1
  12. 'Se completa la funcion para que lea o escriba en todos los bloques de la memoria I2C
  13. 'Esta memoria solo tiene dos bloques y cada uno de ellos tiene 256 posiciones de 1 byte
  14. 'La funcion los maneja como si de un unico bloque de 512 bytes se tratara.
  15. 'Multiplicando la longuitud de 1 bloque por el numero de bloques es igual
  16. 'a la capasidad maxima de la memoria, contemplada como si de su estructura interna
  17. 'estuviera compuesta de un unico bloque (256x2)=512 y direccion maxima 511 bytes
  18. 'ya que la direccion primera comienza en 0.
  19. '*****************************************************************************************
  20. '-------------------------------------Puertos del LCD-------------------------------------
  21. Define LCD_BITS = 8
  22. Define LCD_DREG = PORTB
  23. Define LCD_DBIT = 0
  24. Define LCD_RSREG = PORTC
  25. Define LCD_RSBIT = 0
  26. Define LCD_EREG = PORTC
  27. Define LCD_EBIT = 4
  28. Define LCD_RWREG = PORTC
  29. Define LCD_RWBIT = 1
  30. Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  31. Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  32. Define LCD_INITMS = 50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  33. '****************************************************************************************************
  34. 'Define SIMULATION_WAITMS_VALUE = 1  'Ignora los valores de Waitms
  35. '--------------------------------variables generales-----------------------------------------------
  36. DIM addr AS Word  'direccion I2C
  37. DIM dato AS Byte  'valor a escribir en el I2C
  38. DIM DATA AS Word  'lectura dato I2C, data.HB = 1 = error de escritura, data.LB = dato i2c
  39. DIM eb_i2c AS Byte  'indica el estado del led de la placa I2C
  40. DIM n_random AS Byte  'contendra el numero deseado
  41. '------------------------------------asignacion de valores a las variables--------------------------
  42. dato = 0  'inicializa dato
  43. '--------------------------------------Reasignacion de nombres---------------------------------------
  44. Symbol sda = RC2  'asignamos nombre al pin que hara de SDA del puerto I2C
  45. Symbol scl = RC3  'asignamos nombre al pin que hara de SCL del puerto I2C
  46. Symbol led_amarillo = RA7  'led amarillo
  47. Symbol led_verde = RB0  'led verde
  48. Symbol luz_lcd = RB3  'iluminacion del lcd
  49. Symbol s1 = RA6  'tecla S1
  50. Symbol s2 = RA5  'tecla S2
  51. '------------------------------------Definicion de puertos------------------------------------------
  52. AllDigital  'los pin I/O digitales
  53. 'ANSEL = %00010000  'los pin I/O digitales y RA4 analogico
  54. 'CMCON = 0x07  'comparador a off
  55. 'osccon = 0x7e  'set intrc To 8mhz, se usara reloj interno a 8Mhz
  56. TRISA = 0xff  'Puerto A como ENTRADAS
  57. TRISB = 0xff  'puerto B como ENTRADAS
  58. TRISC = 0xff
  59. TRISD = 0xff
  60. TRISE = 0xff
  61. 'TRISA.4 = 1  'como entrada (RA4, adc)
  62. 'TRISA.6 = 1  'como entrada (RA6, tecla S1)
  63. 'TRISA.5 = 1  'como entrada (RA5, tecla S2)
  64. 'TRISB.3 = 0  'como salida RB3
  65. 'TRISA.7 = 0  'como salida RA7
  66. 'TRISB.0 = 0  'como salida RB0
  67. TRISA.4 = 0  'como salida RA4
  68. 'PORTB.3 = 1  'luz lcd a on (RB3)
  69. 'PORTA.7 = 1  'led amarillo a off (RA7), negado
  70. 'PORTB.0 = 1  'led verde a off (RB0), negado
  71. PORTA.4 = 0  'led EBbasic_I2C a off (RA4)
  72. '------------------------------------Inicio--------------------------------------------
  73. Lcdinit  'inicializa el LCD sin cursor
  74. WaitMs 100  'pausa de 0.1Seg.
  75. Lcdout "Test P. EB_I2C"  'Imprime el texto en el LCD
  76. Lcdcmdout LcdLine2Home
  77. Lcdout "Version 1.1"
  78. WaitMs 5000  'pausa de 5Seg.
  79. '--------------------------------Rutina Programa---------------------------------------
  80. main:
  81.         Lcdcmdout LcdClear  'borra lcd
  82.         FOR addr = 0 TO 511  'addr tomara los valores desde 0 hasta 511, bucle
  83.                 Lcdcmdout LcdLine1Home  'cursor linea 1 y principio
  84.                 Lcdout "Wr: ad.", #addr, " d.", #dato, "    "  '#addr  'se escribe en el lcd
  85.                 DATA = d_e2prom(addr, dato, 0)  'llama a la funcion R/W del I2C en modo escritura
  86.                 Lcdcmdout LcdLine2Home  'cursor linea 2 y principio
  87.                 Lcdout "Read: ", #data.LB, "  "  'se escribe en el lcd
  88.                 WaitMs 100  'se espera 100mSeg.
  89.                 IF DATA.HB = 1 THEN  'bit de error si esta a 1
  90.                         Lcdcmdout LcdClear  'borra el lcd
  91.                         Lcdout "Error: "  'imprime en el display
  92.                         Lcdcmdout LcdLine2Home  'cursor al principio de la linea 2
  93.                         Lcdout "Wr: ", #dato, " Rd:", #data.LB, "      "  'imprime en el display
  94.                         WaitMs 500  'se hace una pausa de 500mSeg.
  95.                 Endif  'cierra el if
  96.         dato = dato + 1  'incrementa dato, se tiene en cuenta que cuando desborda comienza en 0.
  97.         NEXT addr  'cierra el bucle for
  98. END                                              
  99. '------------------------------Rutinas-----------------------------------------------
  100. 'Funcion para el manejo de la E2Prom y Led indicador R/W
  101. 'La funcion devuelve un numero tipo Word, en el que el byte menos significativo es
  102. 'el dato leido y el byte mas significativo indica si hubo error en la escritura, error=1
  103. 'e2p_addr.15...12, selecciona el dispocitivo en el bus I2C
  104. 'e2p_addr.11...09, selecciona la pagina o bloque de la memoria
  105. 'e2p_addr.8, selecciona si la operacion sera de lectura o escritura
  106. 'e2p_addr.LB, selecciona la posicion a escribir dentro del bloque de momoria seleccionado
  107. 'e2p_data, dato a escribir en la posicion indicada por e2p_addr
  108. 'e2p_rw, indica a la funcion si la operacion sera de lectura (=1) o escritura (=0)
  109. FUNCTION d_e2prom(e2p_addr AS Word, e2p_data AS Byte, e2p_rw AS Byte) AS Word
  110.         '0xa0 (1010b) direccion de la memoria I2C, todos los pin de configuracion a cero
  111.         e2p_addr.15 = 1  'direccion o nombre del dispositivo en el bus I2C, bit mas significativo
  112.         e2p_addr.14 = 0  '...
  113.         e2p_addr.13 = 1  '...
  114.         e2p_addr.12 = 0  '..., bit menos significativo
  115.         e2p_addr.11 = e2p_addr.10  'selecciona la pagina de la memoria I2C, bit mas significativo
  116.         e2p_addr.10 = e2p_addr.9  '...
  117.         e2p_addr.9 = e2p_addr.8  '..., bit menos significativo
  118.         'e2p_addr.8 = 0  'modo escritura, indiferente ya que lo controla directamente I2CWrite
  119.         RA4 = 1  'activa el led de la placa EBasic_I2C, actividad
  120.         IF e2p_rw = 0 THEN  'permite el modo escritura
  121.                 I2CWrite sda, scl, e2p_addr.HB, e2p_addr.LB, e2p_data  'escribe en el I2C
  122.                 d_e2prom.HB = 1  'registra posible error si no se borra posteriormente
  123.                 WaitMs 5  'pausa para que el chip termine la escritura, tiempo indicado en el datasheet
  124.         Endif
  125.         'e2p_addr.8 = 1  'modo lectura, indiferente ya que lo controla directamente I2CRead
  126.         I2CRead sda, scl, e2p_addr.HB, e2p_addr.LB, d_e2prom.LB  'lee en el puerto I2C
  127.         IF d_e2prom.LB = e2p_data AND e2p_rw = 0 THEN  'solo se ejecuta si hubo ciclo de escritura
  128.                 d_e2prom.HB = 0  'borra el flag de error
  129.         Endif
  130.         RA4 = 0  'apaga led placa EB_I2C, actividad
  131. END FUNCTION
« Última modificación: 07 de Diciembre de 2008, 19:37:20 por dogflu66 »
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #34 en: 08 de Diciembre de 2008, 16:55:17 »
El siguiente codigo que maneja un DS1307 lo he probado tambien en mi placa entrenadora para el PIC16F877 y funciona correctamente

Código: QBasic/QuickBASIC
  1. 'ADAPTADO PARA EL PIC16F877 ***********************************************************
  2. Define CONF_WORD = 0x3f32
  3. Define CLOCK_FREQUENCY = 20
  4. '********************************** PIC Entrenadora BASIC (PicEBasic)******************************
  5. 'NOMBRE: 16F88_Pic_EBasic_LCD_RTC_ADC_12******ADAPTACION AL PIC16F877******************************
  6. 'MICRO: PIC16F88
  7. 'FECHA/AUTOR: 04/07, 05/07 - By COS
  8. 'VERSION 1.2
  9. 'Se habilita el modulo usar como salida de datos serie
  10. 'se cambian todos los "Serout PORTB.5, 4800, " por Hserout
  11. 'se observa un ahorro de memoria considerable y una aceleracion del programa increible.
  12. 'VERSION 1.1
  13. 'modificacion de la rutina "pause_ms"
  14. 'modificacion de rutina de teclas, porque se veian afectadas al crecer la longitud del programa main
  15. 'Se añade salida de la temperatura, hora y fecha por el puerto serie (Soft)
  16. 'Pendiente de grafica de temperatura por el hyperterminal
  17. 'VERSION 1.0
  18. 'DESCRIPCION: Muestra en el display la fecha, hora (24h)mediante el DS1307 y temperatura (LM35)
  19. 'S1 y S2 pulsadas al mismo tiempo, entramos en programacion del reloj
  20. 'Una vez en programacion con S1 seleccionamos el dato a cambiar, este queda en modo parpadeo
  21. 'Una vez en programacion con S2 incrementamos el dato seleccionado dentro de sus cotas
  22. 'S1, pulsado al principio salida del RTC a on, 1Hz, y S2 salida a off, led off
  23. 'Se muestra la temperatura en el LCD mediante un LM35, temperatura positiva y negativa
  24. '***************************************************************************************************
  25. '-------------------------------------Puertos del LCD-----------------------------------------------
  26. Define LCD_BITS = 8
  27. Define LCD_DREG = PORTB
  28. Define LCD_DBIT = 0
  29. Define LCD_RSREG = PORTC
  30. Define LCD_RSBIT = 0
  31. Define LCD_EREG = PORTC
  32. Define LCD_EBIT = 4
  33. Define LCD_RWREG = PORTC
  34. Define LCD_RWBIT = 1
  35. Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  36. Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  37. Define LCD_INITMS = 50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  38. '-----------------------------------asignacion de nombres-----------------------------------------------------
  39. Symbol sda = PORTC.2  'asignamos nombre al pin que hara de SDA del puerto I2C
  40. Symbol scl = PORTC.3  'asignamos nombre al pin que hara de SCL del puerto I2C
  41. Symbol led_amarillo = PORTA.7  'led amarillo
  42. Symbol led_verde = PORTB.0  'led verde
  43. Symbol luz_lcd = PORTB.3  'retroiluminacion del lcd
  44. Symbol s1 = RE0  'se asigna nombre a la tecla
  45. Symbol s2 = RE1  'se asigna nombre a la tecla
  46. '***********************************DEFINICION DE VARIABLES**************************************
  47. '-----------------------------------variables de los timer---------------------------------------
  48. DIM aux_pause AS Word  'variable auxiiar el PAUSE
  49. DIM pause AS Word  'contiene el valor para simular el comando Waitms
  50. DIM timer_1ms AS Word  'base de tiempos se incrementa cada 1mSeg, timer del PAUSE
  51. DIM timer_base AS Byte  'tiempo referencia para los timer por soft del programa
  52. DIM timer_base_tiempo AS Byte  'contiene el valor del tiempo del timer_base
  53. DIM timer1_ms AS Word  'base de tiempos en ms
  54. DIM timer2_ms AS Word  'base de tiempos en ms
  55. DIM timer3_ms AS Word  'base de tiempos ms
  56. DIM timer1_100ms AS Byte  'base de tiempos msx100
  57. DIM timer2_100ms AS Byte  'base de tiempos msx100
  58. DIM timer3_100ms AS Byte  'base de tiempos msx100
  59. DIM timer_1ms_tiempo AS Word  'contiene el valor del tiempo de timer_1ms
  60. DIM timer1_ms_tiempo AS Word  'contiene el valor del tiempo del timer1_ms
  61. DIM timer2_ms_tiempo AS Word  'contiene el valor del tiempo del timer2_ms
  62. DIM timer3_ms_tiempo AS Word  'contiene el valor del tiempo del timer3_ms
  63. DIM timer1_100ms_tiempo AS Byte  'contiene el valor del tiempo del timer1_100ms
  64. DIM timer2_100ms_tiempo AS Byte  'contiene el valor del tiempo del timer2_100ms
  65. DIM timer3_100ms_tiempo AS Byte  'contiene el valor del tiempo del timer3_100ms
  66. '--------------------------------------Variables Programa RTC----------------------------------------
  67. DIM aux_4h AS Byte  'contendra el nibble alto del dato leido por el I2C
  68. DIM aux_4l AS Byte  'contendra el nibble bajo del dato leido por el I2C
  69. DIM i AS Byte  'variable indice
  70. DIM reg(7) AS Byte  'contendra los valores finales de fecha y hora en el sistema decimal
  71. DIM flash_1 AS Bit  'controla el parpadeo de los digitos del lcd, activo a 1
  72. DIM dato AS Byte  'indica la direccion del RTC a cambiar de valor
  73. DIM flag_1 AS Bit  'activa la rutina de ajuste del reloj, activo a 1
  74. DIM s1_on AS Bit  'tecla pulsada si s1_on=1
  75. DIM s2_on AS Bit  'tecla pulsada si s2_on=1
  76. DIM aux_ajuste AS Byte  'variable auxiliar para la rutina de ajuste
  77. '-----------------------------------------------------------------------------------------------
  78. '-------------------------------Variables del ADC y Rutina division (temperatura)------------------------------
  79. DIM entero AS Word  'parte entera
  80. DIM decimal AS Word  'los dos decimales
  81. DIM division AS LONG  'almacenara el numero con los dos decimales
  82. DIM adc_4 AS Word  'contendra el valor de la entrada del ADC
  83. DIM aux_adc_4 AS Word  'auxiliar
  84. '--------------------------------Variables temperatura-------------------------------------------
  85. DIM factor_escala AS Word  'contiene el factor de correcion para pasar el valor del ADC a voltios, max. 5V
  86. DIM temperatura AS Word  'almacena la temperatura final
  87. DIM temp AS LONG  'contendra la temperatura completa sin coma
  88. DIM signo AS Bit  'indica el signo de la temperatura
  89. '--------------------------------Variables calculo media aritmetica (temperatura)----------------------------
  90. DIM media_temp(20) AS Word  'numero de muestras para calcular la media aritmetica
  91. DIM media_indice AS Byte  'se utiliza como indice
  92. DIM aux_media AS Byte  'variable auxiliar
  93. '------------------------------------------ASIGNACIONES------------------------------------------
  94. '------------------------------------asignacion de valores a las variables (RTC)--------------------------
  95. s1_on = 0
  96. s2_on = 0
  97. dato = 7  'fuera de ajuste o modo normal de trabajo del reloj, de 0 a 6 modo ajuste
  98. flash_1 = 0
  99. flag_1 = 0
  100. timer_base = 0
  101. timer1_ms = 0
  102. timer2_ms = 0
  103. timer3_ms = 0
  104. timer1_100ms = 0
  105. timer2_100ms = 0
  106. timer3_100ms = 0
  107. timer_base_tiempo = 100  'temporiza 100 mSeg
  108. timer_1ms_tiempo = 1  'temporiza 1mseg
  109. timer1_ms_tiempo = 100  'temporiza 100 mSeg., asignado a la tecla S1
  110. timer2_ms_tiempo = 500  'temporiza 500 mSeg.
  111. timer3_ms_tiempo = 100  'temporiza 100 mSeg., asignado a la tecla S2
  112. timer1_100ms_tiempo = 10  'temporiza 1 Seg.
  113. timer2_100ms_tiempo = 10  '255  'temporiza 25.5 Seg.
  114. timer3_100ms_tiempo = 1  'temporiza 0.1seg.
  115. '-------------------------------------asiganacion de valores a las variables (temperatura)------
  116. entero = 0
  117. decimal = 0
  118. division = 0
  119. adc_4 = 0
  120. factor_escala = 10  'factor de escala para un decimal
  121. temperatura = 0
  122. temp = 0
  123. media_indice = 0
  124. aux_media = 0
  125. '**************************************DEFINICION DE PUERTOS*************************************
  126. '----------------------ASIGNACION DE I/O y valores de inicio de las salidas---------------------
  127. AllDigital
  128. 'ADCON1 = 0x07  'Los pin PORTA como I/O
  129. TRISA = 0xff  'Puerto A como salidas
  130. TRISB = 0xff  'puerto B como salidas
  131. TRISC = 0xff
  132. TRISD = 0xff
  133. TRISE = 0xff
  134. 'TRISA.4 = 1  'como entrada (RA4, adc)
  135. TRISE.0 = 1  'como entrada (RA6, tecla S1)
  136. TRISE.1 = 1  'como entrada (RA5, tecla S2)
  137. 'PORTB.3 = 1  'luz lcd a on (RB3)
  138. 'PORTA.7 = 1  'led amarillo a off
  139. 'PORTB.0 = 1  'led verde a off
  140. '------------------------------------Velocidad de la UART-----------------------------------------
  141. Hseropen 4800  'velocidad de trabajo del modulo UART del PIC, RB5 tiene que ser declarado como salida
  142. '------------------------------------Inicializacion de Interrupciones-----------------------------
  143. T1CON.TMR1CS = 0  'asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion
  144. T1CON.T1CKPS0 = 0  'factor del preescales del timer1, 0
  145. T1CON.T1CKPS1 = 0  'factor del preescales del timer1, 0
  146. TMR1H = 0xfc  'carga el registro del contador para que desborde cada 1mSeg, byte alto
  147. TMR1L = 0x18  'carga el registro del contador para que desborde cada 1mSeg, byte bajo
  148. T1CON.TMR1ON = 1  'habilitacion del TMR1, comienza a incrementarce
  149. INTCON.PEIE = 1  'bit de habilitacion de interrupciones de perifericos
  150. Enable  'INTCON.GIE habilita todas las interrupciones globales
  151. '**************************************Inicio Programa*********************************************
  152. Lcdinit  'inicializa el lcd sin cursor
  153. Hserout 0x0c, "MUESTRA LA TEMPERATURA MEDIA CADA 25.5 Seg.", CrLf  'alpuerto serie
  154. Hserout "-------------------------------------------", CrLf, CrLf  'alpuerto serie
  155. PIE1.TMR1IE = 1  'activa las interrupciones del timer1
  156. pause = 1000
  157. GOSUB pause_ms  'espera el tiempo indicado en pause
  158. Lcdout "16F88LCD_RTC/I2C"  'escribe en el lcd
  159. Lcdcmdout LcdLine2Home  'seleciona la linea dos como proxima para escritura
  160. Lcdout "ADC_LM35_RS232"  'escribe en el lcd
  161. pause = 3000
  162. GOSUB pause_ms  'espera el tiempo indicado en pause
  163. Lcdcmdout LcdClear  'borra el display y cursor a casa
  164. '--------------------------------inicializa variable media_temperatura---------------------------
  165. 'Gosub inicializa_temp
  166. '--------------------------------inicializa los registros del RTC---------------------------------
  167. GOSUB inicaliza_rtc
  168. '--------------------------------------Main Programa-----------------------------------------------
  169. main:
  170.         IF s1 = 1 AND s1_on = 1 AND s2 = 1 AND s2_on = 1 AND flag_1 = 0 THEN  '________modo ajuste
  171.                 flag_1 = 1  'activa la rutina de ajustes
  172.                 dato = 0  'selecciono registro del RTC
  173.                 pause = 200
  174.                 GOSUB pause_ms  'hace una pausa del valor que tenga pause en ms
  175.                 s1_on = 0  'desbloquea la tecla S1
  176.                 s2_on = 0  'desbloquea la tecla s2
  177.         Endif  '___________________
  178.         IF flag_1 = 1 THEN GOSUB ajuste_reloj  '__________saltamos a la rutina de ajuste
  179.         IF timer3_100ms >= timer3_100ms_tiempo THEN  'actualiza datos en el lcd cada 100ms
  180.                 GOSUB lee_hora  'lee la fecha y hora del reloj
  181.                 GOSUB print_lcd  'actualiza los datos del reloj en el display
  182.                 timer3_100ms = 0
  183.         Endif  '__________________
  184.         IF timer2_100ms >= timer2_100ms_tiempo THEN
  185.                 GOSUB lee_adc  'salto con retorno, rutina de lectura de la entrada ADC
  186.                 GOSUB temp_calculo  'salto con retorno, hace el calculo de la temperatura y guarda el valor en temperatura
  187.                 GOSUB media_arit  'salto con retorno, calcula la media aritmetica
  188.                 division = dvsion_dcmles(temperatura, factor_escala)  'llama a la funcion dvsion_dcmles, que retorna un long
  189.                 GOSUB print_rs232_temperatura
  190.                 GOSUB print_rs232_date
  191.                 timer2_100ms = 0
  192.         Endif
  193. GOTO main
  194. END                                              
  195. '--------------------------------------FIN DEL MAIN---------------------------------------------
  196. '**************************************Subrrutinas**********************************************
  197. inicaliza_rtc:  '-------------------------inicializa el reloj----------------------------------------------------
  198.         PIE1.TMR1IE = 0  'deshabilita las interrupciones del timer1
  199.         I2CRead sda, scl, 0xd1, 0, reg(0)  'leo los segundos
  200.         reg(0) = reg(0) AND %01111111  'habilito bit de control que activa el reloj
  201.         I2CWrite sda, scl, 0xd0, 0, reg(0)  'escribo el registro de los segundos
  202.         I2CRead sda, scl, 0xd1, 1, reg(0)  'leo el registro de los minutos
  203.         reg(0) = reg(0) AND %10111111  'habilito bit de control que activa el formato de 24h
  204.         I2CWrite sda, scl, 0xd0, 0, reg(0)  'escribo el registro de los minutos
  205. '-------------------------------inicializa la salida del RTC-------------------------------
  206.         I2CWrite sda, scl, 0xd0, 7, 0x10  'salida a 1hz, a on
  207.         IF s2 = 0 THEN I2CWrite sda, scl, 0xd0, 7, 0x80  'salida a off, led off
  208.         PIE1.TMR1IE = 1  'habilita las interrupciones del timer1
  209.         pause = 1000
  210.         GOSUB pause_ms  'espera el tiempo indicado en pause
  211. RETURN                                            
  212. ajuste_reloj:  'rutina de ajuste del reloj
  213.         '________________________Control posicion del dato a variar en el reloj
  214.         IF s1 = 1 AND s1_on = 1 AND s2_on = 0 THEN  'detecta tecla S1
  215.                 dato = dato + 1  'seleciona el dato a ser modificado
  216.                 IF dato > 6 THEN flag_1 = 0  'indica fin de rutina de ajuste
  217.                 s1_on = 0  'la tecla queda desbloqueada
  218.         Endif  '_____________________________
  219.         '____________Lectura de la hora para su modificacion y posterior grabacion, rutina BCD
  220.         IF s2 = 1 AND s2_on = 1 AND s1_on = 0 THEN  'deteca tecla S2
  221.                 s2_on = 0  'la tecla queda desbloqueada
  222.                 IF dato < 7 THEN  'limita la direcciones de trabajo del reloj
  223.                         GOSUB lee_hora  'lee los datos de los regis. RTC y los pasa a decimal, elimina los bit de control
  224.                         aux_ajuste = reg(dato)  'hace una imagen del valor del registro a modificar
  225.                         aux_ajuste = aux_ajuste + 1  'incrementa el dato a modificar que fue seleccionado
  226.                         IF dato = 2 AND aux_ajuste > 23 THEN aux_ajuste = 0  'acota horas
  227.                         IF dato = 0 OR dato = 1 THEN  'acota segundos y minutos
  228.                                 IF aux_ajuste > 59 THEN aux_ajuste = 0
  229.                         Endif
  230.                         IF dato = 3 AND aux_ajuste > 7 THEN aux_ajuste = 1  'acota el dia de la semana
  231.                         IF dato = 4 AND aux_ajuste > 31 THEN aux_ajuste = 1  'acota el dia del mes
  232.                         IF dato = 5 AND aux_ajuste > 12 THEN aux_ajuste = 1  'acota el mes
  233.                         IF dato = 6 AND aux_ajuste > 30 THEN aux_ajuste = 1  'acota el año, año maximo 2030
  234.                         IF aux_ajuste > 49 AND aux_ajuste < 60 THEN  'Decimal a BCD
  235.                                 aux_ajuste = aux_ajuste - 50
  236.                                 aux_ajuste.4 = 1
  237.                                 aux_ajuste.6 = 1
  238.                         Endif
  239.                         IF aux_ajuste > 39 AND aux_ajuste < 50 THEN  'Decimal a BCD
  240.                                 aux_ajuste = aux_ajuste - 40
  241.                                 aux_ajuste.6 = 1
  242.                         Endif
  243.                         IF aux_ajuste > 29 AND aux_ajuste < 40 THEN  'Decimal a BCD
  244.                                 aux_ajuste = aux_ajuste - 30
  245.                                 aux_ajuste.4 = 1
  246.                                 aux_ajuste.5 = 1
  247.                         Endif
  248.                         IF aux_ajuste > 19 AND aux_ajuste < 30 THEN  'Decimal a BCD
  249.                                 aux_ajuste = aux_ajuste - 20
  250.                                 aux_ajuste.5 = 1
  251.                         Endif
  252.                         IF aux_ajuste > 9 AND aux_ajuste < 20 THEN  'Decimal a BCD
  253.                                 aux_ajuste = aux_ajuste - 10
  254.                                 aux_ajuste.4 = 1
  255.                         Endif
  256.                         IF aux_ajuste < 10 THEN aux_ajuste = aux_ajuste  'Decimal a BCD
  257.                         IF dato = 0 THEN aux_ajuste.7 = 0  'restaura el bit de configracion, activa el oscilador del reloj
  258.                         IF dato = 2 THEN aux_ajuste.7 = 0  'restaura el bit, no lo utiliza el RTC
  259.                         IF dato = 2 THEN aux_ajuste.6 = 0  'restaura el bit de configuracion, reloj 24h
  260.                         PIE1.TMR1IE = 0  'deshabilita las interrupciones del timer1
  261.                         I2CWrite sda, scl, 0xd0, dato, aux_ajuste  'actualiza el dato ya modificado
  262.                         PIE1.TMR1IE = 1  'activa las interrupciones del timer1
  263.                 Endif
  264.         Endif  '____________
  265.         '__________Controla el parpadeo de los digitos cuando el modo selec es activo
  266.         IF timer2_ms >= timer2_ms_tiempo THEN  'tiempo del parpadeo
  267.                 IF flash_1 = 1 THEN  'selecciona si el dato a modificar es visible o no
  268.                         flash_1 = 0  'dato es visible
  269.                 ELSE
  270.                         flash_1 = 1  'dato no es visible
  271.                 Endif
  272.                 timer2_ms = 0  'recarga la base de tiempos
  273.         Endif  '______________
  274. RETURN                                            
  275. lee_hora:  'lee la hora del RTC en formato BCD y la pasa a decimal
  276.         i = 0  'variable indice, asigna los datos de forma ordenada, leidos del RTC
  277.         WHILE i <= 6  'se repite el codigo comprendido entre while y wend, mientras i sea menor o igual a 6
  278.                 PIE1.TMR1IE = 0  'deshabilita las interrupciones del timer1
  279.                 I2CRead sda, scl, 0xd0, i, reg(i)  'lectura de la direccion de memoria indicada del RTC, formato BCD
  280.                 PIE1.TMR1IE = 1  'activa las interrupciones del timer1
  281.                 aux_4l = reg(i) AND %00001111  'eliminamos los bit de configuracion del RTC y dejamos solo el nibble bajo
  282.                 IF i = 0 THEN aux_4h = reg(i) AND %01110000  'segundos, borrado de bit configuracion y almacena nibble alto
  283.                 IF i = 1 THEN aux_4h = reg(i) AND %01110000  'minutos, almacena nibble alto
  284.                 IF i = 2 THEN aux_4h = reg(i) AND %00110000  'horas, borrado de bit configuracion y almacena nibble alto
  285.                 IF i = 3 THEN aux_4h = reg(i) AND %00000000  'dia_semana, almacena nibble alto
  286.                 IF i = 4 THEN aux_4h = reg(i) AND %00110000  'dia_mes, almacena nibble alto
  287.                 IF i = 5 THEN aux_4h = reg(i) AND %00010000  'mes, almacena el nibble alto
  288.                 IF i = 6 THEN aux_4h = reg(i) AND %11110000  'año, almacena el nibble alto
  289.                 aux_4h = ShiftRight(aux_4h, 4)  'convierte el nibble alto en bajo
  290.                 reg(i) = (aux_4h * 10) + aux_4l  'fusiona los nibbles alto y bajo en una sola variable en formato decimal
  291.                 i = i + 1  'incrementa la variable indice con cada repeticion del bucle While/Wend
  292.         WEND  'fin del bucle y salta a While
  293. RETURN                                            
  294. print_lcd:  'rutina de escritura en el lcd
  295.         Lcdcmdout LcdLine1Home  'cursor del lcd a la izquierda en la linea 1
  296.         IF dato = 2 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos de la hora
  297.                 Lcdout "  "  'borra el dato determinado para dar la sensacion de parpadeo
  298.         ELSE
  299.                 IF reg(2) < 10 THEN Lcdout "0"  'si horas es inferior a 10 escribe el cero delante
  300.                 Lcdout #reg(2)  'escribe la hora
  301.         Endif
  302.         Lcdout ":"  'escribe el separador
  303.         IF dato = 1 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos de los minutos
  304.                 Lcdout "  "  'borra el dato determinado para dar la sencacion de parpadeo
  305.         ELSE
  306.                 IF reg(1) < 10 THEN Lcdout "0"  'si minutos es inferior a 10 escribe el cero delante
  307.                 Lcdout #reg(1)  'escribe los minutos
  308.         Endif
  309.         Lcdout ":"  'escribe el separador
  310.         IF dato = 0 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos de los segundos
  311.                 Lcdout "  "  'borra el dato determinado para dar la sencacion de parpadeo
  312.         ELSE
  313.                 IF reg(0) < 10 THEN Lcdout "0"  'si segundos es inferior a 10 escribe el cero delante
  314.                 Lcdout #reg(0)  'escribe los segundos
  315.         Endif
  316.         GOSUB print_lcd_temp  'salto con retorno a la rutina de impresion de la temperatura
  317.         Lcdcmdout LcdLine2Home  'cursor del lcd a la izquierda en la linea 2
  318.         IF dato = 3 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos del dia semana
  319.                 Lcdout "    "  'borra el dato determinado para dar la sencacion de parpadeo
  320.         ELSE
  321.                 IF reg(3) = 1 THEN Lcdout "Dom."  'asigna el literal al dia de la semana
  322.                 IF reg(3) = 2 THEN Lcdout "Lun."
  323.                 IF reg(3) = 3 THEN Lcdout "Mar."
  324.                 IF reg(3) = 4 THEN Lcdout "Mie."
  325.                 IF reg(3) = 5 THEN Lcdout "Jue."
  326.                 IF reg(3) = 6 THEN Lcdout "Vie."
  327.                 IF reg(3) = 7 THEN Lcdout "Sab."
  328.         Endif
  329.         Lcdout " "  'escribe separador
  330.         IF dato = 4 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos del dia del mes
  331.                 Lcdout "  "  'borra el dato determinado para dar la sencacion de parpadeo
  332.         ELSE
  333.                 IF reg(4) < 10 THEN Lcdout "0"  'si dia del mes es inferior a 10 escribe cero
  334.                 Lcdout #reg(4)  'escribe el dia del mes
  335.         Endif
  336.         Lcdout "/"  'escribe el separador
  337.         IF dato = 5 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos de los meses
  338.                 Lcdout "  "  'borra el dato determinado para dar la sencacion de parpadeo
  339.         ELSE
  340.                 IF reg(5) < 10 THEN Lcdout "0"  'si mes es inferior a 10 escribe cero
  341.                 Lcdout #reg(5)  'escribe el mes
  342.         Endif
  343.         Lcdout "/20"  'separador y los dos primeros digitos del año de 4 digitos
  344.         IF dato = 6 AND flash_1 = 1 THEN  'control final del parpadeo de los digitos de los años
  345.                 Lcdout "  "  'borra el dato determinado para dar la sencacion de parpadeo
  346.         ELSE
  347.                 IF reg(6) < 10 THEN Lcdout "0"  'si año es inferior a 10 escribe primero el cero
  348.                 Lcdout #reg(6)  'escribe el año
  349.         Endif
  350. RETURN                                            
  351. '--------------------------------------Subrrutina lectura ADC, division y LCD
  352. lee_adc:  '_______________________lee la entrada analogica
  353. 'ADCON1 = 0x00  'Los pin PORTA como analogicos
  354. 'Adcin 4, adc_4  'Lee el valor de la entrada analogica y lo guarda en adc_4
  355. 'ADCON1 = 0x07  'Los pin PORTA como I/O
  356. RETURN                                            
  357. print_lcd_temp:  '____________________muestra los datos por el display
  358.         entero = division.HW  'sede el word alto a entero, parte entera
  359.         decimal = division.LW  'sede el byte alto del word bajo a decimal_1
  360.         Lcdout " "  'espacio en blanco
  361.         IF signo = 0 THEN Lcdout "+", #entero, "."  'muestra los datos en el lcd
  362.         IF signo = 1 THEN Lcdout "-", #entero, "."  'muestra los datos en el lcd
  363.         Lcdout #decimal, "C   "  'muestra los datos en el lcd
  364. RETURN                                            
  365. '________Argumentos de entrada dos variables tipo word, dividendo y divisor, argumento de salida una variable tipo long
  366. FUNCTION dvsion_dcmles(dvdo AS Word, dvsor AS Word) AS LONG  '________Rutina funcion division con decimales
  367.         DIM f_entera AS Word  'variable local, contendra la parte entera
  368.         DIM f_resto AS Word  'varable local, contendra el resto
  369.         DIM f_decimal AS Word  'contendra la parte decimal
  370.         f_entera = dvdo / dvsor  'obtengo la division
  371.         f_resto = dvdo MOD dvsor  'obtengo el resto
  372.         f_decimal = (f_resto * 10) / dvsor  'calculo 1 decimal, para obtener 2 decimales multiplicar por 100
  373.         dvsion_dcmles.HW = f_entera  'almacena la parte entera en el word alto
  374.         dvsion_dcmles.LW = f_decimal  'almacena la parte decimal word bajo
  375.         'Recuerda que la parte decimal tiene que ser mostrada en el display con plantilla de dos digitos siempre
  376. END FUNCTION                                      
  377. '___________Calculo de la media aritmetica de la temperatura, 20 muestras
  378. media_arit:
  379.         media_temp(media_indice) = temperatura  'asigna el valor
  380.         temperatura = 0  'se inicaliza a cero
  381.         FOR aux_media = 0 TO 19  'blucle for, se ejecuta 20 veces
  382.                 temperatura = temperatura + media_temp(aux_media)  'se suman los valores
  383.         NEXT aux_media  'cierra for
  384.         temperatura = temperatura / 20  'termina el calculo de la media
  385.         media_indice = media_indice + 1  'controla la entrada de datos que corresponde a media_temp(x)
  386.         IF media_indice > 19 THEN media_indice = 0  'acota el ultimo valor del indice de media_temp
  387. RETURN                                            
  388. '___________Calculo de la temperatura
  389. temp_calculo:  'calculo de la temperatura y del signo de la misma
  390.         IF adc_4 > 112 THEN  'determina si la temperatura es superior a 0ºC
  391.                 aux_adc_4 = adc_4  'asigna el valor del ra4 a la variable auxiliar
  392.                 aux_adc_4 = aux_adc_4 - 112  'elimina de la temperatura la parte de la escala negativa
  393.                 temp = (5000 * aux_adc_4) / 1023  'calcuala el valor de la temperatura sin coma decimal
  394.                 signo = 0  'temperatura positiva
  395.         Endif
  396.         IF adc_4 = 112 THEN  'determina si la temperatura es 0ºC
  397.                 temp = 0  'temperatura 0ºC
  398.                 signo = 0  'asigna signo positivo
  399.         Endif
  400.         IF adc_4 < 112 THEN  'determina si la temperatura es inferior a 0ºC
  401.                 aux_adc_4 = adc_4  'asigna el valor del RA4 a la variable auxiliar
  402.                 aux_adc_4 = 112 - aux_adc_4  'elimina de la temperatura la parte de la escala negativa
  403.                 temp = (5000 * aux_adc_4) / 1023  'calcuala el valor de la temperatura sin coma decimal
  404.                 signo = 1  'asigna el simbolo menos a la temperatura
  405.         Endif
  406.         temperatura = temp  'se pasa de Long a Word
  407. RETURN                                            
  408. inicializa_temp:  '__________inicializa la media aritmetica de la temperatura en el arranque
  409.                 GOSUB lee_adc  'salto con retorno, rutina de lectura de la entrada ADC
  410.                 GOSUB temp_calculo  'salto con retorno, hace el calculo de la temperatura y guarda el valor en temperatura
  411.                 FOR media_indice = 0 TO 19  'indice para rocorrer todas las direcciones de memoria que forman la variable tipo array media_temp
  412.                         media_temp(media_indice) = temperatura  'se de el valor a media_temp
  413.                 NEXT media_indice  'terminacion del bucle For
  414.                 media_indice = 0  'se inicializa a cero, para un uso posterior
  415.                 GOSUB media_arit  'salto con retorno, calcula la media aritmetica
  416.                 division = dvsion_dcmles(temperatura, factor_escala)  'llama a la funcion dvsion_dcmles, que retorna un long
  417. RETURN                                            
  418. print_rs232_temperatura:  'Envia la temperatura con decimales al puerto serie
  419.         PIE1.TMR1IE = 0  'OFF, interrupciones del timer1
  420.         Hserout "TEMPERATURA: "  'pagina en blanco y literal al purto serie
  421.         IF signo = 0 THEN Hserout "+"  'muestra el signo de la temperatura
  422.         IF signo = 1 THEN Hserout "-"  'muestra el signo de la temperatura
  423.         Hserout #entero, ".", #decimal, " "  'temperatura al rs232
  424.         PIE1.TMR1IE = 1  'ON, interrupciones del timer1
  425. RETURN                                            
  426. print_rs232_date:  'rutina de escritura de la hora y fecha por el RS232
  427.         PIE1.TMR1IE = 0  'OFF, interrupciones del timer1
  428.         IF reg(2) < 10 THEN Hserout " 0"  'si horas es inferior a 10 escribe el cero delante
  429.         Hserout #reg(2), ":"  'escribe la hora
  430.         IF reg(1) < 10 THEN Hserout "0"  'si minutos es inferior a 10 escribe el cero delante
  431.         Hserout #reg(1), ":"  'escribe los minutos
  432.         IF reg(0) < 10 THEN Hserout "0"  'si segundos es inferior a 10 escribe el cero delante
  433.         Hserout #reg(0), " "  'escribe los segundos
  434.         IF reg(3) = 1 THEN Hserout "Dom."  'asigna el literal al dia de la semana
  435.         IF reg(3) = 2 THEN Hserout "Lun."
  436.         IF reg(3) = 3 THEN Hserout "Mar."
  437.         IF reg(3) = 4 THEN Hserout "Mie."
  438.         IF reg(3) = 5 THEN Hserout "Jue."
  439.         IF reg(3) = 6 THEN Hserout "Vie."
  440.         IF reg(3) = 7 THEN Hserout "Sab."
  441.         IF reg(4) < 10 THEN Hserout " 0"  'si dia del mes es inferior a 10 escribe cero
  442.         Hserout #reg(4), "/"  'escribe el dia del mes
  443.         IF reg(5) < 10 THEN Hserout "0"  'si mes es inferior a 10 escribe cero
  444.         Hserout #reg(5), "/20"  'escribe el mes
  445.         IF reg(6) < 10 THEN Hserout "0"  'si año es inferior a 10 escribe primero el cero
  446.         Hserout #reg(6), "#", CrLf  'escribe el año
  447.         PIE1.TMR1IE = 1  'ON, interrupciones del timer1
  448. RETURN                                            
  449. pause_ms:  'rutina de espera, rutina tipo Waitms, pause establese el tiempo total en mSeg
  450. 'pause = 1  'ESTA LINEA SOLO SE ACTIVA CUANDO SE UTILIZA EL SIMULADOR
  451.         PIE1.TMR1IE = 0  'OFF, interrupciones del timer1
  452.         timer_1ms_tiempo = pause  'valor a temporizar por timer_1ms
  453.         timer_1ms = 0  'al borrar el contador se activa y comienza la cuenta de 1mSeg
  454.         PIE1.TMR1IE = 1  'ON, interrupciones del timer1
  455.         WHILE timer_1ms < timer_1ms_tiempo  'tiempo en mSeg maximos a contar
  456.         WEND
  457. RETURN                                            
  458. '***********************************Interrupciones*****************************************************
  459. ON Interrupt  'Comienzan las rutinas de las interrupciones, desactiva las interrupciones
  460.         TMR1H = 0xec  'recarga el contador del timer1 para que desborde pasado 1mSeg, byte alto
  461.         TMR1L = 0x79  'recarga el contador del timer1 para que desborde pasado 1mSeg, byte bajo
  462.         Save SYSTEM  'Guarda los valores del sistema para poder reemprender el curso normal del programa
  463.         IF PIR1.TMR1IF = 1 THEN  'comprueba que la interrupcion del timer1 es activa
  464.                 '_________________bases de tiempos
  465.                 timer_base = timer_base + 1  'contador general
  466.                 IF timer_1ms < timer_1ms_tiempo THEN timer_1ms = timer_1ms + 1  'contador para control de la rutina Pause
  467.                 IF timer1_ms < timer1_ms_tiempo THEN timer1_ms = timer1_ms + 1  'contador
  468.                 IF timer2_ms < timer2_ms_tiempo THEN timer2_ms = timer2_ms + 1  'contador
  469.                 IF timer3_ms < timer3_ms_tiempo THEN timer3_ms = timer3_ms + 1  'contador
  470.                 IF timer_base >= timer_base_tiempo THEN  'limita el timepo de ejecucion, cada timer_base_tiempo
  471.                         IF timer1_100ms < timer1_100ms_tiempo THEN timer1_100ms = timer1_100ms + 1  'contador
  472.                         IF timer2_100ms < timer2_100ms_tiempo THEN timer2_100ms = timer2_100ms + 1  'condtador
  473.                         IF timer3_100ms < timer3_100ms_tiempo THEN timer3_100ms = timer3_100ms + 1  'contador
  474.                         timer_base = 0  'reset a la base de tiempos
  475.                 Endif  '________________fin bases de tiempos
  476.         PIR1.TMR1IF = 0  'borra el flag de salto del tmr1
  477.         Endif
  478. '_________________Detecta tecla pulsada
  479.         IF s1 = 0 AND s1_on = 0 AND timer1_ms >= timer1_ms_tiempo THEN  'tecla S1
  480.                 s1_on = 1  'la tecla fue pulsada
  481.                 s2_on = 0  'la tecla s2 a pff
  482.                 IF s1 = 0 AND s2 = 0 THEN s2_on = 1  'S2
  483.                 timer1_ms = 0  'tiempo entre pulsacion y pulsacion
  484.         Endif
  485.         IF s2 = 0 AND s2_on = 0 AND timer3_ms >= timer3_ms_tiempo THEN  'tecla s2
  486.                 s2_on = 1  'la tecla fue pulsada
  487.                 s1_on = 0  'la tecla s1 a off
  488.                 IF s1 = 0 AND s2 = 0 THEN s1_on = 1  'S1
  489.                 timer3_ms = 0  'tiempo entre pulsacion y pulsacion
  490.         Endif
  491.         IF s1 = 0 THEN led_verde = 0  'mestra el estado de S1
  492.         IF s2 = 0 THEN led_amarillo = 0  'muestra el estado de S2
  493.         IF s1 = 1 THEN led_verde = 1  'mestra el estado de S1
  494.         IF s2 = 1 THEN led_amarillo = 1  'muestra el estado de S2
  495.         '________Fin detecta tecla pulsada
  496. RESUME  'activa las interrupciones y retorna el curso normal del programa, antes del salto
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #35 en: 08 de Diciembre de 2008, 17:14:38 »
Lo mismo, este tambien funciona en mi entrenadora.

Código: QBasic/QuickBASIC
  1. 'ADAPTADO PARA MI PLACA ENTRENADORA CON PIC16F877 By DOGFLU66
  2. '------------------------------------------------------------
  3.  
  4. 'ejemplo tomado del amigo xocas, modificado (gracias amigo)
  5. 'Pic 16f877A
  6.  
  7. Define CONF_WORD = 0x3f32
  8. Define CLOCK_FREQUENCY = 20
  9. '-------------------------------------Puertos del LCD-----------------------------------------------
  10. Define LCD_BITS = 8
  11. Define LCD_DREG = PORTB
  12. Define LCD_DBIT = 0
  13. Define LCD_RSREG = PORTC
  14. Define LCD_RSBIT = 0
  15. Define LCD_EREG = PORTC
  16. Define LCD_EBIT = 4
  17. Define LCD_RWREG = PORTC
  18. Define LCD_RWBIT = 1
  19. Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  20. Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  21. Define LCD_INITMS = 50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  22. Lcdinit  '-----------------------------------Puerto I2C-----------------------------------------------------
  23. Symbol sda = PORTC.2  'asignamos nombre al pin que hara de SDA del puerto I2C
  24. Symbol scl = PORTC.3  'asignamos nombre al pin que hara de SCL del puerto I2C
  25. '***********************************DEFINICION DE VARIABLES**************************************
  26. '--------------------------------------Variables Programa----------------------------------------
  27. DIM addr(7) AS Byte
  28. DIM DATA AS Byte
  29. DIM escribe AS Byte
  30. DIM sec AS Byte
  31. DIM min AS Byte
  32. DIM hour AS Byte
  33. DIM day AS Byte
  34. DIM daym AS Byte
  35. DIM month AS Byte
  36. DIM year AS Byte
  37. DIM d_hi AS Byte
  38. DIM d_lo AS Byte
  39.  
  40. AllDigital
  41.  
  42. WaitMs 1000  'bucle que escribe los datos iniciales en DS1307
  43.  
  44. FOR addr = 0 TO 6
  45.         escribe = LookUp(0x00, 0x15, 0x16, 0x01, 0x22, 0x06, 0x08), addr
  46.         I2CWrite sda, scl, 0xd0, addr, escribe  'escribe los datos al DS1307
  47. NEXT addr  'bucle para lectura de datos desde el DS1307
  48.  
  49. LOOP:
  50.         addr = 0
  51.         I2CRead sda, scl, 0xd1, addr, sec
  52.         addr = 1
  53.         I2CRead sda, scl, 0xd1, addr, min
  54.         addr = 2
  55.         I2CRead sda, scl, 0xd1, addr, hour
  56.         addr = 3
  57.         I2CRead sda, scl, 0xd1, addr, daym
  58.         addr = 4
  59.         I2CRead sda, scl, 0xd1, addr, day
  60.         addr = 5
  61.         I2CRead sda, scl, 0xd1, addr, month
  62.         addr = 6
  63.         I2CRead sda, scl, 0xd1, addr, year  'escribimos resultado en el lcd
  64.         Lcdcmdout LcdClear
  65.         Lcdcmdout LcdLine1Home
  66.         Lcdout " Hora: "
  67.         DATA = hour
  68.         GOSUB PRINT
  69.         Lcdout "."
  70.         DATA = min
  71.         GOSUB PRINT
  72.         Lcdout "."
  73.         DATA = sec
  74.         GOSUB PRINT
  75.         Lcdcmdout LcdLine2Home
  76.         Lcdout "Fecha: "
  77.         DATA = day
  78.         GOSUB PRINT
  79.         Lcdout "/"
  80.         DATA = month
  81.         GOSUB PRINT
  82.         Lcdout "/0", #year
  83.         WaitMs 100
  84. GOTO LOOP
  85. END  'subrutina de conversión                    
  86.         d_hi = DATA / 16
  87.         d_lo = DATA MOD 16
  88.         IF d_hi < 10 THEN
  89.                 Lcdout #d_hi
  90.         ELSE
  91.                 Lcdout "X"
  92.         Endif
  93.         IF d_lo < 10 THEN
  94.                 Lcdout #d_lo
  95.         ELSE
  96.                 Lcdout "X"
  97.         Endif
  98. RETURN
Saludos desde Granada, España.

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #36 en: 08 de Diciembre de 2008, 19:07:05 »
hola amigo Dogflu

al ultimo codigo puesto: le modifique este cachito de programa:

Código: FreeBasic
  1. '-------------------------------------Puertos del LCD-----------------------------------------------
  2. Define LCD_BITS = 8
  3. Define LCD_DREG = PORTB
  4. Define LCD_DBIT = 0
  5. Define LCD_RSREG = PORTC
  6. Define LCD_RSBIT = 0
  7. Define LCD_EREG = PORTC
  8. Define LCD_EBIT = 4
  9. Define LCD_RWREG = PORTC
  10. Define LCD_RWBIT = 1
  11. Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  12. Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  13. Define LCD_INITMS = 50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  14. Lcdinit  
  15. '-----------------------------------Puerto I2C-----------------------------------------------------
  16. Symbol sda = PORTC.2  'asignamos nombre al pin que hara de SDA del puerto I2C
  17. Symbol scl = PORTC.3  'asignamos nombre al pin que hara de SCL del puerto I2C
  18. '***********************************DEFINICION DE VARIABLES**************************************

 este cachito lo cambio por este otro:

Código: FreeBasic
  1. '-------------------------------------Puertos del LCD-----------------------------------------------
  2. Define LCD_BITS = 4 ' bit
  3. Define LCD_DREG = PORTB
  4. Define LCD_DBIT = 4 'empieza en el bit 4
  5. Define LCD_RSREG = PORTB
  6. Define LCD_RSBIT = 1
  7. Define LCD_EREG = PORTB
  8. Define LCD_EBIT = 2
  9. 'Define LCD_RWREG = PORTB ' no asigno lo pongo a masa en lcd y al aire en el pic
  10. 'Define LCD_RWBIT = 0 ' no asigno
  11. '-----------------------------------------
  12. Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
  13. Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
  14. Define LCD_INITMS = 50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
  15. Lcdinit  0 '
  16. '-----------------------------------Puerto I2C-----------------------------------------------------
  17. Symbol sda = PORTC.4  'asignamos nombre al pin que hara de SDA del puerto I2C
  18. Symbol scl = PORTC.3  'asignamos nombre al pin que hara de SCL del puerto I2C
  19. '***********************************DEFINICION DE VARIABLES**************************************

cambio en vez de 8 bit al lcd le pongo 4bit, desde el 4 al 7, el b7 del pic al db7 del lcd y esto mismo con el b6, b5,b4 el resto de pines del DB3 al DB0 del lcd estan al aire.

cambio el pin "rs" al puerto b1 y el "E" al puerto b2 el "rw" dejo al aire en el pic y a masa en el lcd,
el sda del pic "puerto c4" lo pongo con el  sda del ds1307 y el SCL del pic "puerto C3" al a patita del scl del ds1307.



podrias hacerme el favor de probarme este cachito de codigo con tu placa, en la mia es un PIC16F877A, voy a poner fotos de lo que se ve


un saludo

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #37 en: 08 de Diciembre de 2008, 22:24:30 »
Lo siento, pero mi placa entrenadora no permite que el LCD trabaje a 4Bit.

Cuando la construí para mi no tenia mucho sentido utilizar un PIC con tantos puertos y, conectarle el LCD a 4 BIT, ya que al trabajar a 4 BIT se vuelve más lento el LCD.

Tampoco puedo modificar los pin del I2C.

En fin, no sé que problema puedes tener con el LCD. Y también he caído en callejones que a primera vista no tenían salida, que al pasar el tiempo y no vislumbrar una solución me hacían echar la culpa del problema a cualquier cosa, pero te puedo asegurar que al final el error era mío, ya sea de programación o de hardware.

De esta manera es como conecto el LCD cuando trabajo a 4 BIT:



http://img166.imageshack.us/my.php?image=lcdpf1.png
« Última modificación: 08 de Diciembre de 2008, 22:42:02 por dogflu66 »
Saludos desde Granada, España.

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #38 en: 09 de Diciembre de 2008, 00:16:06 »
hola amigos.
creo haber descubierto que es lo que ha dado tantos quebraderos de cabeza,

yo le simule con proteus y todo era perfecto verifique con lo del amigo xocas, y me dio una corazonada, he cogido el modelo de xocas y lo simule en proteus iba muy bien le modifique cosas y lo probe en proteus y seguia bien cuando de repente me quede mirando las resistencias,resistencias pull-up. y me dio por sacarlas y volverlas a meter. ya habia probado de todo, y eso no podia ser, pero me equivocaba,

en el simulador hice lo mismo las desconecte, sorpresa, salia todo ceros eran las resistencias.
lo que antes eran ceros, ahora son xx, menos en los años que pone "0225".
algo hemos avanzado.

queria agradecer al amigos xocas y al amigo dogfluu por el tiempo que me han dedicado, es de agradecer esta ayuda.
gracias, muchas gracias.

ahora invetigare lo de las x haber que ocurre..

« Última modificación: 09 de Diciembre de 2008, 00:23:38 por pajaro »

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2312
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #39 en: 09 de Diciembre de 2008, 12:49:22 »
me alegra que vayas avanzando, al final sabrás más que nosotros sobre el i2c  8)

primero te dejo un enlace que ya trataba ese tema en proteus: http://www.todopic.com.ar/foros/index.php?topic=17608.msg118879#msg118879 y en el datasheet de ds1307 verás que sda es 'colector abierto' y por tanto necesita esa resistencia. en el caso de scl ya he leído que si y he leído que no... yo no lo sé pero siempre pongo ambas, y en la práctica suelo usar valores entre 4k7 y 10k para esas resistencias.

en el código que te puse puedes ver que si se 'desborda' algún valor (por ejemplo día 34 o mes 19) el lcd mostrará una 'x' indicándolo. repasa los valores que le estás dando al ds1307 y el orden de los mismos...

un saludo

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #40 en: 09 de Diciembre de 2008, 22:03:05 »
hola amigos
yo habia pensado en acotar esos valores,

para los meses que fuera 01,02,03,04,05,06,07,08,09,10,11,12, y que no hiciera nada con 1a,1b,1c,1d,1e,1f

pero no se muy bien como hace el ds1307, en el data dice que trabaja en BCD, binario codificado en decimal,
este ds1307, es un contador bcd o lo hace en binario.

Código: FreeBasic
  1. print:
  2. d_hi = data / 16
  3. d_lo = data Mod 16
  4. If d_hi < 10 Then
  5. Lcdout #d_hi
  6. Else
  7. Lcdout "X"
  8. Endif
  9. If d_lo < 10 Then
  10. Lcdout #d_lo
  11. Else
  12. Lcdout "X"
  13. Endif
  14. Return


data estará en binario, o en bcd o, en decimal, lo dividimos entre 16 para ponerlo en base 16.

la parte alta la comparamos con 10 pero ese 10 esta binario verdad.


voy ha investigar.

En el proteus va perfecto el funcionamientos con las resistencias pull-up pero en la realidad solo me saca "x " a que se deberá?

voy ha seguir investigando, la rutina de conversión.

un saludo

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #41 en: 10 de Diciembre de 2008, 00:08:05 »
hola
poco duro la alegria en casa de los pobres,
al parecer segun tenga puesto las resistencias pull-up, muestra una cosa diferente en el lcd,
sin ellas me muestra 00.00.00 pero con ellas me muestra 255255.255255.255255.

estara roto el rtc o el pic funciona como analogico digital
cambie las x por #hour o #min y da lo anterior todo xxxxx

excepto en el año que muestra 255

causa los mismo efectos, si en proteus le quitamos la union entre el scl al ds1307 con el pic.


He buscado en el foro sobre las resistencias pull-up y encontre esto muy representativo y con dibujos muy buenos.

http://www.todopic.com.ar/foros/index.php?topic=23978.0

en mi circuito no, revise todo a mi pensar parece estar bien, pero no funciona.
Cuado le pongo las resistencias pull-up hace cosas raras,
o se pone a 00 o se pone a 255 osea "x" , pero si le toco con el dedo la resistencia  varia el valor.
Pero eso solo pasa con la resistecia SCL que cosa mas rara?

sigo pensado que tiene los puertos como analogico digital, comparadores, u algo pero esto es muy raro, eso podrtia ser posible.
si es el puerto c4 y c3.

abajo puse una foto miren

un saludo




« Última modificación: 11 de Diciembre de 2008, 23:09:03 por pajaro »

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #42 en: 11 de Diciembre de 2008, 23:23:39 »
hola

Voy a poner el archivo .hex y el .bas así como el de proteus haber si alguien me puede decir que es lo que le ocurre,
estará roto algún componente el DS1307 o el pic, o no pondré las pull-up adecuadas,
 no tendré bien configurado el pic, o será algo mucho mas sencillo.

un saludo
« Última modificación: 11 de Diciembre de 2008, 23:25:53 por pajaro »

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #43 en: 13 de Diciembre de 2008, 21:34:53 »
El I2C se utiliza para ahorrar hilos en los buses de comunicaciones entre circuitos integrados de una misma placa, esta compuesto de dos hilos uno para Rx/Tx de datos y el otro como señal de sincronismo, si somos un poco quisquillosos son tres hilos, GND o masa o común o negativo como queramos llamarlo es el tercero, ya que las señales del bus van referenciadas a masa. El I2C es muy susceptible a las interferencias por lo que solo se suele utilizar para controlar circuitos integrados situados en la misma placa del circuito impreso, y en el caso de conectar otros circuitos integrados de otra placa al bus se emplea cables de muy corta longitud. Los circuitos integrados que llevan el I2C integrado no pueden suministrar nivel positivo a las líneas del bus, solo pueden suministrar nivel lógico cero. De esto se deduce que solo poseen dos estados uno de nivel lógico cero y el otro alta impedancia ya que internamente trabajan como colector abierto. De esto también se deduce que si queremos que funcione tenemos que suministrar siempre el nivel lógico alto nosotros, conectando sendas resistencias de polarización a positivo. El valor típico de estas resistencias es de 4K7 oh. Este valor puede disminuir si necesitamos reforzar la polarización de los hilos del bus. Un truco para saber si el bus esta bien en toda su extensión es quitar los circuitos integrados asociados a él y conectando la alimentación comprobar que cada zócalo de los circuitos integrados tipo I2C en sus respectivos hilos de dato y reloj les llega perfectamente la alimentación suministrada por las resistencias de polarización del mismo, normalmente 5V, después procederemos a cortocircuitar cada línea del bus a masa y comprobaremos que todo él queda a cero voltios.

A tener en cuenta cuando se usa emulación de I2C por alguno de los circuitos conectados al bus: Cuando alguno de los circuitos conectados al bus no utiliza modulo I2C interno, hay que tener un especial cuidado en que no suministre nivel lógico alto durante el arranque al bus I2C ya que se puede producir cortocircuito con algún otro circuito integrado que quiera utilizar el bus y provocando una posible rotura de alguno, a esto se le llama lucha de niveles. Este problema en teoría no se puede producir si se utilizan circuitos integrados genuinos de I2C integrado en ellos ya que se suponen que no pueden generar nunca el estado lógico alto.

Bien, llegados hasta aquí no te voy a dar ninguna recomendación Pajaro, solo voy decir lo que yo haría si estuviera en tu lugar:

1º Desmontar todo el circuito.
2º Montar un circuito compatible con los programas que ya se te dieron que funcionan.
3º Cables del bus lo mas cortos posibles y pegados a la placa incluyendo las resistencias de polarización del mismo, es decir colocarlas al lado de los integrados.
4º Colocar condensadores de desacople de alimentación a los circuitos integrados.
5º No dejar nunca una entrada sin polarización.
6º Una vez verificado que funciona ir haciendo las modificaciones pertinentes según las necesidades del circuito que estas construyendo.
« Última modificación: 13 de Diciembre de 2008, 22:31:07 por dogflu66 »
Saludos desde Granada, España.

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: DS1307 - Pic16F877A - Proteus 7 - PSI (Problemas)
« Respuesta #44 en: 15 de Diciembre de 2008, 00:34:05 »
hola
monte el mismo circuito pero con el 16f84A
y el problema era el mismo,
le puse a la salida de la onda cuadrada una resistencia de 10k
y me funciono, aparte de la de 4k7 del scl y sda.

Pero al cambair las resistencias al otro montaje
no me volvieron a funconar.

El problema esta ahi, por lo que sea, esas resistencias,
se han declarado en huega

no esta bien polarizado el bus?

si funcinona y le quitas energia y se la vuelves a poner
unas veces funciona y otras solo muestra 255.
Como es esto.


alguien sabe responderme

un laludo
« Última modificación: 15 de Diciembre de 2008, 00:58:12 por pajaro »


 

anything