Leer slave I2C en 16 bit
2 participantes
Página 1 de 1.
Leer slave I2C en 16 bit
de nuevo aqui para pedir ayuda.he creado un test de lectura de un pic mode slave con resolucion a 16 bit.es para leer los valores de una brujula digital que estoy construyendo con un IC HMC5883L.
este es el master con lectura a 8 bit:
y este es el code del slave:
como este code se bloca el programa:
este es el master con lectura a 8 bit:
- Código:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'CHIP
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#CHIP 16F876A,4
#CONFIG OSC=XT,WDT_OFF,PWRTE_ON,CP_OFF,DEBUG_OFF,WRT_OFF,CPD_OFF,LVP_OFF,BODEN_ON,BOREN_OFF
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'VARIABLES & DEFINE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
DIM Contador AS INTEGER
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'SUB & FUNCTION
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB Setup_I2C()
SSPSTAT=b'1100000'
SSPADD=b'00001001'
SSPCON2=0
SSPCON=b'00111000'
SET PIR1.SSPIF OFF
SET PIR2.BCLIF OFF
END SUB
SUB W_MSSP()
DO
LOOP UNTIL PIR1.SSPIF=1
PIR1.SSPIF=0
END SUB
SUB START
SET SSPCON2.SEN ON
W_MSSP()
END SUB
SUB RESTART
SET SSPCON2.RSEN ON
W_MSSP()
END SUB
SUB STOP
SET SSPCON2.PEN ON
W_MSSP()
END SUB
SUB I2C_ACK()
SET SSP1CON2.ACKDT OFF
SET SSP1CON2.ACKEN ON
W_MSSP()
END SUB
SUB I2C_Not_ACK()
SET SSP1CON2.ACKDT ON
SET SSP1CON2.ACKEN ON
W_MSSP()
END SUB
SUB Tx_I2C(SendByte AS BYTE)
SSPBUF=SendByte
W_MSSP()
DO
LOOP UNTIL SSPCON2.ACKSTAT=0
END SUB
FUNCTION I2C_Rx() AS BYTE
SSPCON2.RCEN=1
W_MSSP()
I2C_Rx=SSPBUF
END FUNCTION
SUB WRITE_Memory(ID_Address AS BYTE,Address AS WORD,Dato AS WORD)#NR
START()
Tx_I2C(ID_Address)
Tx_I2C(Address_H)
Tx_I2C(Address)
Tx_I2C(Dato)
STOP()
END SUB
SUB WRITE_Slave(IDAddress AS WORD,Dato AS WORD)#NR
START()
Tx_I2C(IDAddress)
Tx_I2C(Dato)
STOP()
END SUB
FUNCTION READ_Memoria(ID_Address AS WORD,Address AS WORD)
START()
Tx_I2C(ID_Address)
Tx_I2C(Address_H)
Tx_I2C(Address)
RESTART()
Tx_I2C(ID_Address+1)
READ_Memoria=I2C_Rx()
I2C_Not_ACK()
STOP()
END FUNCTION
FUNCTION READ_Slave(ID_Address AS WORD,Comando AS BYTE)
START()
Tx_I2C(ID_Address)
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address+1)
EPWrite 0x00,I2C_Rx()
I2C_Not_ACK()
STOP()
END FUNCTION
Inicio:
TRISA=b'000000'
TRISB=b'00000000'
TRISC=b'00011000'
PORTA=b'000000'
PORTB=b'00000000'
PORTC=b'00000000'
INTCON=b'00000000'
CVRCON=b'00000000'
CCP1CON=b'00000000'
CCP2CON=b'00000000'
ADCON0=b'00000000'
ADCON1=b'10000110'
Setup_I2C()
WAIT 1 s
FOR Contador=0 TO 255
WRITE_Memory(0xA0,Contador,Contador)
WRITE_Slave(0xA4,Contador)
WRITE_Slave(0xA6,Contador)
PulseOut PORTC.5,100 ms
WAIT 100 ms
NEXT Contador
WAIT 1 s
READ_Slave(0xA6,0xF1)
PulseOut PORTC.5,1 s
y este es el code del slave:
- Código:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'CHIP
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#CHIP 16F88,4
#CONFIG OSC=XT,MCLR_ON,CP_OFF,CCP1_RB3,DEBUG_OFF,WRT_PROTECT_OFF
#CONFIG CPD_OFF,LVP_OFF,BODEN_ON,PWRTE_ON,WDT_OFF,IESO_OFF,FCMEN_OFF
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INTERRUPT
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Interrupt SSP1Ready call I2C_Interrupt
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'VARIABLES
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
DIM InByte,Clear_Address,Contador,Valor(2),StatusSSP AS BYTE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'SUB AND FUNCTION
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SUB I2C_Interrupt()#NR
IF PIR1.SSPIF=1 THEN
IF SSPSTAT.DA THEN 'MASTER QUIERE ESCRIBIR EL DATO
InByte=SSPBUF
EPWrite SSPBUF,SSPBUF
END IF
IF SSPSTAT.R_W THEN 'MASTER QUIERE LEER EL DATO
IF InByte=0xF1 THEN
SSPBUF=Valor(Contador)
Contador+=1
IF Contador>1 THEN Contador=0:InByte=0x00
END IF
END IF
END IF
Clear_Address=SSPBUF
PIR1.SSPIF=0
SSPCON.CKP=1
END IF
END SUB
INICIO:
TRISA=b'000000'
TRISB=b'00010010'
PORTA=b'000000'
PORTB=b'00000000'
INTCON=b'11000000'
SSPADD=0xA6
SSPSTAT=b'00000000'
SSPCON=b'00110110'
PIE1.SSPIE=1
CVRCON=b'00000000'
CMCON=b'00000111'
CCP1CON=b'00000000'
ANSEL=b'00000000'
ADCON0=b'00000000'
ADCON1=b'10000000'
Contador=0
Valor(0)=0xAA
Valor(1)=0xAB
InByte=0x00
DO
''''''''''''''''''''''
LOOP
como este code se bloca el programa:
- Código:
.
.
FUNCTION READ_Slave(ID_Address AS WORD,Comando AS BYTE)
START()
Tx_I2C(ID_Address)
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address+1)
EPWrite 0x00,I2C_Rx()
I2C_ACK()
EPWrite 0x01,I2C_Rx()
I2C_Not_ACK()
STOP()
END FUNCTION
.
.
alejandro- Participante Activo
- Mensajes : 87
Fecha de inscripción : 12/02/2009
Re: Leer slave I2C en 16 bit
Hola Alejandro.
Prueba esto:
Creo que asi deberia funcionar.
Prueba esto:
- Código:
...
Tx_I2C(ID_Address) ' Manda byte bajo
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address_H) ' Manda byte alto
...
Creo que asi deberia funcionar.
Re: Leer slave I2C en 16 bit
grazias pikitin por la respuesta asi veloz.
però el problema no es en trasmicion(no es una eeprom 24lc),es quando el master(16F876A) tendrià que recibir dos byte (un MSB y un LSB) del slave(16F88).no se si es un problema en el code del master o en aquel del slave.
la procedura serià asi:
2)master envià el byte de ID slave en escritura(xxxxxxx0)
3)envia el byte de address de la region de la memoria que desea leer(o byte de comando si es un pic)
4)envia un bit di restart o reinicio
5)master envià el byte de ID slave en lectura(xxxxxxx1)
6)envia el bit pedido de lectura del dato en el address(o respuesta del comando) del punto 3 y lo escribe en la eeprom interna al addresss 0x00
7)envia el not_ack + el bit habilitaciòn del ack(o sea que no quiero otros datos del slave)
8)envia el bit de stop(fin transmicion)
esto funciona.el problema es quando el master pide màs de un byte del slave:
2)master envià el byte de ID slave en escritura(xxxxxxx0)
3)envia el byte de address de la region de la memoria que desea leer(o byte de comando si es un pic)
4)envia un bit di restart o reinicio
5)master envià el byte de ID slave en lectura(xxxxxxx1)
6)envia el bit pedido de lectura del primer dato en el address(o respuesta del comando) del punto 3 y lo escribe en la eeprom interna al addresss 0x00
7)envia el ack + el bit habilitaciòn del ack(o sea que el master espera otro dato del slave)
8)envia el bit pedido de lectura del segundo dato en el address(o respuesta del comando) del punto 3 y lo escribe en la eeprom interna al addresss 0x01
9)envia el not_ack + el bit habilitaciòn del ack(o sea que no quiero otros datos del slave)
10)envia el bit de stop(fin transmicion)
esto no funciona.el programa se bloca.donde me equivoco
però el problema no es en trasmicion(no es una eeprom 24lc),es quando el master(16F876A) tendrià que recibir dos byte (un MSB y un LSB) del slave(16F88).no se si es un problema en el code del master o en aquel del slave.
la procedura serià asi:
- Código:
FUNCTION READ_Slave(ID_Address AS WORD,Comando AS BYTE)
START()
Tx_I2C(ID_Address)
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address+1)
EPWrite 0x00,I2C_Rx()
I2C_Not_ACK()
STOP()
END FUNCTION
2)master envià el byte de ID slave en escritura(xxxxxxx0)
3)envia el byte de address de la region de la memoria que desea leer(o byte de comando si es un pic)
4)envia un bit di restart o reinicio
5)master envià el byte de ID slave en lectura(xxxxxxx1)
6)envia el bit pedido de lectura del dato en el address(o respuesta del comando) del punto 3 y lo escribe en la eeprom interna al addresss 0x00
7)envia el not_ack + el bit habilitaciòn del ack(o sea que no quiero otros datos del slave)
8)envia el bit de stop(fin transmicion)
esto funciona.el problema es quando el master pide màs de un byte del slave:
- Código:
FUNCTION READ_Slave(ID_Address AS WORD,Comando AS BYTE)
START()
Tx_I2C(ID_Address)
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address+1)
EPWrite 0x00,I2C_Rx()
I2C_ACK()
EPWrite 0x01,I2C_Rx()
I2C_Not_ACK()
STOP()
END FUNCTION
2)master envià el byte de ID slave en escritura(xxxxxxx0)
3)envia el byte de address de la region de la memoria que desea leer(o byte de comando si es un pic)
4)envia un bit di restart o reinicio
5)master envià el byte de ID slave en lectura(xxxxxxx1)
6)envia el bit pedido de lectura del primer dato en el address(o respuesta del comando) del punto 3 y lo escribe en la eeprom interna al addresss 0x00
7)envia el ack + el bit habilitaciòn del ack(o sea que el master espera otro dato del slave)
8)envia el bit pedido de lectura del segundo dato en el address(o respuesta del comando) del punto 3 y lo escribe en la eeprom interna al addresss 0x01
9)envia el not_ack + el bit habilitaciòn del ack(o sea que no quiero otros datos del slave)
10)envia el bit de stop(fin transmicion)
esto no funciona.el programa se bloca.donde me equivoco
alejandro- Participante Activo
- Mensajes : 87
Fecha de inscripción : 12/02/2009
Re: Leer slave I2C en 16 bit
ok.el problema principal era con el code del slave(la gestiòn del interrupt).
esta es la version de la sub de gestiòn de lectura del slave:
PD:me hago una linda libreria personal (por gusto no màs)
esta es la version de la sub de gestiòn de lectura del slave:
- Código:
SUB Setup_I2C()#NR
SSPSTAT=b'1100000'
'el valor es 9 porque el bus trabaja a 100k con quarzo de 4mhz.se calcula ((FOSC/(4*FBus))-1
SSPADD=b'00001001'
SSPCON2=0
SSPCON=b'00111000'
SET PIR1.SSPIF OFF
SET PIR2.BCLIF OFF
END SUB
SUB START()#NR
SET SSPCON2.SEN ON
W_MSSP()
END SUB
SUB RESTART()#NR
SET SSPCON2.RSEN ON
W_MSSP()
END SUB
SUB STOP()#NR
SET SSPCON2.PEN ON
W_MSSP()
END SUB
SUB Tx_I2C(SendByte AS BYTE)#NR
SSPBUF=SendByte
W_MSSP()
DO
LOOP UNTIL SSPCON2.ACKSTAT=0
END SUB
SUB W_MSSP()#NR
DO
LOOP UNTIL PIR1.SSPIF=1
PIR1.SSPIF=0
END SUB
FUNCTION I2C_Rx() AS BYTE
SSPCON2.RCEN=1
W_MSSP()
I2C_Rx=SSPBUF
SET SSPCON2.ACKEN ON
W_MSSP()
END FUNCTION
FUNCTION READ_Memoria_24LCXXX(ID_Address AS WORD,Address AS WORD) AS BYTE
START()
Tx_I2C(ID_Address)
Tx_I2C(Address_H)
Tx_I2C(Address)
RESTART()
Tx_I2C(ID_Address+1)
READ_Memoria=I2C_Rx()
I2C_Not_ACK()
STOP()
END FUNCTION
FUNCTION READ_Slave_8BIT(ID_Address AS WORD,Comando AS BYTE) AS BYTE
START()
Tx_I2C(ID_Address)
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address+1)
SET SSPCON2.ACKDT ON
READ_Slave_8BIT=I2C_Rx()
STOP()
END FUNCTION
FUNCTION READ_Slave_16BIT(ID_Address AS WORD,Comando AS BYTE) AS WORD
DIM H_Byte,L_Byte AS BYTE
START()
Tx_I2C(ID_Address)
Tx_I2C(Comando)
RESTART()
Tx_I2C(ID_Address+1)
SET SSPCON2.ACKDT OFF
H_Byte=I2C_Rx()
SET SSPCON2.ACKDT ON
L_Byte=I2C_Rx()
STOP()
READ_Slave_16BIT=L_Byte
READ_Slave_16BIT_H=H_Byte
END FUNCTION
PD:me hago una linda libreria personal (por gusto no màs)
alejandro- Participante Activo
- Mensajes : 87
Fecha de inscripción : 12/02/2009
Página 1 de 1.
Permisos de este foro:
No puedes responder a temas en este foro.