Autor Tema: SPI  (Leído 3209 veces)

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

Desconectado O_R_E

  • PIC10
  • *
  • Mensajes: 13
SPI
« en: 30 de Marzo de 2006, 15:40:00 »
Hola muy buenas,

Estoy intentando configurar el puerto serie sincrono SPI de un PIC16F877, conectado a un conversor A/D MAX187. Utilizo el compilador de C de CCS y lo que intento es mostrar por el display el valor analógico proporcionado por un LM35.

Para hacer un poco de resumen, el MAX187, necesita activa el bit CS a nivel bajo, posteriormente esperar un max de 8,5uS para posteriormente activar el reloj durante 13 ciclos, para despues colocar CS a nivel alto. Pero a todo esto me asaltan una serie de dudas:

1. ¿Como se gestiona el obtener 13 ciclos de reloj con CCS?
2. Al realizar un nuevo proyecto y indicarle que use el bus SPI, lo selecciono en modo master y SPI mode en CKP=CKE=0, tal y como indica los cronogramas de ambos dispostivos, hasta ahí bién, pero...mi reloj de cuarzo corre a 10MHz, y lo mínimo que devide este reloj es x4, con lo que obtengo una frecuencia de 2,5MHz, pero el MAX187 necesita que la frecuencia del reloj sea superior >2,5MHz para poder realizar conversiones, ¿Me funcionará?, porque no puedo seleccionar otra cosa a la hora de programar.
3. ¿Para que sirve la funcion sample at end? Esta se selecciona en la pestaña SPI and LCD cuando se inicia un nuevo proyecto.
4. El dato que obtengo es del tipo entero, ¿Debo convertirlo para obtenerlo por el LCD?

Este es el código de programa que he generado, con la diferencia que no lo muestro por el display sino que lo hago por la pantalla.

// Configuracion chip y compilador

#include "16F877.h"
#fuses EC_IO,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)

// Definición de pins ADC

#define MAX187_CS    = 7.2
#define MAX187_SCLK    = 7.3
#define MAX187_DOUT   = 7.4

// Funciones

int leerMAX187(void);

void main(void)
{
   // Variables
   int dato;

   // Configuracion de los puertos
   #use fast_io(A)
   #use fast_io(B)
   #use fast_io(C)
   #use fast_io(D)
   #use fast_io(E)
   set_tris_a(0b00000000);
   set_tris_b(0b00000000);
   set_tris_c(0b00110110);
   set_tris_d(0b00000000);
   set_tris_e(0b00000000);

   // Inicializacion del SPI
   output_high(MAX187_CS);         // Activo el pin CS a nivel alto

   // Inicialización del puerto SPI
   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4);
   
                while(1)
                {
                           dato = leerMAX187();
                           printf("Este es el valor procedente del ADC: %d
",dato);
                           delay_us(100);
                }

   return;
}

int leerMAX187(void)
{
   int datoMAX187;

   output_low(MAX187_CS);                            // Seleciono CS para decirle al ADC que va ha comenzar la adquisición de datos
   delay_us();                     // Espera
   datoMAX187 = spi_read(0);                         // Adquiero el dato del MAX187
   output_high(MAX187_CS);                           // Desabilito el ADC  

   return datoMAX187;
}

Gracias

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
RE: SPI
« Respuesta #1 en: 30 de Marzo de 2006, 18:19:00 »
Tratare de responderte las cosas que son genéricas ya que no uso el CCS

1. ¿Como se gestiona el obtener 13 ciclos de reloj con CCS?

En realidad hay varios integrados que no usan 8 o 16 bits, sino algun numero como 13, 21, etc.  Lo que se hace es mandar en tu caso,  16 bits.  Los primeros 3 bits, se descartan por el mismo funcionamiento de los perifericos SPI es decir que el MAX en cuestión no le hará caso.


2. Al realizar un nuevo proyecto y indicarle que use el bus SPI, lo selecciono en modo master y SPI mode en CKP=CKE=0, tal y como indica los cronogramas de ambos dispostivos, hasta ahí bién, pero...mi reloj de cuarzo corre a 10MHz, y lo mínimo que devide este reloj es x4, con lo que obtengo una frecuencia de 2,5MHz, pero el MAX187 necesita que la frecuencia del reloj sea superior >2,5MHz para poder realizar conversiones, ¿Me funcionará?, porque no puedo seleccionar otra cosa a la hora de programar.


Una cosa es la comunicación SPI y otra es el clock que necesita tu conversor A/D.  Estas seguro que no estas mezclando la información del datasheet?  te lo pregunto porque no leí la datasheet del integrado que mencionas.  

Los modulos SPI se especifican por velocidades MAXIMAS pero jamás vi una especificación de una mínima velocidad ya que las validaciones de los datos se hacen en los flancos del CLOCK del SPI!


3. ¿Para que sirve la funcion sample at end? Esta se selecciona en la pestaña SPI and LCD cuando se inicia un nuevo proyecto.

Se refiere si el dato entrante será SAMPLEADO o RECIBIDO por el SSPBUF en el medio del dato saliente o al final.  Es decir,  con el SPI tu debes generar siempre salida para obtener una entrada.  Esto sirve para configurar si la entrada es latcheada al finalizar la salida o bien en la mitad del último bit transmitido.  Eso leelo en el datasheet del MAX.


4. El dato que obtengo es del tipo entero, ¿Debo convertirlo para obtenerlo por el LCD?

Los lcd pueden representar caracteres de 0 a 255.  Lo que ocurre es que seguramente será un dato ilegible para el comun de los mortales.  Lo sugerido es hacer una conversión del INT a ASCII.  La función del ansi C suele llamarte itoa (integer to ascii) .


Otro comentario, fijate esto que aparece en tu código

 set_tris_c(0b00110110);

En el SPI si tu eres MASTER (como veo que lo eres) , los pines de SDO y SCK son salidas!! y el SDI entrada.

Además para usar la  USART por hardware, los bits del RC7 y RC6 deben también estar como entrada.

Sin saber que conectaras en RC0:RC2 te digo que tu configuración debiera ser asi

 set_tris_c(0b11001111);

Nota que los bits RC0:RC2 los puse como entrada poruqe no se que haras con ellos.


Espero te haya servido mi post.

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado O_R_E

  • PIC10
  • *
  • Mensajes: 13
RE: SPI
« Respuesta #2 en: 01 de Abril de 2006, 06:59:00 »
Hola Maunix,

Muchas gracias por la información, pero después de ver tu post, tengo una duda: tu me dices que cooque en el port c, set_tris_c(0b11001111), es decir, RC0=entrada, RC1=entrada, RC2=salida=CS(MAX187), RC3=salida=SCLK(MAX187), RC4=entrada=DOUT(MAX187), RC5=entrada=SDO(PIC16F877), RC6=entrada=TX, RC7=entrada=RX. Veo dos errores; el primero tiene que ver con el el pin RC5, no puede ser de entrada, ya que es un pin de salida de datos SPI, y el segundo es que el pin RC6 TX, lo activas como entrada, y no es para enviar datos al PC?

Sobre el tema del clock, no entiendo, el PIC proporciona un clock constante que se activa por software, pero mi pregunta es, ¿Cuanto dura este clock, 12, 13, 21, 100? ¿o lo paro yo mediante software?
Entiendo por tu post que el ciclo un clock es el que regulo yo con SPI setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4), eso es lo que entiendo.

De todas formas muchas gracias por tus comentarios, me han servido de gran ayuda, y espero en estos días dar una solucion y poder recibir los datos de mi LM35 y poder visualizarlos por el lcd.

Un saludo,

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
RE: SPI
« Respuesta #3 en: 01 de Abril de 2006, 16:53:00 »
Creo que alguien aquí alguien tiene que leer un manual de PICs antes de hablar....

Escrito originalmente por O_R_E
Hola Maunix,
Muchas gracias por la información, pero después de ver tu post, tengo una duda: tu me dices que cooque en el port c, set_tris_c(0b11001111), es decir, RC0=entrada, RC1=entrada, RC2=salida=CS(MAX187), RC3=salida=SCLK(MAX187), RC4=entrada=DOUT(MAX187), RC5=entrada=SDO(PIC16F877), RC6=entrada=TX, RC7=entrada=RX. Veo dos errores; el primero tiene que ver con el el pin RC5, no puede ser de entrada, ya que es un pin de salida de datos SPI, y el segundo es que el pin RC6 TX, lo activas como entrada, y no es para enviar datos al PC?



Yo puse mal 1 dígito pero tu estas leyendo de izquierda a derecha!!! y un número en cualquier base se lee de DERECHA A IZQUIERDA!!
Un 0 indica salida
Un 1 indica entrada

set_tris_c(0b11010111)
RC0 entrada
RC1 entrada
RC2 entrada: (los puse como entrada pero los podes poner como salida, no se que uso les daras en tu software)
RC3 salida : es el SCK , la salida de clock del SPI
RC4 entrada : es el SDI del pic, o salida del MAX
RC5: salida : SDO del pic
RC6 y RC7: deben ponerse como entrada para ser configurados como puerto de USART (leer el manual).


Escrito originalmente por O_R_E

Sobre el tema del clock, no entiendo, el PIC proporciona un clock constante que se activa por software, pero mi pregunta es, ¿Cuanto dura este clock, 12, 13, 21, 100? ¿o lo paro yo mediante software?
Entiendo por tu post que el ciclo un clock es el que regulo yo con SPI setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4), eso es lo que entiendo.
Un saludo,


El clock se activa cada vez que envias un dato.

Lo de SPI_L_TO_H indica en que momento de la trasición del clock se transmite el dato.  Cuando se usa como recepción seria en que momento se valida el dato entrante.

SPI_CLK_DIV_4 es que divides el clock del microcontrolador por 4.  Estarías andando a 1 Mhz de SPI.

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado O_R_E

  • PIC10
  • *
  • Mensajes: 13
RE: SPI
« Respuesta #4 en: 02 de Abril de 2006, 09:59:00 »
Hola Manuix,

Usted me perdone, he tenido una confusión...si que leí el manal de pics, uno puede cometer un error, ¡Soy humano!, pág 32, manual compilador CCS:

Estas funciones permiten escribir directamente los registros tri-estado para la
configuración de los puertos.
Esto debe usarse con FAST_IO() y cuando se accede a los puertos de I/O como si
fueran memoria, igual que cuando se utiliza una directiva #BYTE. Cada bit de value
representa una patilla. Un "1" indica que la patilla es de entrada y un "0" que es de
salida.
Ejemplo:
SET_TRIS_B( 0x0F ); // pone B0, B1, B2 y B3 como entradas; B4, B5, B6 y B7
// como salidas, en un PIC 16c84

Espero que no se me vuelva a olvidar, y me entre en esta cabeza dura de mollera que tengo.

Disculpas de nuevo.

Un saludo,

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
RE: SPI
« Respuesta #5 en: 02 de Abril de 2006, 15:12:00 »
Escrito originalmente por O_R_E
Hola Manuix,

Usted me perdone, he tenido una confusión...si que leí el manal de pics, uno puede cometer un error, ¡Soy humano!, pág 32, manual compilador CCS:

Estas funciones permiten escribir directamente los registros tri-estado para la
configuración de los puertos.
Esto debe usarse con FAST_IO() y cuando se accede a los puertos de I/O como si
fueran memoria, igual que cuando se utiliza una directiva #BYTE. Cada bit de value
representa una patilla. Un "1" indica que la patilla es de entrada y un "0" que es de
salida.
Ejemplo:
SET_TRIS_B( 0x0F ); // pone B0, B1, B2 y B3 como entradas; B4, B5, B6 y B7
// como salidas, en un PIC 16c84

Espero que no se me vuelva a olvidar, y me entre en esta cabeza dura de mollera que tengo.

Disculpas de nuevo.

Un saludo,


Bueno, disculpas aceptadas.  No es que me haya enojado pero considero que alguien debe leer bien e informarse mejor antes de decir que otra persona está equivocada Sonrisa

Es que en realidad en cualquier compilador los numeroso se leen de derecha a izquierda.  En cualquier sistema numérico arábico o descendiente de ellos  (no se como escribiran los chinos, coreanos o japoneses los números).

Si yo pongo 123 , uno interpreta ciento veinti tres.  Y no trescientos ventiuno.

Idem en cualquier lenguaje de informática, no importa si estas en binario,  hexa ,  octal o decimal.

Más allá de esto,  siempre siempre consulta primero el manual de los pics! Después ves como implementa tu compilador la sentencia pero si solo te fijas en el compilador puede que mal interpretes algo y hagas cualquier cosa.

Para aprender a usar un módulo hay que leer el manual de los pics.  El compilador de C sirve para allanar camino, para hacernos las cosas más faciles pero no te enseñará como configurar un módulo.

Un abrazo


- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)


 

anything