Autor Tema: Cómo enviar o recibir sólo 4bits usando interfaz spi...  (Leído 8132 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Cómo enviar o recibir sólo 4bits usando interfaz spi...
« en: 01 de Junio de 2008, 14:56:20 »
Saludos gente todopic!
Bueno pues se me ha presentado este inconveniente. Tengo un PIC16F876 que estoy tratando de comunicar con un módulo de brújula electrónica. Ahí les dejo la datasheet. La cuestión es que para inicializar el módulo y decirle que mande los datos, se necesitan enviar primero el dato 0b000 para resetear el módulo, luego 0b1000 y finalmente 0b1100. Después de enviar este último dato se debe hacer una lectura y ver si el dato recibido es 0b1100, lo que indica que el módulo está listo para enviar la lectura. La cuestión es que no logro con el ccs transmitir sólo 4 bits, siempre manda los 8 bits. ¿Tienen idea de cómo enviar o recibir sólo 4bits?
Pic Basic tiene una opción con los comandos shifout y shiftin donde uno coloca la cantidad de bits que quiere enviar... lo he probado y en efecto sí se pueden enviar sólo 4 bits (y también con sólo cuatro ciclos de sck o el reloj de la interfaz spi)... pero en C cómo se hace?

Intenté hacerlo declarando la opción BITS=4 dentro del #use spi:

Código: C
  1. #include <16f876.h>
  2. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
  3. #define RX PIN_C7
  4. #define Tx PIN_C6
  5. #define SDO PIN_C5
  6. #define SDI PIN_C4
  7. #define SCK PIN_C3
  8. #define EN PIN_C2
  9. #use fast_io(A)
  10. #use fast_io(B)
  11. #use fast_io(C)
  12. #use delay (CLOCK=20000000)
  13. #use rs232 (BAUD=19200,XMIT=Tx,RCV=Rx)
  14. #byte porta = 0x05
  15. #byte portb = 0x06
  16. #byte portc = 0x07
  17. #byte portd = 0x08
  18. #byte porte = 0x09
  19. const int reset                 = 0b0000;
  20. const int measure            = 0b1000;
  21. const int report               = 0b1100;
  22. char eje;
  23.  
  24. #use spi (master,DI=SDI,DO=SDO,CLK=SCK,CLOCK_HIGH=1,CLOCK_LOW=1,MODE=1,[b]BITS=4[/b])
  25. void inicia_brujula()
  26. {
  27.         int estado;
  28.         spi_write(reset);
  29.         output_high(EN);
  30.         output_low(EN);
  31.         spi_write(measure);
  32.         output_high(EN);
  33.         output_low(EN);
  34.         spi_write(report);
  35.         estado=spi_read();
  36.         while(!spi_data_is_in());
  37. }
  38.  
  39. #use spi (master,DI=SDI,DO=SDO,CLK=SCK,CLOCK_HIGH=1,CLOCK_LOW=1,MODE=1,BITS=11)
  40. int16 recibe_brujula(eje)
  41. {
  42.         int16 dato;
  43.         switch (eje)
  44.         {
  45.                 case 'x':            dato=spi_read();
  46.                                         dato>>=4;
  47.                                         break;
  48.                 case 'y':            dato=spi_read();
  49.                                         dato>>=4;
  50.                                         break;
  51.         }
  52.         return (dato); 
  53. }
  54.  
  55. void main (void)
  56. {
  57.         signed int16 dato_x,dato_y;
  58.         set_tris_a(0b11111111);
  59.         set_tris_b(0b11111111);
  60.         set_tris_c(0b00010000);
  61.         output_high(EN);
  62.         setup_spi (spi_master | spi_h_to_l | spi_ss_disabled);
  63.         inicia_brujula();
  64.         while(TRUE)
  65.         {
  66.                 output_high(EN);
  67.                 output_low(EN);
  68.                 dato_x = recibe_brujula('x');
  69.                 dato_y = recibe_brujula('y');
  70.                 printf("X= %Ld",dato_x);
  71.                 printf("  Y= %Ld\n\r",dato_y);
  72.         }      
  73. }

... Pero sigue mandando los 8 bits. Aquí les dejo la captura de lo que muestra proteus:



Qué me dicen señores? Alguna idea?
Desde ya les agradezco cualquier ayuda que puedan prestarme. Ya esto me trae de cabeza  :?
Ok nos leemos!  :mrgreen:

« Última modificación: 02 de Junio de 2008, 18:48:51 por firepic »
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi?
« Respuesta #1 en: 01 de Junio de 2008, 18:27:00 »
Revisando el manual de CCS acabo de ver una instrucción que se me había pasado por alto:
spi_xfer(stream,data,bits)
Pero trato de implementarla aplicando un STREAM=id al #use spi y nada... con esta si que no hace ni coquito...
.... qué será lo que estoy haciendo mal? Alguna burrada debe ser... tiene idea de cuál es?
De nuevo les agradezco sus respuestas.
Nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi... (solucionado)
« Respuesta #2 en: 01 de Junio de 2008, 23:58:13 »
Pues me respondo yo mismo, ya detecté cuál era el problema  :P
Para poder generar una spi de un tamaño diferente a 8 bits, se tiene que hacer implementando la spi por software. Por eso, el error estaba en la línea 62:
Código: [Seleccionar]
setup_spi (spi_master | spi_h_to_l |spi_ss_disabled);
Esa directiva es para implementar el spi por hardware, el cual no es el caso.
Al quitar esa línea y especificar los demás datos en la misma #use spi (como por ejemplo MSB_FIRST), funcionó perfectamente el código; usando el comando
Código: [Seleccionar]
spi_xfer (STREAM,data,bits);
Ojalá que este hilo le sirva a alguien que tenga el mismo inconveniente. No le vaya a pasar lo mismo que a mí  :D
Ok de todos modos agradezco a todos y al foro, del que he tomado muchos nuevos conocimientos  :-/
Saludos pues, nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi... (solucionado)
« Respuesta #3 en: 02 de Junio de 2008, 00:00:22 »
Los moderadores y expertos del foro pensarán: "este muchacho no se cansa de cometer burradas?"  :D
Disculpen mi inexperiencia... pero ahí dandome golpes voy aprendiendo  :lol:
Nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi... (solucionado)
« Respuesta #4 en: 02 de Junio de 2008, 17:28:00 »
...Disculpen mi inexperiencia... pero ahí dandome golpes voy aprendiendo  :lol:

Estamos en la misma situación, Javier  :D

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi... (solucionado)
« Respuesta #5 en: 02 de Junio de 2008, 18:18:50 »
Firepic, eres un genio!!!
Te preguntas y te contestas solo!!! :D :D :D
Esta bueno ese comando, no lo conocia, estaba por contestarte que lo hicieras por software, como las librerias donde mandas 12 bits, por ejemplo..
Pero eso esta mucho mas "piola" como decimos aqui... :lol:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi... (solucionado)
« Respuesta #6 en: 02 de Junio de 2008, 18:43:17 »
Firepic, eres un genio!!!
No lo creo... todavía estoy en pañalitos... pero gracias por el ánimo!  :-/

Pues ya que comencé este hilo, por aquí dejo el código un poco mejorado (aunque todavía no me ha funcionado como debe ser para recibir los datos de la brújula, pero sí hace la parte del envío de 4 bits con interfaz spi) y también pueden ver las simulación en proteus...

Código: C
  1. #include <16f876.h>
  2. #include <math.h>
  3. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
  4. #define RX              PIN_C7
  5. #define Tx              PIN_C6
  6. #define SDO     PIN_C5
  7. #define SDI     PIN_C4
  8. #define SCK     PIN_C3
  9. #define EN      PIN_C2
  10. #use fast_io(A)
  11. #use fast_io(B)
  12. #use fast_io(C)
  13. #use delay (CLOCK=20000000)
  14. #use rs232 (BAUD=19200,XMIT=Tx,RCV=Rx)
  15. #use spi (MASTER,CLOCK_HIGH=5,CLOCK_LOW=5,DI=SDI,DO=SDO,CLK=SCK,MSB_FIRST,MODE=1,STREAM=brujula_out)
  16. #use spi (MASTER,CLOCK_HIGH=5,CLOCK_LOW=5,DI=SDI,DO=SDO,CLK=SCK,LSB_FIRST,MODE=1,STREAM=brujula_in)
  17. #byte porta = 0x05
  18. #byte portb = 0x06
  19. #byte portc = 0x07
  20. #byte portd = 0x08
  21. #byte porte = 0x09
  22. int16 dato_x,dato_y;
  23. const int reset = 0b0000;
  24. const int measure = 0b1000;
  25. const int report = 0b1100;
  26. const int16 negmask = 0b1111100000000000;
  27.  
  28. void recibe_brujula()
  29. {
  30.         int estado=0;
  31.         output_low(EN);
  32.         spi_xfer(brujula_out,reset,4);
  33.         output_high(EN);
  34.         delay_us(20);
  35.         output_low(EN);
  36.         spi_xfer(brujula_out,measure,4);
  37.         output_high(EN);
  38.         delay_us(20);
  39.         output_low(EN);
  40.         while (estado != 3)
  41.         {
  42.         spi_xfer(brujula_out,0b1100,4);
  43.         estado = spi_xfer(brujula_in,0b0000,4);
  44.         }
  45.         dato_x=spi_xfer(brujula_in,reset,11);
  46.         dato_y=spi_xfer(brujula_in,reset,11);
  47. }      
  48.  
  49. void main (void)
  50. {
  51.         float x,y,angulo;
  52.         set_tris_a(0b00000000);
  53.         set_tris_b(0b00000010);
  54.         set_tris_c(0b10010000);
  55.         output_high(EN);
  56.         while(TRUE)
  57.         {
  58.                 recibe_brujula();
  59.                 if (bit_test(dato_x,10)==1) dato_x = dato_x | negmask ;
  60.                 if (bit_test(dato_y,10)==1) dato_y = dato_y | negmask ;
  61.                 x=(float)dato_x;
  62.                 y=(float)dato_y;
  63.                 angulo = atan2 (-y,x);
  64.                 angulo*=57.2958;
  65.                 printf ("Angulo= %f\n\r",angulo);
  66.                 delay_ms(150);
  67.         }      
  68. }



Como se puede apreciar, primero se envía el dato 0b000, luego 0b100, posteriormente 0b1100 y el reloj marca otros cuatro ciclos a la espera de la respuesta del dispositivo spi (en este caso la brújula).

Bueno espero este hilo le puede servir a alguien que se tope en algún momento con este problemilla.
Ok saludos, nos leemos!
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #7 en: 10 de Diciembre de 2008, 15:05:47 »
Y se puede enviar menos de 8 bits usando el hardware del pic ??? pregunto yo xP

Salu2.

PD: result = spi_xfer(stream, data, bits) Data puede ser de 16bits ? :S y bits puede llegar hasta 16 ? Como funciona esto? Y, esto es lo mismo que spi_read(data) ? y que hace exactamnt este ultimo? AHHH estoi mas perdido! porfa que alguien me oriente que tengo muchos problemas aora con el SPI =D
« Última modificación: 10 de Diciembre de 2008, 15:11:14 por jeremylf »

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #8 en: 10 de Diciembre de 2008, 15:17:29 »
Hola.

El spi_xfer() si envia 16 bits, de hecho yo lo he usado para trabajar asi el AD9833 y corre bien ... no tenia ni idea de que se podian enviar solo 4 bits ... hay que leer mejor la ayuda  :lol:

Saludos
El papel lo aguanta todo

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #9 en: 10 de Diciembre de 2008, 15:39:02 »
Haya, y sabrian si es lo mismo para lectura??  osea, quisiera que el SPI_DATA_IS_IN() (o de otra forma) me avisara que hay dato a los 3 bits, o algo asi para poder sacar datos recien en el 4 pulso del clock.. se entiende?

Gracias.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #10 en: 10 de Diciembre de 2008, 15:50:31 »
Hola.

Esto es lo que dice del spi_xfer(), se usa la misma funcion para escribir o leer.



Saludos
El papel lo aguanta todo

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #11 en: 10 de Diciembre de 2008, 16:44:35 »
Si tengo eso y lo e visto y todo pero como harias para leer 3 bits ? o que te avisen cuando llego 3 bits

Gracias igual =D

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #12 en: 10 de Diciembre de 2008, 18:55:47 »
Hola.

Pues me imagino que colocando el numero de bits en la funcion spi_xfer(stream, data, BITS). No lo he usado, pero si al colocar ese valor configuro los bits que envio, me imagino que tambien configura los que recibo ....

Si lo vas a usar ... me cuentas si funciona  :mrgreen:

Saludos
El papel lo aguanta todo

Desconectado begoña1966

  • PIC10
  • *
  • Mensajes: 6
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #13 en: 21 de Enero de 2009, 07:23:00 »
Hola Firepic, muy bueno tu trabajo.

Me he hecho con un modulo HM55 y he copiado los fuentes que tu has probado y a mi no me responde el modulo HM55.

Los fuentes los compilo sobre CCS version 4, y lo hago correr sobre un pic18F4550.

Me podias ayudar con alguna indicacion.

Saludos a todos

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Cómo enviar o recibir sólo 4bits usando interfaz spi...
« Respuesta #14 en: 13 de Febrero de 2009, 16:20:06 »
Saludos Begoña!
A ver si todavía estoy a tiempo de darte alguna aclaratoria.
Lo primero, la intrucción de que funciona, funciona. Pero no te creas, a mi no me funcionó a la primera.
Yo por ejemplo tuve que hacer varias cosas.
Primero, le enviaba los datos de reset y activación y recibía el dato que mandaba la brújula, y enviaba ese valor por puerto serial para monitorear qué estaba mandando la brújula.
Además tuve que revisar muy bien el hardware, cualquier mal contacto en el protoboard daña toda la transmisión spi.
Espero logres resolver el problema, nos leemos!
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web