Autor Tema: Problema con spi_write(var)  (Leído 4921 veces)

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

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Problema con spi_write(var)
« en: 15 de Agosto de 2010, 06:03:59 »
Hola!!

Soy nuevo en esto del CCS y en la comunicacion por SPI y me ha surgido un problema que no entiendo y no logro resolver.

En el siguiente código:
Código: [Seleccionar]
#INCLUDE <16F88.h>
#FUSES XT,NOWDT
#USE delay (clock=8M)
#USE fast_io(A)
#USE fast_io(B)
#define SS PIN_B5


//PROGRAMA PRINCIPAL
void main(){

   int8 dato=0;
  
   set_tris_a(0b00000001); //Configuración I/O
   set_tris_b(0b00000010);
   output_high(SS);
  
   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_16 ); //Configuramos hardware spi.
      
      //Enviar valor numérico:
   output_low(SS);
   spi_write(0xAA);     //Este valor se envia correctamente
   output_high(SS);
    
      //Enviar variable:
   dato=0xBB;
   output_low(SS);
   spi_write(dato);     //Al enviar la variable, se produce un error.
   output_high(SS);
      
      
      
   while(1);  
}

El problema es quecuendo envío un valor numeric fijo(ex:spi_write(0xAA)), este se envia sin más, pero cundo envio una variable(spi_write(dato)), no funciona. a continuacion incluyo laimagen del spi debugger de Proteus:



Aqui esta la config del spi debbuguer...




Agradeceria mucho que alguien me explicara por que me pasa esto, no se si seráproblema del CCS, del Proteus o mio jejeje :D

hasta pronto..

« Última modificación: 01 de Septiembre de 2010, 12:56:15 por rugs20 »

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #1 en: 31 de Agosto de 2010, 13:29:02 »
A nadie le ha pasado esto??
que mala suerte tengo, jejeje
a ver sa alguien me puede echar una manitaaaa...

gracias.. :)

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con spi_write(var)
« Respuesta #2 en: 31 de Agosto de 2010, 18:14:06 »
¿Ya probaste colocando un retardo antes de volver a hacer "0" el pin SS para enviar la variable dato?
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #3 en: 01 de Septiembre de 2010, 12:50:32 »
Hola!!!

Gracias por tu respuesta, ya he probado, pero sigue sin funcionar, no se donde puede estar el error :5]

a seguir probando, jeje

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #4 en: 06 de Septiembre de 2010, 14:02:20 »
Hola!!

No consigo saber por que me pasa esto, he estado mirando el asm gnerado por el compilador y he visto que el codigo generado por spi_write(0xAA) y el generado por spi_write(dato), son diferentes, pero no consigo entenderlos.

Si alguien ha hecho esto alguna vez y me pudiera echar una mano....

Aqui dejo una imagen del asm:



gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema con spi_write(var)
« Respuesta #5 en: 06 de Septiembre de 2010, 14:19:54 »
Hola. Los códigos son muy similares. Lo único que noto de distinto, fuera de las diferencias lógicas, es que en el primer caso, lee el registro del SSPBUF antes de efectuar la escritura, y en el segundo no.


Primer caso:
Código: ASM
  1. MOVF       SSPBUF,W                ;mover SSPBUF a W
  2.     MOVLW    0xBB                        ;cargar W con 0xBB
  3.     MOVWF    SSPBUF                    ;y volcarlo en SSPBUF. Esto inicia automaticamente el envio
  4.  
  5.     BSF         STATUS, RP0            ;cambio a banco de memoria 1
  6.  
  7. Prox:
  8.     RRF         SSPSTAT, W             ;poner el bit 0(BF) de SSPSTAT en el Carry
  9.     BTFSS     STATUS,C                 ;verificar si el STATUS,C vale 1.Si es cierto, saltear la proxima instruccion
  10.     GOTO      Prox                         ;seguir esperando..(STATUS,C=0)


Segundo caso:
Código: ASM
  1. MOVF    DATO,W                        ;cargar W con el valor de la variable DATO
  2.     MOVWF    SSPBUF                    ;y volcarlo en SSPBUF. Esto inicia automaticamente el envio
  3.  
  4.     BSF         STATUS, RP0            ;cambio a banco de memoria 1
  5.  
  6. Prox2:
  7.     RRF         SSPSTAT, W             ;poner el bit 0(BF) de SSPSTAT en el Carry
  8.     BTFSS     STATUS,C                 ;verificar si el STATUS,C vale 1.Si es cierto, saltear la proxima instruccion
  9.     GOTO      Prox2                       ;seguir esperando..(STATUS,C=0)


Es raro lo que comentás. Probaste poniendo SPI1 a la configuracion del SPI para forzarlo a usar los pines  del SPI del uC?

Saludos.


P.D.

Revisando el datasheet:

Citar
SSPSTAT,0 es el bit BF:

BF: Buffer Full Status bit
Receive (SPI and I2 C modes):
1 = Receive complete, SSPBUF is full
0 = Receive not complete, SSPBUF is empty

Transmit (in I2 C mode only):
1 = Transmit in progress, SSPBUF is full (8 bits)
0 = Transmit complete, SSPBUF is empty

Por lo que segun el datasheet, verificar ese bit para transmitir sólo es aplicable al modo I2C, no al  SPI...
« Última modificación: 06 de Septiembre de 2010, 14:33:02 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con spi_write(var)
« Respuesta #6 en: 06 de Septiembre de 2010, 14:26:03 »
Yo lo único que noto diferente es en el caso de "spr_write(0xBB)" es la instrucción "movf 13,W".

No le encuentro mucho sentido ya que luego hay un "movlw 0xBB" eso lleva el valor 0XBB al registro W. Justamente estás llevando a W el dato que querés transmitir.

En el caso de "spi_write(dato)" hace "movf 21,W" Lleva a W el dato almacenado en la dirección 21 (que seguro es la dirección de tu variable dato en "CCS")

Luego todo es similar.

"movwf 13"  llevar el valor de W a la direccion 13 -registro SSPBUF-
"bsf 3.5"  hacer "1" el bit 5 del la dirección 3 -registro STATUS-
"RRF 14,W" rota a la derecha el registro 14 -SSPCON- y almacena el resultado en W
"btfss 3.0" testea si está seteado el bit de Carry en el registro STATUS
"goto xx" vuelve a la línea de "RRF 14,w"
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #7 en: 06 de Septiembre de 2010, 15:05:41 »
Hola!!

Gracias por contestar.

Contestando a BrunoF:
Lo de SPI1, creo que no es para CCS, en este compilador, al utilizar la funcion setup_spi, entiende que se va a utilizar el spi por hardware. Despues, lo que comentas del bit BF, creo que al ser una comunicacion Full-duplex, si se han recivido 8 bits (no importan los que sean), se supone que tambien se han enviado los 8 bits que queriamos enviar. (Creo que será por eso, es la primera vez que usoel SPI).

No consigo entender por que pasa esto  :5]...

Segun lo que dice el proteus, solo se envia un bit cuando utilizo la función para enviar la variable "dato" (ver imagen del primer mensaje).

Muchas gracias por vestras respuestas.

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #8 en: 07 de Septiembre de 2010, 12:45:20 »
Hola de nuevo!

Creo que he encontrado la solucion :-/, o por lo menos eso parece...

Comparando los codigos en asm me he dado cuenta que cuando utiliza spi_write(dato), el compilador no hace la lectura del SSPBUF antes de escribir el dato a enviar:



En el data sheet, he leido algo de que el bit BF, se pone a 0 por hardware cuando se lee el registro SSPBUF (corregidme si me equivoco jeje)...

Si hago lo siguiente, parece funcionar correctamente:

Código: [Seleccionar]
   
   output_low(SS);
   #asm
   BCF    03.5
   MOVF   0x13,W     //Leo el registro SSPBUF
   #endasm
   spi_write(dato);    //Y despues envio el dato
   output_high(SS);


De esta forma, parece funcionar bien al simular en proteus.

Espero que esta sea una buena solución, si a alguien  se le ocurre otra cosa mejor que lo diga...

Gracias y hasta luegoo... ;-)

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con spi_write(var)
« Respuesta #9 en: 07 de Septiembre de 2010, 14:08:50 »
No recuerdo como era la definición de "spi_write" pero me parece que también devolvía el byte leido a través del puerto SPI.

Si es que devuelve el dicho byte se podría probar de poner la sentencia de la siguiente manera

Código: C
  1. int8 dato_de_entrada; //la definicion de la variable
  2. dato_de_entrada = spi_write(dato);
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #10 en: 07 de Septiembre de 2010, 15:26:23 »
hola AngelGris!

Para lo que me comentas, existe la función spi_read(), que acabo de probar y tampoco funciona, cuando le doy una variable como dato de entrada, pero haciendo lo mismo que con la funcion spi_write, funciona correctamente.

Sería algo así:
Código: [Seleccionar]
   
   int8 res;
   #asm
   BCF    03.5
   MOVF   0x13,W
   #endasm
   res=spi_read(dat);

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con spi_write(var)
« Respuesta #11 en: 07 de Septiembre de 2010, 15:48:55 »
Qué lo pario!  :5] :5] :5]

Por suerte encontraste esa forma de resolverlo. Habría que ver si dicho problema no es bug en la versión que estás usando. ¿Intentaste con otra versión de dicho compilador?
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Problema con spi_write(var)
« Respuesta #12 en: 07 de Septiembre de 2010, 23:43:04 »
Que tal amigos!
rugs20 te adjunto un circuito corriendo con spi_write haber si te ayuda tambien  :mrgreen:
Operando 100% con un 74hc595!  ;-)

Saludos

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #13 en: 08 de Septiembre de 2010, 10:44:33 »
Hola!!

Gracias al ejemplo de RALF2, he podido ver que AngelGris, tenía algo de razón con lo del retardo:

Citar
¿Ya probaste colocando un retardo antes de volver a hacer "0" el pin SS para enviar la variable dato?

solo que hay que ponerlo antes de volver a poner a 1 el pin SS, colocándolo de esta forma parece funcionar bien:
Código: [Seleccionar]
  dato=0xDD;
   output_low(SS);
   spi_write(dato);
   delay_ms(2);
   output_high(SS);  


Solo me queda una duda: ¿Por qué cuando se envia un valor ( spi_write(0xXX) ) no hay que poner ese "delay_ms()"? ¿Por qué con una variable si?

Gracias!!
« Última modificación: 08 de Septiembre de 2010, 14:33:45 por rugs20 »

Desconectado rugs20

  • PIC10
  • *
  • Mensajes: 18
Re: Problema con spi_write(var)
« Respuesta #14 en: 09 de Septiembre de 2010, 15:53:15 »
hola de nuevo!!

He estado probando con los retardos y para que funcione, hay que poner como mínimo un retardo de 15us (delay_us(15)).

¿Alguien sabe por que pasa esto?

¿Puede ser problema del SPI DEBUGGER del Proteus?

:shock: ESTO ME ESTA VOLVIENDO LOCO :shock: