Microcontroladores PIC en Linux.
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

Leer slave I2C en 16 bit

2 participantes

Ir abajo

Leer slave I2C en 16 bit Empty Leer slave I2C en 16 bit

Mensaje por alejandro Vie 25 Mayo 2012 - 22:17

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:
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                   
puedo leer un byte y memorisarlo en la Eeprom del Master.però si modifico el code para poder leer con una resolucion de 16 bit
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
.
.
se aceptan ideas de todo tipo Very Happy
alejandro
alejandro
Participante Activo
Participante Activo

Mensajes : 87
Fecha de inscripción : 12/02/2009

Volver arriba Ir abajo

Leer slave I2C en 16 bit Empty Re: Leer slave I2C en 16 bit

Mensaje por Pikitin Sáb 26 Mayo 2012 - 15:49

Hola Alejandro.

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.

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Leer slave I2C en 16 bit Empty Re: Leer slave I2C en 16 bit

Mensaje por alejandro Sáb 26 Mayo 2012 - 20:01

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:
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
1)master envia un bit de start(inicio trasmicion,todos los slave estàn atentos)
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
1)master envia un bit de start(inicio trasmicion,todos los slave estàn atentos)
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 Shocked
alejandro
alejandro
Participante Activo
Participante Activo

Mensajes : 87
Fecha de inscripción : 12/02/2009

Volver arriba Ir abajo

Leer slave I2C en 16 bit Empty Re: Leer slave I2C en 16 bit

Mensaje por alejandro Dom 27 Mayo 2012 - 10:15

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:
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
ahora funcionan bien,grazias a todos.grande GCBasic cheers

PD:me hago una linda libreria personal (por gusto no màs) Cool
alejandro
alejandro
Participante Activo
Participante Activo

Mensajes : 87
Fecha de inscripción : 12/02/2009

Volver arriba Ir abajo

Leer slave I2C en 16 bit Empty Re: Leer slave I2C en 16 bit

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.