Autor Tema: I2C con XC8: Pin SCL como salida?  (Leído 7619 veces)

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

Desconectado Loudness

  • PIC16
  • ***
  • Mensajes: 147
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #15 en: 05 de Junio de 2018, 04:37:24 »
Gracias de nuevo, no sabes como te agradezco la explicacion.

Por fin he entendido el i2c por soft y por hard. Hasta ahora siempre habia pensado que la forma de soft era la unica que existia :oops:.
Jamas habia visto una explicacion tan buena como la tuya ((:-))

.. y aun asi no me funciona :shock:.

Como quiero utilizar el MSSP1 he adaptado todos los registros necesarios (SSPCON -> SSP1CON, etc).
He metido en el main este trozo de codigo que me pasaste para ver que tal:

Código: [Seleccionar]
   while(1){                                    //bucle infinito
       Send_I2C_StartBit();               // start
       Send_I2C_Data(0x00);            // control byte con R/W bit=0
       Send_I2C_Data(0x01);            // direccion alta de la memoria
       Send_I2C_Data(0x23);            // direccion baja de la memoria
       Send_I2C_Data(0x50);            // dato a enviar
       Send_I2C_StopBit();               // stop
       __delay_ms(100);                  // retraso
            }

Y al simular en Proteus sale este pantallazo


* Error 180605.JPG
(186.3 kB, 795x609 - visto 427 veces)


Parece que recibe la condicion de start pero luego salen miles de mensajes de error y no hace nada mas :?....

Buscando por internet, parece que hay gente que le pasa este error cuando intenta escribir cadenas de datos muy largas, pero creo que este no es el caso porque es solo un dato (0x50)?...

Estudiando c ya he conseguido hacer funcionar los ADC, el DAC, PWM, eeprom interna... pero el i2c se me esta resistiendo sobremanera....
Soy el unico o no es tan facil como parece?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #16 en: 05 de Junio de 2018, 09:48:54 »
Primero que nada, pasa el programa  (e imagen del esquema) ahora como lo tenes ( o luego de haber realizado las correcciones).

Segundo, tenes que recordar que no solo estas peleando con el programar, sino tambien con el simulador. Si observas el simulador solo admite algunas cosas y no todas. Ya el primer warning te dice que solo soporta algunas cosas y utiliza las funciones de los viejos PIC16 (que no deberian haber cambiado tanto).

Y esos "warnings" es porque nunca cambia el registro de acceso indirecto ( FSR ) de valor, ni siquiera se porque arrancan en FFFF ya que este error comienza desde el Contador de Programa en 0x5, a no ser que en esos valores cargue el FSR en FFFF, y luego cada instruccion que se ejecuta, que tal ves ni siquiera utilice el INDF, aparece el warning.

Código: [Seleccionar]
       Send_I2C_Data(0x00);            // control byte con R/W bit=0
Como te comente (lo que pide la memoria) en ese punto tenes que enviar la direccion de la eeprom. Esto no lo dije pero la direccion esta formada por 1010 + 3 bits configurables en los pines A2 a A0. Suponiendo que tenes todos los pines en 0. Entonces la direccion es 1010000,  pero son 7 bits y necesitariamos 1 bit mas que es el de R/W.
Los bits estarian formados asi:

7 bits de direccion - 1 de R/W

Y si observas esos 7 bits estan como los de mayor peso, por eso o le aplicas un shift a la izquierda, o directamente lo cargas como si fueran 8 bits ya corridos. Si lo queres ver de forma grafica:

http://ww1.microchip.com/downloads/en/DeviceDoc/21203M.pdf (Pagina 9)

Código: C
  1. #define EEPROM_ADDRESS (0b10100000)  // Valor ya con el shift un lugar a la izquierda
  2. #define WRITE (0)
  3. #define READ (1)

Ahora si usas:

Código: C
  1. Send_I2C_Data(EEPROM_ADDRESS | WRITE);

Si no pones correctamente la dirección, la memoria al leer la dirección y ver que no es la de el (recorda que de un mismo bus podes colgar muchas cosas), procede a omitir todo lo que le llegue hasta el proximo STOP.
« Última modificación: 05 de Junio de 2018, 10:20:50 por KILLERJC »

Desconectado Loudness

  • PIC16
  • ***
  • Mensajes: 147
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #17 en: 05 de Junio de 2018, 10:39:17 »
Gracias por tu tiempo

Primero que nada, pasa el programa  (e imagen del esquema) ahora como lo tenes

Aqui te envio el programa (archivo main y libreria para i2c) y tambien el archivo de proteus que estoy utilizando.
He intentado variar varias cosas pero al final se ha quedado casi como estaba.
* I2C 180605.zip
(23.74 kB - descargado 185 veces)


Segundo, tenes que recordar que no solo estas peleando con el programar, sino tambien con el simulador.

Lo bueno seria probar en un protoboard para saber si de verdad funciona o no en la realidad.
Ya me ha pasado otra vez que un cogido que no iba en proteus funcionaba bien en el protoboard.

Código: C
  1. #define EEPROM_ADDRESS (0b10100000)  // Valor ya con el shift un lugar a la izquierda
  2. #define WRITE (0)
  3. #define READ (1)

Ahora si usas:

Código: C
  1. Send_I2C_Data(EEPROM_ADDRESS | WRITE);

Si no pones correctamente la dirección, la memoria al leer la dirección y ver que no es la de el (recorda que de un mismo bus podes colgar muchas cosas), procede a omitir todo lo que le llegue hasta el proximo STOP.

Tambien he anadido esta parte pero sigue igual...

Que estara pasando? :?
« Última modificación: 05 de Junio de 2018, 10:47:44 por Loudness »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #18 en: 05 de Junio de 2018, 12:39:07 »
En Send_I2C_StartBit tenes la instruccion:

Código: C
  1. while(!SSP1CON2bits.SEN);

Pienso que deberias quitarla, el flag deberia suficiente como para indicarte que la operacion de Start del I2C ya termino. Es mas ese bit, que es el que pones a 1 para iniciar el START, al momento de terminarse, se pone en 0 por hardware (el mismo modulo), por ende queda encerrado en ese while ahi para siempre. Del datasheet:

Citar
bit 0 SEN: Start Condition Enable bit(1)
In Master mode:
1 = Initiate Start condition on SDAx and SCLx pins. Automatically cleared by hardware

La funcion de StopBit tambien tiene lo mismo. Asi que vas a tener que sacar el ultimo while.

No poseo Proteus en el trabajo como para probarlo, si llego a casa y tengo tiempo lo veo

Desconectado Loudness

  • PIC16
  • ***
  • Mensajes: 147
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #19 en: 05 de Junio de 2018, 21:42:02 »
Gracias de nuevo

En Send_I2C_StartBit tenes la instruccion:

Código: C
  1. while(!SSP1CON2bits.SEN);

Pienso que deberias quitarla, el flag deberia suficiente como para indicarte que la operacion de Start del I2C ya termino.

Estuve probando varios tipos y al final se quedaron los dos while :lol:.
Ya lo elimino.

Revisando de nuevo el programa y segun este esquema

Citar
24.6.6.4 Typical transmit sequence:
1. The user generates a Start condition by setting the SEN bit of the SSPxCON2 register.
2. SSPxIF is set by hardware on completion of the Start.
3. SSPxIF is cleared by software.
4. The MSSPx module will wait the required start time before any other operation takes place.
5. The user loads the SSPxBUF with the slave address to transmit.
6. Address is shifted out the SDAx pin until all eight bits are transmitted. Transmission begins as soon as SSPxBUF is written to.
7. The MSSPx module shifts in the ACK bit from the slave device and writes its value into the ACKSTAT bit of the SSPxCON2 register.
8. The MSSPx module generates an interrupt at the end of the ninth clock cycle by setting the SSPxIF bit.
9. The user loads the SSPxBUF with eight bits of data.
10. Data is shifted out the SDAx pin until all eight bits are transmitted.
11. The MSSPx module shifts in the ACK bit from the slave device and writes its value into the ACKSTAT bit of the SSPxCON2 register.
12. Steps 8-11 are repeated for all transmitted data bytes.
13. The user generates a Stop or Restart condition by setting the PEN or RSEN bits of the SSPxCON2 register. Interrupt is generated once the Stop/Restart condition is complete

en el paso 7 habla sobre el ACK pero en mi codigo no estoy teniendo en cuenta este bit.
No se si tiene que ver con este problema (creo que no) pero voy a investigar un poco sobre el tema.



Desconectado Loudness

  • PIC16
  • ***
  • Mensajes: 147
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #20 en: 08 de Junio de 2018, 10:44:45 »
Llevo unos dias sin escribir pero sigo con el tema y, por fin, parece que he tenido algun avance.
Os lo cuento lo mas breve posible:

Para empezar he dejado temporalmente de lado el PIC16F1947 y he empezado a investigar con el PIC16F877A, que le conozco mucho mas.

Al principio me salia la msima cadenas de mensajes que antes  :shock::

"Indirection address [0xFFFF] for INDF register is outside of writable memory..."

Solucion: declarar una rutina de interrucpion, aunque no la utilize, algo asi

Código: [Seleccionar]
void interrupt isr (void)
{
    if(PIR1bits.SSPIF == 1)
    {
        PIR1bits.SSPIF = 0;
    }
    else
    {
    }
}

Al poner esto desaparecion los errores. El codigo no podia regresar de un retfie y por eso salian esos errores??

Despues de esto y cambiando la libreria y el main aqui y alla (muy largo para explicarlo, luego os cuelgo el codigo) el codigo iniciaba e iba hasta la condicion de start pero luego nada mas :5].

Solucion: poner retardos entre las operaciones de start_bit, send_data.... entre cada una sin falta un retraso.
Y el codigo empezo a funcionar, eso si, en proteus. En circuito real lo probare la semana que viene o la siguiente, depende del trabajo...pero tiene buena pinta :)

Todavia no se si funciona en realidad y si lo hace me queda hacerlo funcionar en el 16F1947, es decir, todavia me queda camino pero por lo menos, despues de semanas de estudio, he empezado a ver el final del tunel.

Si avanzo mas os mantendre informados.

Gracias a todos por vuestra ayuda.
* i2c_eng877.c
(6.45 kB - descargado 208 veces)

* i2c_eng877.h
(0.74 kB - descargado 189 veces)

* Practicas_877a_1.production.hex
(2.36 kB - descargado 189 veces)

* main.c
(1.95 kB - descargado 190 veces)

« Última modificación: 08 de Junio de 2018, 10:57:04 por Loudness »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #21 en: 08 de Junio de 2018, 12:57:57 »
Felicidades por el avance.

Que raro que te exija una funcion de interrupcion cuando uno no la habilita.

Desconectado electroipod

  • PIC16
  • ***
  • Mensajes: 166
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #22 en: 09 de Junio de 2018, 17:39:32 »
en esta página hay buena información de como usar el i2c.
http://microcontroladores-mrelberni.com/i2c-pic-comunicacion-serial/

Desconectado Loudness

  • PIC16
  • ***
  • Mensajes: 147
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #23 en: 10 de Junio de 2018, 09:38:01 »
electroipod: Gracias por el link. Muy bueno con muy detallada informacion ((:-))

Por cierto, he visto que estas trabajando con memorias i2c y pic18f.
Espero que tengas mas suerte que yo porque de momento no lo llevo bastante bien jejeje.

Saludos.



Desconectado Loudness

  • PIC16
  • ***
  • Mensajes: 147
Re:I2C con XC8: Pin SCL como salida?
« Respuesta #24 en: 18 de Junio de 2018, 23:02:01 »
Hola de nuevo.

Os cuento que he tenido acceso (por fin!!) a un PIC16F877A y he podido probar el I2C.
He modificado un poco el programa que colgue anteriormente para que despues de escribir un numero en la memoria, lo lea de nuevo, saque el dato por el LCD y aumente el numero para empezar de nuevo.

Y parece que funciona :-/

Ahora solo queda adaptarlo y probarlo para un pic de la serie 16f1, pero eso me llevara mas tiempo asi que de momento pongo el tema como solucionado.

Muchas gracias a todos, en especial a KILLERJC, por su ayuda.

Cuelgo el programa por si le sirve de guia a alguien.

* I2C.zip
(3.78 kB - descargado 202 veces)




 

anything