El codigo:
'***************** Placa Entrenadora (PIC EBadic) ***************************************
'NOMBRE: 16F88_Pic_EBasic_EJEMPLO_28
'Descripción: TEST DE LA PLACA EBasic_I2C (Led y 24LC04B)
'Micro: PIC16F88 / 8mhz reloj interno
'Fecha/Autor: 30/12/07, 29/7/07, By COS, PSI v7.41
'Versión: 1.1
'Se completa la función para que lea o escriba en todos los bloques de la memoria I2C
'Esta memoria solo tiene dos bloques y cada uno de ellos tiene 256 posiciones de 1 byte
'La funcion los maneja como si de un único bloque de 512 bytes se tratara.
'Multiplicando la longuitud de 1 bloque por el numero de bloques es igual
'a la capasidad maxima de la memoria, contemplada como si de su estructura interna
'estuviera compuesta de un unico bloque (256x2)=512 y direccion maxima 511 bytes
'ya que la direccion primera comienza en 0.
'Version: 1.0
'Solo escribe o lee en el bloque "0" de la memoria
'*****************************************************************************************
Define CONF_WORD = 0x2f50 'Configuración de bits (fuses)
Define CONF_WORD_2 = 0x3ffc 'Configuración de bits (fuses)
Define CLOCK_FREQUENCY = 8 'Frecuencia del reloj en Mhz
'Define SIMULATION_WAITMS_VALUE = 1 'Hace que se ignoren los tiempos de los WaitMs
'-------------------------------------Puertos del LCD-------------------------------------
Define LCD_BITS = 4 'Indicamos que el bus de datos del lcd sera de 4bit
Define LCD_DREG = PORTA 'Bus de datos sera el puerto A
Define LCD_DBIT = 0 'Bus de datos seran los 4 bit menos significativos del puerto A
Define LCD_RSREG = PORTB 'Bit de control RS sera del puerto B
Define LCD_RSBIT = 7 'RB7 como RS
Define LCD_EREG = PORTB 'Bit de control E sera del puerto B
Define LCD_EBIT = 6 'RB6 como E
Define LCD_COMMANDUS = 2000 'Tiempo de espera despues de ejecutar un comando del lcd en uSeg.
Define LCD_DATAUS = 50 'Tiempo de espera despues de enviar un dato al LCD en uSeg.
Define LCD_INITMS = 50 'Tiempo de espera despues de inicializar el Display.
'*********************************************************************************
'------------------------------------Definicion de puertos------------------------------------------
AllDigital 'los pin I/O digitales
'ANSEL = %00010000 'los pin I/O digitales y RA4 analogico
CMCON = 0x07 'comparador a off
OSCCON = 0x7e 'set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISA = 0xff 'Puerto A como entradas
TRISB = 0xff 'puerto B como entradas
'TRISA.4 = 1 'como entrada (RA4, adc)
'TRISA.6 = 1 'como entrada (RA6, tecla S1)
'TRISA.5 = 1 'como entrada (RA5, tecla S2)
TRISB.3 = 0 'como salida RB3
TRISA.7 = 0 'como salida RA7
TRISB.0 = 0 'como salida RB0
TRISA.4 = 0 'como salida RA4
PORTB.3 = 1 'luz lcd a on (RB3)
PORTA.7 = 1 'led amarillo a off (RA7), negado
PORTB.0 = 1 'led verde a off (RB0), negado
PORTA.4 = 0 'led EBbasic_I2C a off (RA4)
'------------------------------------Inicio--------------------------------------------
'------------------------------Reasignacion de nombres----------------------
Symbol sda = RB1 'asignamos nombre al pin que hara de SDA del puerto I2C
Symbol scl = RB4 'asignamos nombre al pin que hara de SCL del puerto I2C
Symbol led_amarillo = RA7 'led amarillo
Symbol led_verde = RB0 'led verde
Symbol luz_lcd = RB3 'iluminacion del lcd
Symbol s1 = RA6 'tecla S1
Symbol s2 = RA5 'tecla S2
'--------------------------------variables generales-----------------------------------------------
Dim addr As Word 'direccion I2C
Dim dato As Byte 'valor a escribir en el I2C
Dim data As Word 'lectura dato I2C, data.HB = 1 = error de escritura, data.LB = dato i2c
'------------------------------------asignacion de valores a las variables--------------------------
dato = 0 'inicializa dato
'--------------------------------------------------------------------------------------
Lcdinit 'inicializa el LCD sin cursor
WaitMs 100 'pausa de 0.1Seg.
Lcdout "Test P. EB_I2C" 'Imprime el texto en el LCD
Lcdcmdout LcdLine2Home
Lcdout "Version 1.1"
WaitMs 5000 'pausa de 5Seg.
'--------------------------------Rutina Programa---------------------------------------
main:
Lcdcmdout LcdClear 'borra lcd
For addr = 0 To 511 'addr tomara los valores desde 0 hasta 511, bucle
Lcdcmdout LcdLine1Home 'cursor linea 1 y principio
Lcdout "Wr: ad.", #addr, " d.", #dato, " " '#addr 'se escribe en el lcd
data = d_e2prom(addr, dato, 0) 'llama a la funcion R/W del I2C en modo escritura
Lcdcmdout LcdLine2Home 'cursor linea 2 y principio
Lcdout "Read: ", #data.LB, " " 'se escribe en el lcd
WaitMs 100 'se espera 100mSeg.
If data.HB = 1 Then 'bit de error si esta a 1
Lcdcmdout LcdClear 'borra el lcd
Lcdout "Error: " 'imprime en el display
Lcdcmdout LcdLine2Home 'cursor al principio de la linea 2
Lcdout "Wr: ", #dato, " Rd:", #data.LB, " " 'imprime en el display
WaitMs 500 'se hace una pausa de 500mSeg.
Endif 'cierra el if
dato = dato + 1 'incrementa dato, se tiene en cuenta que cuando desborda comienza en 0.
Next addr 'cierra el bucle for
End
'------------------------------Subrutinas y funciones ----------------------------------------
'Funcion para el manejo de la E2Prom y Led indicador R/W
'La funcion devuelve un numero tipo Word, en el que el byte menos significativo es
'el dato leido y el byte mas significativo indica si hubo error en la escritura, error=1
'e2p_addr.15...12, selecciona el dispositivo en el bus I2C
'e2p_addr.11...09, selecciona la pagina o bloque de la memoria
'e2p_addr.8, selecciona si la operacion sera de lectura o escritura
'e2p_addr.LB, selecciona la posicion a escribir dentro del bloque de momoria seleccionado
'e2p_data, dato a escribir en la posicion indicada por e2p_addr
'e2p_rw, indica a la funcion si la operacion sera de lectura (=1) o escritura (=0)
Function d_e2prom(e2p_addr As Word, e2p_data As Byte, e2p_rw As Byte) As Word
'0xa0 (1010b) direccion de la memoria I2C, todos los pin de configuracion a cero
e2p_addr.15 = 1 'direccion o nombre del dispositivo en el bus I2C, bit mas significativo
e2p_addr.14 = 0 '...
e2p_addr.13 = 1 '...
e2p_addr.12 = 0 '..., bit menos significativo
e2p_addr.11 = e2p_addr.10 'selecciona la pagina de la memoria I2C, bit mas significativo
e2p_addr.10 = e2p_addr.9 '...
e2p_addr.9 = e2p_addr.8 '..., bit menos significativo
e2p_addr.8 = 0 'modo escritura, indiferente ya que lo controla directamente I2CWrite
RA4 = 1 'activa el led de la placa EBasic_I2C, actividad
If e2p_rw = 0 Then 'permite el modo escritura
I2CWrite RB1, RB4, e2p_addr.HB, e2p_addr.LB, e2p_data 'escribe en el I2C
d_e2prom.HB = 1 'registra posible error si no se borra posteriormente
WaitMs 5 'pausa para que el chip termine la escritura, tiempo indicado en el datasheet
Endif
e2p_addr.8 = 1 'modo lectura, indiferente ya que lo controla directamente I2CRead
I2CRead RB1, RB4, e2p_addr.HB, e2p_addr.LB, d_e2prom.LB 'lee en el puerto I2C
If d_e2prom.LB = e2p_data And e2p_rw = 0 Then 'solo se ejecuta si hubo ciclo de escritura
d_e2prom.HB = 0 'borra el flag de error
Endif
RA4 = 0 'apaga led placa EB_I2C, actividad
End Function
PD:
Donde decia "55. TRISA = 0xff 'Puerto A como salidas"
Ahora dice "55. TRISA = 0xff 'Puerto A como entradas"
Donde decia "56. TRISB = 0xff 'Puerto B como salidas"
Ahora dice "56. TRISB = 0xff 'Puerto B como entradas"