TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cyberpex en 06 de Junio de 2011, 13:01:05

Título: (Solucionado) Ayuda con SPI y CS5463
Publicado por: cyberpex en 06 de Junio de 2011, 13:01:05
Hola Amigos de TodoPic.

Siempre he entrado al foro y me he nutrido de conocimientos y por lo general, las respuestas a mis preguntas las he encontrado con el buscador.

Esta vez estoy trabajando en un proyecto para hacer un medidor de energía monofásico y no he encontrado mucha ayuda al respecto.

Inicialmente lo pensé con un integrado especializado de Sames (http://www.sames.co.za/), el SA9903.

Me fue imposible conseguirlo (soy de Chile) y finalmente obtuve una solución alternativa de Cirrus Logic, el CS5463.

Lamentablemente, me ha dado más dolores de cabeza de lo pensado, viene en un encapsulado SSOP24 y necesita de un cristal de 4.096MHz.

Para utilizarlo diseñé un PCB que me permite ubicarlo en un protoboard.

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=35036.0;attach=15964;image)

En el PCB se encuentra el CS5463 y el cristal de 4.096MHz por debajo del mismo.

Para probarlo realicé un pequeño programa que me permite enviar una trama en hexadecimal y recibir de vuelta la respuesta del integrado.

El código utilizado está escrito en CCS y usa el microcontrolador 18F252

Lo muestro a continuación

Código: [Seleccionar]
#include <18f252.h>
#fuses XT,NOWDT
#use delay(clock=4096000)
#use spi(MASTER, FORCE_HW, MODE=0, BITS=8)
#use rs232(baud=19200, uart1, ERRORS, stream=SERIE)

#include <stdlib.h>
#include <string.h>

//constantes
#define LED    PIN_B4
#define CS     PIN_B3
#define RESET  PIN_B6
#define INT    PIN_B1

//variables
char recibido[50];
int index=0, final;
int contador = 0;
int1 procesar=0;

//definicion de funciones
int gethex1(char digit);

#INT_RDA
void rda_isr()
{
   if(kbhit(SERIE))
   {
      recibido[index] = fgetc(SERIE);
      fputc(recibido[index], SERIE);
      
      if((recibido[index]!='\r')&&(recibido[index]!='\n')&&(recibido[index]!=0x08)&&(recibido[index]!=' ')&&(recibido[index]!='\t'))
      {
         if(index<50)
         {
            index++;
         }
         else
         {
            index=0;
         }        
      }
      else if ((recibido[index]==0x08))
      {
         if(index>0)
         {
            index--;
            recibido[index]='\0';
            
         }
      }
      else if ((recibido[index]=='\n'))
      {
         recibido[index]='\0';
         final=index;
         index=0;
         procesar=1;
      }      
   }  
}

#INT_TIMER0
void rtcc_isr()
{
   if(contador >0)
   {
      contador--;
   }
   else
   {
      contador = 8;
      output_toggle(LED);
   }
}

void main()
{
   int pos, comando, resultado;
   output_high(LED);
   delay_ms(1000);
   output_low(LED);
  
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_RDA);  
   enable_interrupts(GLOBAL);
   set_timer0(0);
   //output_high(RESET);
  
   fprintf(SERIE, "\f>");
   for(;;)
   {
      if(procesar)
      {
         pos=0;
         //fprintf(SERIE, "(procesando: %s)\r\n", recibido);
         output_low(CS);
         fprintf(SERIE, "=");
         while(pos<final)
         {
            comando=gethex1(recibido[pos]);
            pos++;            
            comando<<=4;
            comando+=gethex1(recibido[pos]);
            pos++;
            resultado = spi_xfer(comando);
            fprintf(SERIE, "%X", resultado);
            delay_ms(50);
            
         }
         fprintf(SERIE, "\r\n\r\n>");
         output_high(CS);  
         procesar = 0;
      }
  
   }
}

int gethex1(char digit)
{
   if(digit<='9')
      return(digit-'0');
   else
      return((toupper(digit)-'A')+10);
}

Para verificar su buen funcionamiento, en el bus SPI conecté una memoria SPI la M25X80VSIG (una bios de HP). Puedo leerla y escribirla sin problemas (el chip que mide energía está en el mismo Bus, pero su CS está en estado alto).

La verdad es que me he leído el datasheet del CS5463 bastante bien, pero no sé si me he pasado algo o estoy haciendo algo mal.
Hasta ahora se que hay tres tipos de órdenes:


Para pruebas, he cortocircuitado las entradas Vin+/Vin- y Iin+/Iin-, estoy usando el voltaje de referencia interno y he conectado VA+ VD+ GND y AGND (aparte de la conexión SPI).

Hasta ahora la memoria (que uso para probar el protocolo SPI) funciona bien y puedo leer y escribir, pero el medidor de energía algunas veces devuelve

Código: [Seleccionar]
>f8
=FF
>26fefefe
=5FFFF000

pero el resto de las veces hace:

Código: [Seleccionar]
>f8
=00
>26fefefe
=00000000

Ojalá alguien me pueda ayudar.

El datasheet lo encuentran en:
http://www.cirrus.com/cn/pubs/proDatasheet/CS5463_F3.pdf (http://www.cirrus.com/cn/pubs/proDatasheet/CS5463_F3.pdf)

una placa de desarrollo en la que baso mis conexiones:
http://www.cirrus.com/en/pubs/rdDatasheet/CDB5463U_DB2.pdf (http://www.cirrus.com/en/pubs/rdDatasheet/CDB5463U_DB2.pdf)

la página de producto:
http://www.cirrus.com/en/products/cs5463.html (http://www.cirrus.com/en/products/cs5463.html)

Saludos
Título: Re: Ayuda con SPI y CS5463
Publicado por: MGLSOFT en 06 de Junio de 2011, 14:55:15
Estoy armando mi placa, así que en poco tiempo estaré haciendo mis primeros pinos con este integrado.
Allí te escribiré experiencias...
Título: Re: Ayuda con SPI y CS5463
Publicado por: Suky en 06 de Junio de 2011, 17:19:10
Hola! Te comento, yo he trabajado con el CS5461A, y es muy parecido al CS5463.

La frecuencia del cristal no es tan estricta, o sea puede tomar valores entre 1MHz y 5Mhz si no recuerdo mal. Pero, para que no haya falta de sincronismo entre la frecuencia de red y la frecuencia de muestreo la frecuencia elegida debería ser:

FrecuenciaSeñal x 1024 x Npc

Donde Npc es la cantidad de ciclos de computación por ciclo de señal. Fíjate que el CS permite configurar los ciclos de computación (N), para calcular por ejemplo los valores RMS, mediante el registro  Cycle Count Register, pero este no es estrictamente Npc sino un múltiplo. Por ejemplo, si la señal de red es 50Hz y pretendo ocupar 100ms para calcular el valor RMS, N=5*Npc.

Fíjate que si Npc es igual a 80, entonces la frecuencia del cristal debería ser 4096000Hz, y si deseo tomar 1seg de muestras para calcular los valores RMS N debería de colocarlo en 50*80=4000, valor que viene por defecto  ;-)

Como ves, podes elegir un valor de frecuencia del cristal más comercial (de la zona) y modificar el valor de N para que el error sea mínimo.

Respecto a la configuración, SPI debe configurarse en modo CKE=1, CKP=0, frecuencia máxima 2MHz. Para la inicialización hago lo siguiente:


Código: [Seleccionar]
PIN_CS5461=0;
vWriteSPI_CS5461A(0x80); // Reset por software...
PIN_CS5461=1;
__delay_us(200);

PIN_CS5461=0;
vWriteSPI_CS5461A(0x40); // Registro de configuración
vWriteSPI_CS5461A(0x00);
vWriteSPI_CS5461A(0x00); // Int activo bajo
vWriteSPI_CS5461A(0x61); // HPF=1, K=1;
PIN_CS5461=1;

PIN_CS5461=0;
vWriteSPI_CS5461A(0x4A);
vWriteSPI_CS5461A(0x00);
vWriteSPI_CS5461A(0x0F);
vWriteSPI_CS5461A(0x3C); // N=3900 -> 4Mhz ~ 1s
PIN_CS5461=1;

//----------------------------------
PIN_CS5461=0;
vWriteSPI_CS5461A(0x5E);
vWriteSPI_CS5461A(0xFF);
vWriteSPI_CS5461A(0xFF);
vWriteSPI_CS5461A(0xFF);       // Borramos todos los bits de STATUS
PIN_CS5461=1;

PIN_CS5461=0;
vWriteSPI_CS5461A(0x74);
vWriteSPI_CS5461A(0x80);
vWriteSPI_CS5461A(0x00);
vWriteSPI_CS5461A(0x00); // Mask = 0x800000 -> INT=DRDY Ciclo de computado terminado
PIN_CS5461=1;

//----------------------------------
PIN_CS5461=0;
vWriteSPI_CS5461A(0xE8); // Conversion continua
PIN_CS5461=1;

Con ello te permite testear el pin INT el cual te indicará que ha terminado el ciclo de computación y realizar la lectura:

Código: [Seleccionar]
void vReadCS5461A(void){

PIN_CS5461=0;
vWriteSPI_CS5461A(0x16); // Leemos IRMS
ValueIRMS.HB=ucReadSPI_CS5461A(0xFF);
ValueIRMS.MB=ucReadSPI_CS5461A(0xFF);
ValueIRMS.LB=ucReadSPI_CS5461A(0xFF);
PIN_CS5461=1;

PIN_CS5461=0;
vWriteSPI_CS5461A(0x18); // Leemos VRMS
ValueVRMS.HB=ucReadSPI_CS5461A(0xFF);
ValueVRMS.MB=ucReadSPI_CS5461A(0xFF);
ValueVRMS.LB=ucReadSPI_CS5461A(0xFF);
PIN_CS5461=1;

PIN_CS5461=0;
vWriteSPI_CS5461A(0x5E);
vWriteSPI_CS5461A(0x80);
vWriteSPI_CS5461A(0x00);
vWriteSPI_CS5461A(0x00); // Borramos todos los bits de STATUS
PIN_CS5461=1;
}

ValueIRMS y ValueVRMS son variables de 24-bits, en donde 0xFFFFFF = 250mV. En mi caso al tomar los primeros valores, los resultados obtenidos (sin ningún tipo de calibración) eran un % menor al real, y diferente en cada canal, pero realizando la calibración de ganancia AC eso mejora y los resultados son muy buenos.


Saludos!


Título: Re: Ayuda con SPI y CS5463
Publicado por: cyberpex en 14 de Junio de 2011, 12:43:16
Gracias!!!

Estoy gratamente sorprendido de que me respondieran tan pronto, lamentablemente, no había tenido tiempo de revisar.

La gente de Cirrus todavía no me responde los correos que envié antes de postear en el foro.

Muchas Gracias Suky, probaré la inicialización en tanto tenga un poco de tiempo libre y te comento los resultados!!

Muchas gracias por la pronta respuesta. (También a MGLSOFT)
Título: Re: Ayuda con SPI y CS5463
Publicado por: Suky en 14 de Junio de 2011, 13:37:18
La gente de Cirrus todavía no me responde los correos que envié antes de postear en el foro.

Parece que no son de responder, yo hace más de un mes les escribí y todavía los espero  :? Suerte que no soy de quedarme esperando  :D


Saludos!
Título: Re: Ayuda con SPI y CS5463
Publicado por: cyberpex en 15 de Junio de 2011, 01:42:46
Hola Suky...
debo agradecerte muchísimo la ayuda...

estuve haciendo puebas hasta ahora y finalmente lo conseguí. Lamentablemente, no era por un tema de software, sino por un error humano. la alimentación VA+ estaba cortada.

Ahora recibo datos, aunque no son estables, veré si funciona correctamente leyendo los otros registros...

adjunto el código optimizado, que inicializa el chip de Cirrus y lee temperatura, IRMS y VRMS por si le sirve a alguien

Código: [Seleccionar]
#include <18f252.h>
#fuses HS,NOWDT
#use delay(clock=20MHz)
#use spi(FORCE_HW, MODE=0, MASTER, stream=MYSPI, BITS=32)
#use rs232(baud=19200, uart1, ERRORS, stream=SERIE)

//constantes
#define LED    PIN_B4
#define RESET  PIN_B5
#define INT    PIN_B1

//variables globales

//definicion de funciones

void CS5463_init()
{
   // Software reset
   spi_xfer(MYSPI, 0x80, 8);
   delay_ms(200);
   
   //Registro de configuración: Int activo bajo; HPF=1, K=1
   spi_xfer(MYSPI, 0x40000061);
   
   //N=4000  cristal de 4,096MHz
   spi_xfer(MYSPI, 0x4A000FA0);
   
   // Borrar todos los bits de STATUS
   spi_xfer(MYSPI, 0x5E000000);
   
   // Mask=0x800000 -> INT=DRDY Ciclo de computado terminado
   spi_xfer(MYSPI, 0x74800000);
   
   //Conversión contínua
   spi_xfer(MYSPI, 0xE8, 8);   
}


void main()
{
   int32 recibido;
   output_high(LED);
   delay_ms(1000);
   output_low(LED);
   
   fprintf(SERIE, "Iniciando dispositivo...");
   output_low(RESET);
   delay_ms(200);
   output_high(RESET);
   delay_ms(100);
   CS5463_init();   
   fprintf(SERIE, "OK\r\n\r\n");
   
   for(;;)
   {
      // Lee Temperatura
      recibido=spi_xfer(MYSPI, 0x26FFFFFF);
      fprintf(SERIE, "Temperatura: \t%LX\r\n", recibido);     
     
      // Lee IRMS
      recibido=spi_xfer(MYSPI, 0x16FFFFFF);
      fprintf(SERIE, "Corriente: \t%LX\r\n", recibido);
     
      // Lee VRMS
      recibido=spi_xfer(MYSPI, 0x18FFFFFF);
      fprintf(SERIE, "Voltaje: \t%LX\r\n", recibido);
     
      // Borra todos los bits de STATUS
      spi_xfer(MYSPI, 0x5E800000);
     
      delay_ms(1000);
   }

Debo comenrtar que las entradas Vin+- y Iin+- estan cortocircuitadas, para que la entrada del comparador  sea cero, aunque, todavía no calibro el chip.

dejaré el tema abirto hasta que verifique que funciona bien...

Saludos a todos y muchas gracias
Título: (Solucionado) Ayuda con SPI y CS5463
Publicado por: cyberpex en 15 de Junio de 2011, 04:13:37
Finalmente funciona!!

Pongo el código que muestra el valor de las variables (en hexa) refresca cada 5 segundos y manda la info por serie:

Código: [Seleccionar]
#include <18f252.h>
#fuses HS,NOWDT
#use delay(clock=20MHz)
#use spi(FORCE_HW, MODE=0, MASTER, stream=MYSPI, BAUD=400000, BITS=8)
#use rs232(baud=19200, uart1, ERRORS, stream=SERIE)

//constantes
#define INT    PIN_B1
#define CS     PIN_B3
#define LED    PIN_B4
#define RESET  PIN_B5

const char VARIABLE[32][30]=
{  
   "Configuration................",
   "Current DC Offset............",
   "Current Gain.................",
   "Voltage DC Offset............",    
   "Voltage DC Gain..............",      
   "N............................",      
   "Pulse Rate...................",      
   "Instantaneous Current........",      
   "Instantaneous Voltage........",      
   "Instantaneous Power..........",      
   "Active Power.................",      
   "RMS Current..................",      
   "RMS Voltage..................",      
   "Epsilon......................",      
   "Power Offset.................",      
   "Status.......................",      
   "Current AC Offset............",      
   "Voltage AC Offset............",      
   "Operation Mode...............",      
   "Temperature..................",      
   "Average Reactive Power.......",      
   "Instantaneous Reactive Power.",      
   "Peak Current.................",      
   "Peak Voltage.................",    
   "Reactive Power (Triangle)....",      
   "Power Factor.................",      
   "Interrupt Mask...............",      
   "Apparent Power...............",      
   "Control......................",      
   "Harmonic Active Power........",      
   "Fundamental Active Power.....",      
   "Fundamental Reactive Power..."
};
      
//Comandos
#define CONFIG       0
#define I_DCOFF      1
#define I_GN         2
#define V_DCOFF      3
#define V_GN         4
#define CYCLECOUNT   5
#define PULSERATEE   6
#define I            7
#define V            8
#define P            9
#define P_ACTIVE     10
#define I_RMS        11
#define V_RMS        12
#define EPSILON      13
#define P_OFF        14
#define STATUS       15
#define I_ACOFF      16
#define V_ACOFF      17
#define MODE         18
#define T            19
#define Q_AVG        20
#define Q            21
#define I_PEAK       22
#define V_PEAK       23
#define Q_TRIG       24
#define PF           25
#define MASK         26
#define S            27
#define CTRL         28
#define P_H          29
#define P_F          30
#define Q_F          31



//variables globales

//definicion de funciones

void CS5463_init()
{
   // Software reset
   output_low(CS);
   spi_xfer(0x80);
   output_high(CS);
   delay_ms(200);
  
   //Registro de configuración: Int activo bajo; HPF=1, K=1
   output_low(CS);
   spi_xfer(0x40);
   spi_xfer(0x00);
   spi_xfer(0x00);
   spi_xfer(0x61);
   output_high(CS);
    
   //N=4000  cristal de 4,096MHz
   output_low(CS);
   spi_xfer(0x4A);
   spi_xfer(0x00);
   spi_xfer(0x0F);
   spi_xfer(0xA0);
   output_high(CS);
  
   // Borrar todos los bits de STATUS
   output_low(CS);
   spi_xfer(0x5E);
   spi_xfer(0x00);
   spi_xfer(0x00);
   spi_xfer(0x00);
   output_high(CS);
  
   // Mask=0x800000 -> INT=DRDY Ciclo de computado terminado
   output_low(CS);
   spi_xfer(0x74);
   spi_xfer(0x80);
   spi_xfer(0x00);
   spi_xfer(0x00);
   output_high(CS);
  
   //Conversión contínua
   output_low(CS);
   spi_xfer(0xE8);    
   output_high(CS);
  
}

int32 leer_CS5463(int registro)
{
   int h_byte, m_byte, l_byte;
   output_low(CS);
   spi_xfer(registro<<1);
   h_byte=spi_xfer(0xff);
   m_byte=spi_xfer(0xff);
   l_byte=spi_xfer(0xff);
   output_high(CS);
   return(make32(0,h_byte,m_byte,l_byte));  
}


void main()
{
   int32 resultado;
   int cont, temperatura;
   output_high(LED);
   delay_ms(1000);
   output_low(LED);
  
   fprintf(SERIE, "\fIniciando dispositivo...");
   output_low(RESET);
   delay_ms(200);
   output_high(RESET);
   delay_ms(100);
   CS5463_init();  
   fprintf(SERIE, "OK\r\n\r\n");
   delay_ms(500);
  
   for(;;)
   {
      fprintf(SERIE, "\f");      
      for(cont=0; cont<32;cont++)
      {
         resultado = leer_CS5463(cont);
         fprintf(SERIE, "%s%LX",VARIABLE[cont], resultado);
         if(cont%2)
            fprintf(SERIE, "\r\n");
         else
            fprintf(SERIE, "   ");        
      }
      
      //Temperatura
      resultado = leer_CS5463(T);
      temperatura = make8(resultado, 2);
      fprintf(SERIE, "\r\n Temperatura actual: %d grados Celsius",temperatura);
      
      delay_ms(5000);
   }
}

Y la salida del terminal es:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=35036.0;attach=16024;image)

Falta por comprobar los valores agregando la etapa de alterna y calibrar el dispositivo.

En tanto tenga la placa definitiva cuelgo algo, para el que le pueda servir.

Saludos

Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 15 de Junio de 2011, 10:32:06
Buenísimo! Vas a observar, por lo menos me paso, que en AC hay que calibrar, pero hecho eso los resultados son muy buenos y se mantiene una excelente linealidad en todo el rango.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 03 de Agosto de 2011, 12:44:55
Hola muchachos,

Muy buen post, los felicito, me ha nutrido de información muy valiosa.
Estoy armando un proyecto con medidores CS5463 y MCU's ATMEGA128RFA1 (con protocolo ZigBee incorporado). La idea es conectar varios CS5463 en distintos toma corrientes de una casa, conectados por SPI a varios ATMEGA128RFA1, que tienen una antena donde transmiten la información de las mediciones a un MCU central donde se lo conecta a un PC.
He leído muchas veces el datasheet del Cirrus, pero la misma no es muy extensa en lo que refiere al bootloader. En la sección 8.1 dice algo así como Auto-boot Configuration. Por lo que entendí, la idea es poder cambiar los registros asignados por defecto y comenzar a registrar los valores de energía (tensión RMS, corriente, factor de potencia, etc, etc). Para ello, compré una de las EEPROM's SPI sugeridas por el fabricante: la AT25020A. Cirrus ofrece una secuencia como ejemplo, pero la misma no es muy clara, y no le encontré mucha utilidad. ¿Cómo lograron uds. decirle al CS5463  que comience a guardar valores en sus registros internos? ¿Tal vez no es necesario, y lo hace automático, sin necesidad del auto-boot secuence?

Gracias y saludos,
Gabriel
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 03 de Agosto de 2011, 13:07:43
Entiendo que el Auto-boot Configuration es para que el CS tomé la configuración de los registros de calibración desde una memoria externa y después comience a trabajar. Fíjate que enviando el comando 0xE8 el CS convierte continuamente...

Yo por ejemplo no uso eeprom, las configuraciones de cada CS están dentro de la memoria del micro y se establece cuando se inicia.

Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 03 de Agosto de 2011, 14:11:47
Entiendo que el Auto-boot Configuration es para que el CS tomé la configuración de los registros de calibración desde una memoria externa y después comience a trabajar. Fíjate que enviando el comando 0xE8 el CS convierte continuamente...

Yo por ejemplo no uso eeprom, las configuraciones de cada CS están dentro de la memoria del micro y se establece cuando se inicia.

Saludos!

Así que tal vez no sea necesaria ni la EEPROM ni ningún programador?

Gracias,
Gabriel
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 03 de Agosto de 2011, 14:16:16
No es necesario, es un adicional que se ofrece.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 03 de Agosto de 2011, 14:20:23
No es necesario, es un adicional que se ofrece.


Saludos!

Gracias Suky! Me has alegrado el día. Mandé las placas a soldar, en cuanto estén prontas, intentaré recabar datos desde el micro. Los mantendré informados.

Saludos,
Gabriel
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 03 de Agosto de 2011, 14:22:57
Hechas las placas lo que queda es calibrarlos individualmente, guardar esos valores que son lo que se establecen al inicializar el dispositivo. Los valores los podes guar en la memoria del microcontrolador  ;-)


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 18 de Agosto de 2011, 18:37:45
Hola nuevamente,

He terminado la interfaz a la red monofásica. La hice como sugiere el fabricante, a través de un shunt resistor de 5m ohm y un divisor de tensión con una resistencia de 470ohm, y la otra de 1Mohm. En el divisor se utilizaron dichos valores para tener un voltaje de 106.07mV RMS, mientras que el shunt es de 5m ohm para una tensión de 106.07mV RMS y una corriente de 20A RMS.
En cuanto a las resistencias y capacitores que se utilizan para filtrar el ruido (la hoja de datos no da los valores), utilicé todas las resistencias de 100ohm (RI+, RI-, RV+, RV-), los capacitores:

CV+=4.7nF
CV-=100pF
CI+=0.1uF
CI-=0.1uF
CVDiff=4.7nF
No estoy utilizando CIDiff.

En cuanto a la tierra (ACGND), uní las intersecciones de todos los capacitores (salvo CVDiff), de igual forma que lo sugiere Cirrus, y conecté la unión al vivo de la línea.

Para testear el funcionamiento, conecté la pinza del osciloscopio (negativo) a ACGND, y la punta (positivo) a la salida VIN+. Con esto, tome una fotografía, para ver la forma de onda. Obtuve la siguiente imagen:

(http://img38.imageshack.us/img38/3603/tenmx.th.jpg) (http://imageshack.us/photo/my-images/38/tenmx.jpg/)

Luego hice lo mismo, pero para la corriente. Obtuve la siguiente imagen:

(http://img842.imageshack.us/img842/3245/corrp.th.jpg) (http://imageshack.us/photo/my-images/842/corrp.jpg/)

Para la primera, Vpico=240mV
Para la segunda, Vpico=130mV

Claramente se ve que la forma de onda esta distorcionada. Lo curioso, es que no varió la forma de onda al conectarle carga. Nota: no conecté el Cirrus para evitar fallas.

FINALMENTE, conecté la pinza del osciloscopio a VIN- y la punta a VIN+, deseando ver una hermosa onda senoidal de 106mVRMS. (Sin carga). Resultado: se quemó instantáneamente la resistencia de 100ohm RV-. Y no comprendo porque (todas las resistencias de 100ohm son de 1/4W, mientras que las del divisor son de 2W).

Qué experiencias han tenido ustedes con la interfaz analógica?

Saludos,
Gabriel
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 26 de Agosto de 2011, 14:06:44
El problema estaba en la medición. Al enchufar el osciloscopio con un cable de 3 patas, no se estaba referenciando contra el vivo. Ahora aparecen formas de onda aceptables.

Con respecto al Cirrus, conecté las entradas diferenciales como corresponde, VA+ a la salida del rectificador, y ACGDN es la tierra, conectada al vivo. Conecté la punta del osciloscopio a E1 para ver si aparecían los pulsos de energía con la frecuencia proporcional a la potencia...pero no. Solo observo ruido...
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 26 de Agosto de 2011, 14:49:02
El problema estaba en la medición. Al enchufar el osciloscopio con un cable de 3 patas, no se estaba referenciando contra el vivo. Ahora aparecen formas de onda aceptables.

Con respecto al Cirrus, conecté las entradas diferenciales como corresponde, VA+ a la salida del rectificador, y ACGDN es la tierra, conectada al vivo. Conecté la punta del osciloscopio a E1 para ver si aparecían los pulsos de energía con la frecuencia proporcional a la potencia...pero no. Solo observo ruido...


Pero lo inicializaste? Hay que indicarle por SPI, conversión continua o conversión única.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 26 de Agosto de 2011, 17:10:01
Aún no tenemos pronto el sócalo para el MCU, estará listo el lunes. ¿Será que por defecto hace una única conversión , y por eso no se observaron pulsos en E1?

Gracias Suky, como siempre.
Gabriel
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 26 de Agosto de 2011, 17:43:43
Aún no tenemos pronto el sócalo para el MCU, estará listo el lunes. ¿Será que por defecto hace una única conversión , y por eso no se observaron pulsos en E1?

Gracias Suky, como siempre.
Gabriel

No, no hace nada. Porque hay varios parámetros que ajustar y luego iniciar conversiones.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 08 de Septiembre de 2011, 18:23:51
Hola Suky,

Desde el lunes que me estoy tratando de comunicar con el cirrus. Ayer encontré un programa llamado SPIGen que utiliza el puerto paralelo del PC. Lo que hace es simplemente comunicarse por SPI hacia algun dispositivo que tenga SPI. O sea, leer y escribir. Cuando se hace un comando de lectura, el PC muestra el valor del registro del dispositivo externo.
Ayer estuve probando dialogar (sin conectar las entradas diferenciales, sólo la fuente de 5v) y nunca tuve respuesta del cirrus. Entonces hoy hice lo mismo, pero con las entradas conectadas.

En el momento de enchufar, comenzó a salir humo por el puerto paralelo. Puede haber sido un desbalance de tierras, porque no uní las tierras del cirrus con la del paralelo. También puede haber sido un desbalance producido por el osciloscopio, que estaba conectado a SCLK.

Tienes idea que puede haber sucedido?

Seguramente compre un adaptador SSOP24 a DIP 24, para trabajar con el chip más tranquilo. Y comenzaré desde cero, porque cosas como estan no pueden suceder. Algo así sería: http://www.ebay.com/itm/TSSOP24-SSOP24-SSOP-DIP24-Adapter-Universal-Xeltek-/220844857550?pt=LH_DefaultDomain_0&hash=item336b6118ce

Un abrazo,
Gabriel
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 08 de Septiembre de 2011, 19:19:49
No conectar las tierra fue una posible causa, y siendo el puerto paralelo muy sensible, dudo que esté en condiciones  :tongue: Aparte de la tensión de 5V, colocaste algún oscilador o cristal?

Seguramente compre un adaptador SSOP24 a DIP 24, para trabajar con el chip más tranquilo. Y comenzaré desde cero, porque cosas como estan no pueden suceder. Algo así sería: http://www.ebay.com/itm/TSSOP24-SSOP24-SSOP-DIP24-Adapter-Universal-Xeltek-/220844857550?pt=LH_DefaultDomain_0&hash=item336b6118ce

 :shock: Interesante adaptador! No había visto de ese estilo


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: MGLSOFT en 08 de Septiembre de 2011, 23:19:15
Lindo adaptador!!
A ese precio ya no te conviene comprar el medidor hecho?? :D :D
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: cyberpex en 13 de Septiembre de 2011, 11:50:08
Hola Suky...
cuales fueron los pasos para calibrar el CS5463?

he dejado un poco de lado esta parte porque estaba reviviendo un equipo ethernet que quiero conectarle a este equipo...

Además tengo otro problema, cuando pido valores consecutivos de una variable (Vrms, por ejemplo) y luego pido una variable distinta (Irms, por ejemplo) me llega el valor de la primera variable (Vrms) en vez de la que pedí (Irms). Cuando la vuelvo a pedir funciona bien, pero si cambio pasa lo mismo. Te ha pasado algo así? Hay una solución más elegante que pedir 2 veces el dato?

te adjunto el código que estoy usando

Código: [Seleccionar]
#include <18f252.h>
#fuses HS,NOWDT
#use delay(clock=20MHz)
#use spi(FORCE_HW, MODE=0, MASTER, stream=MYSPI, BAUD=400000, BITS=8)
#use rs232(baud=19200, uart1, ERRORS, stream=SERIE)

//constantes
#define INT    PIN_B1
#define E1     PIN_B2
#define E3     PIN_B0
#define SIGNO  PIN_B3
#define CS     PIN_B4
#define RST    PIN_B5
#define LED    PIN_C1


//Ordenes Serie
#define LEER          'T'

//variables globales
int32 EA_consumida=0, EA_entregada=0, EA_total=0;
int32 ER_consumida=0, ER_entregada=0, ER_total=0;
int32 EA_delta=0, ER_delta=0;

int8 recibido[16];
int8 index=0;
int8 comm, param1, param2, param3;
int8 h_byte, m_byte, l_byte;
int1 error = 0;
int1 flagDebug = 0;
int1 flagProcesar = 0;


//definicion de funciones
void CS5463_init();
int32 leer_CS5463(int registro);
void sincronizar_CS5463();
int ghex(char digit1, char digit2);

//interrupciones
#INT_EXT2
void EA()
{
   if(input(SIGNO))
   {
      EA_consumida++;
      EA_total++;
      EA_delta++;
   }
   else
   {
      EA_entregada++;
      EA_total--;
      EA_delta--;
   }   
}

#INT_EXT
void ER()
{
   if(input(SIGNO))
   {
      ER_consumida++;
      ER_total++;
      ER_delta++;
   }
   else
   {
      ER_entregada++;
      ER_total--;
      ER_delta--;
   }   
}

#INT_RDA
void comunicacion()
{   
   if(kbhit(SERIE))
   {
      recibido[index] = toupper(fgetc(SERIE));
      if (flagDebug)
      {
         fputc(recibido[index],SERIE); //Debug
      }
      if((recibido[index]!='\r')&&(recibido[index]!='\n'))
      {
         if(index<16)
         {
            index++;
         }
         else
         {
            index=0;
         }         
      }
      else if ((recibido[index]=='\n'))
      {
         recibido[index]='\0';
         flagProcesar = 1;
         index=0;
         disable_interrupts(INT_RDA);         
      }     
   }

}

// Función Principal
void main()
{   
   output_high(LED);
   delay_ms(1000);
   output_low(LED);
   
   fprintf(SERIE, "\fIniciando dispositivo...");
   output_low(RST);
   delay_ms(200);
   output_high(RST);
   delay_ms(100);
   //CS5463_init();   
   fprintf(SERIE, "OK\r\n\r\n");
   delay_ms(500);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT2);
   enable_interrupts(GLOBAL);
   
   for(;;)
   {
      if(flagProcesar)
      {
         output_high(LED);
         comm=0;
         param1=0;
         param2=0;
         param3=0;
         
         switch(recibido[0])
         {
            case 'R':
            {
               comm=ghex(recibido[1], recibido[2]);
               if(!error)
               {                 
                  output_low(CS);
                  spi_xfer(comm);
                  h_byte=spi_xfer(0xff);
                  m_byte=spi_xfer(0xff);
                  l_byte=spi_xfer(0xff);
                  output_high(CS);
                  if(flagDebug)
                  {
                     fprintf(SERIE, "LEIDO: (%X)%X%X%X\r\n", comm, h_byte, m_byte, l_byte ); //Debug
                  }
                  else
                  {
                     fputc(h_byte, SERIE);
                     fputc(m_byte, SERIE);
                     fputc(l_byte, SERIE);
                  }
               }
               else
               {
                  error = 0;
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
               }
               break;
            }
           
            case 'W':
            {
               comm=ghex(recibido[1], recibido[2]);
               param1=ghex(recibido[3], recibido[4]);
               param2=ghex(recibido[5], recibido[6]);
               param3=ghex(recibido[7], recibido[8]);
               if(!error)
               {                 
                  output_low(CS);
                  spi_xfer(comm);
                  spi_xfer(param1);
                  spi_xfer(param2);
                  spi_xfer(param3);
                  output_high(CS);
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ESCRITO: (%X)%X%X%X\r\n", comm, param1, param2, param3); //Debug                 
                  }
                  else
                  {
                     fputc(0x00, SERIE);
                  }
               }
               else
               {
                  error = 0;
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
                  else
                  {
                     fputc(0xff, SERIE);
                  }
               }
               break;
            }
           
            case 'I':
            {
               comm=ghex(recibido[1], recibido[2]);
               if(!error)
               {                 
                  output_low(CS);
                  spi_xfer(comm);
                  output_high(CS);
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ENVIADO: %X\r\n", comm); //Debug
                  }
                  else
                  {
                     fputc(0x00, SERIE);
                  }
               }
               else
               {
                  error = 0;
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
                  else
                  {
                     fputc(0xff, SERIE);
                  }
               }
               break;
            }
           
            case 'S':
            {
               output_low(CS);
               spi_xfer(0xff);
               spi_xfer(0xff);
               spi_xfer(0xff);               
               spi_xfer(0xfe);
               output_high(CS);
               if(flagDebug)
               {
                  fprintf(SERIE, "SINCRONIZADO.\r\n"); //Debug
               }
               else
               {
                  fputc(0x00, SERIE);
               }
               break;
            }
           
            case 'D':
            {
               if((recibido[1]=='D')&&(recibido[2]=='E')&&(recibido[3]=='B')&&(recibido[4]=='U')&&(recibido[5]=='G'))
               {               
                  flagDebug = 0;
                  fprintf(SERIE, "DEBUG DESACTIVADO.\r\n"); //Debug
               }
               else
               {
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
                  else
                  {
                     fputc(0xff, SERIE);
                  }
               }
               
               break;
            }
           
            case 'A':
            {
               if((recibido[1]=='D')&&(recibido[2]=='E')&&(recibido[3]=='B')&&(recibido[4]=='U')&&(recibido[5]=='G'))
               { 
                  flagDebug = 1;
                  fprintf(SERIE, "DEBUG ACTIVADO.\r\n"); //Debug                 
               }
               else
               {
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
                  else
                  {
                     fputc(0xff, SERIE);
                  }
               }
               break;
            }
           
            case 'E':
            {
               if(((recibido[1]=='A')||(recibido[1]=='R'))&&((recibido[2]=='C')||(recibido[2]=='E')||(recibido[2]=='T')||(recibido[2]=='D')))
               {
                  if(recibido[1]=='A')
                  {
                     switch(recibido[2])
                     {
                        case 'C':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "ENERGIA ACTIVA CONSUMIDA: %ld\r\n", EA_consumida);                                         
                           }
                           else
                           {
                              fputc(make8(EA_consumida,3), SERIE);
                              fputc(make8(EA_consumida,2), SERIE);
                              fputc(make8(EA_consumida,1), SERIE);
                              fputc(make8(EA_consumida,0), SERIE);
                           }
                           break;
                        }
                        case 'E':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "ENERGIA ACTIVA ENTREGADA: %ld\r\n", EA_entregada);                                         
                           }
                           else
                           {
                              fputc(make8(EA_entregada,3), SERIE);
                              fputc(make8(EA_entregada,2), SERIE);
                              fputc(make8(EA_entregada,1), SERIE);
                              fputc(make8(EA_entregada,0), SERIE);
                           }
                           break;
                        }
                        case 'T':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "ENERGIA ACTIVA TOTAL: %ld\r\n", EA_total);                                         
                           }
                           else
                           {
                              fputc(make8(EA_total,3), SERIE);
                              fputc(make8(EA_total,2), SERIE);
                              fputc(make8(EA_total,1), SERIE);
                              fputc(make8(EA_total,0), SERIE);
                           }
                           break;
                        }
                        case 'D':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "DELTA DE ENERGIA ACTIVA: %ld\r\n", EA_delta);                                         
                           }
                           else
                           {
                              fputc(make8(EA_delta,3), SERIE);
                              fputc(make8(EA_delta,2), SERIE);
                              fputc(make8(EA_delta,1), SERIE);
                              fputc(make8(EA_delta,0), SERIE);
                           }
                           EA_delta = 0;
                           break;
                        }                       
                     }
                  }
                  else if(recibido[1]=='R')
                  {
                     switch(recibido[2])
                     {
                        case 'C':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "ENERGIA REACTIVA CONSUMIDA: %ld\r\n", ER_consumida);                                         
                           }
                           else
                           {
                              fputc(make8(ER_consumida,3), SERIE);
                              fputc(make8(ER_consumida,2), SERIE);
                              fputc(make8(ER_consumida,1), SERIE);
                              fputc(make8(ER_consumida,0), SERIE);
                           }
                           break;
                        }
                        case 'E':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "ENERGIA REACTIVA ENTREGADA: %ld\r\n", ER_entregada);                                         
                           }
                           else
                           {
                              fputc(make8(ER_entregada,3), SERIE);
                              fputc(make8(ER_entregada,2), SERIE);
                              fputc(make8(ER_entregada,1), SERIE);
                              fputc(make8(ER_entregada,0), SERIE);
                           }
                           break;
                        }
                        case 'T':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "ENERGIA REACTIVA TOTAL: %ld\r\n", ER_total);                                         
                           }
                           else
                           {
                              fputc(make8(ER_total,3), SERIE);
                              fputc(make8(ER_total,2), SERIE);
                              fputc(make8(ER_total,1), SERIE);
                              fputc(make8(ER_total,0), SERIE);
                           }
                           break;
                        }
                        case 'D':
                        {
                           if(flagDebug)
                           {
                              fprintf(SERIE, "DELTA DE ENERGIA REACTIVA: %ld\r\n", ER_delta);                                         
                           }
                           else
                           {
                              fputc(make8(ER_delta,3), SERIE);
                              fputc(make8(ER_delta,2), SERIE);
                              fputc(make8(ER_delta,1), SERIE);
                              fputc(make8(ER_delta,0), SERIE);
                           }
                           ER_delta = 0;
                           break;
                        }                       
                     }
                  }
               }               
               else
               {
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
                  else
                  {
                     fputc(0xff, SERIE);
                  }
               }
               break;
            }
           
            case 'H':
            {
               if((recibido[0]=='H')&&(recibido[1]=='E')&&(recibido[2]=='L')&&(recibido[3]=='P'))
               { 
                  fprintf(SERIE, "\r\n");
                  fprintf(SERIE, "*********************************************************\r\n");
                  fprintf(SERIE, "*                    COMANDOS                           *\r\n");
                  fprintf(SERIE, "*********************************************************\r\n");
                  fprintf(SERIE, "* HELP     : Muestra esta ayuda.                        *\r\n");
                  fprintf(SERIE, "* IXX      : Ejecuta la instruccion XX.                 *\r\n");                 
                  fprintf(SERIE, "* S        : Sincroniza reloj SPI                       *\r\n");
                  fprintf(SERIE, "* RXX      : Lee el registro XX                         *\r\n");
                  fprintf(SERIE, "* WXXYYYYYY: Escribe en el registro XX el valor YYYYYY. *\r\n");
                  fprintf(SERIE, "* ADEBUG   : Activa DEBUG.                              *\r\n");
                  fprintf(SERIE, "* DDEBUG   : Desactiva DEBUG.                           *\r\n");
                  fprintf(SERIE, "* EAC      : Energia Activa Consumida.                  *\r\n");
                  fprintf(SERIE, "* EAE      : Energia Activa Entregada.                  *\r\n");
                  fprintf(SERIE, "* EAT      : Energia Activa Total.                      *\r\n");
                  fprintf(SERIE, "* ERC      : Energia Reactiva Consumida.                *\r\n");
                  fprintf(SERIE, "* ERE      : Energia Reactiva Entregada.                *\r\n");
                  fprintf(SERIE, "* ERT      : Energia Reactiva Total.                    *\r\n");
                  fprintf(SERIE, "* EAD      : Delta Energia Activa.                      *\r\n");
                  fprintf(SERIE, "* ERD      : Delta Energia Reactiva.                    *\r\n");
                  fprintf(SERIE, "*********************************************************\r\n");
                  fprintf(SERIE, " NOTA1: XX es un numero hexadecimal de 2 cifras.\r\n");
                  fprintf(SERIE, " NOTA2: YYYYYY es un numero hexadecimal de 6 cifras.\r\n");
                  fprintf(SERIE, "\r\n");                 
               }
               else
               {
                  if(flagDebug)
                  {
                     fprintf(SERIE, "ERROR EN LA SINTAXIS DEL COMANDO.\r\n"); //Debug
                  }
                  else
                  {
                     fputc(0xff, SERIE);
                  }
               }
               break;
            }
           
            default:
            {
               if(flagDebug)
               {               
                  fprintf(SERIE, "COMANDO NO VALIDO.\r\n"); //Debug
               }
               else
               {
                  fputc(0xff, SERIE);
               }
            }           
         }
         flagProcesar = 0;         
         enable_interrupts(INT_RDA);
         output_low(LED);
      }
   }
}

void CS5463_init()
{
   // Software reset
   output_low(CS);
   spi_xfer(0x80);
   output_high(CS);
   delay_ms(200);
   
   //Registro de configuración: Int activo bajo; HPF=1, K=1
   output_low(CS);
   spi_xfer(0x40);
   spi_xfer(0x00);
   spi_xfer(0x00);
   spi_xfer(0x00);
   output_high(CS);
   
   //N=4000  cristal de 4,096MHz
   output_low(CS);
   spi_xfer(0x4A);
   spi_xfer(0x00);
   spi_xfer(0x0F);
   spi_xfer(0xA0);
   output_high(CS);
   
   // Borrar todos los bits de STATUS
   output_low(CS);
   spi_xfer(0x5E);
   spi_xfer(0x80);
   spi_xfer(0x00);
   spi_xfer(0x01);
   output_high(CS);
   
   // Mask=0x000000 -> INT=DRDY Ciclo de computado terminado
   output_low(CS);
   spi_xfer(0x74);
   spi_xfer(0x00);
   spi_xfer(0x00);
   spi_xfer(0x00);
   output_high(CS);
   
   //Conversión contínua
   output_low(CS);
   spi_xfer(0xE8);   
   output_high(CS);
   
}

int32 leer_CS5463(int registro)
{
   int h_byte, m_byte, l_byte;
   output_low(CS);
   spi_xfer(registro<<1);
   h_byte=spi_xfer(0xff);
   m_byte=spi_xfer(0xff);
   l_byte=spi_xfer(0xff);
   output_high(CS);
   return(make32(0,h_byte,m_byte,l_byte));   
}

void sincronizar_CS5463()
{
   output_low(CS);
   spi_xfer(0xff);
   spi_xfer(0xff);
   spi_xfer(0xff);
   spi_xfer(0xff);
   spi_xfer(0xfe);
   output_high(CS);   
}

int ghex(char digit1, char digit2)
{
   int8 temp_int1, temp_int2;
   int8 respuesta=0xff;
   
   if(((digit1>='0' && digit1<='9')||(digit1>='A' && digit1<='F'))&&((digit2>='0' && digit2<='9')||(digit2>='A' && digit2<='F')))
   {
      if(digit1<='9')
         temp_int1 = digit1-'0';
      else
         temp_int1 = (digit1-'A')+10;
     
      if(digit2<='9')
         temp_int2 = digit2-'0';
      else
         temp_int2 = (digit2-'A')+10;
         
      respuesta = (temp_int1<<4)+temp_int2;
   }
   else
   {
      error=1;
      if(flagDebug)
      {
         fprintf(SERIE, "ERROR EN LA ENTRADA %c%c.\r\n", digit1, digit2); //Debug
      }
   }
   
   return(respuesta);
}

Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: cyberpex en 13 de Septiembre de 2011, 12:03:24
El código anterior es el que utilizo para optoacoplar el medidor al controlador principal.
se comunica por serie (con optoacopladores) y un PIC18F252 hace la interfaz SPI, además de contar los pulsos de energía activa y reactiva.

Este micro recibe las ordenes en texto plano:

IXX: Escribe la instrucción XX (ejm: I80)
RXX: Lee el registro XX (ejm: R26 lee y devuelve 3 bytes de Temperatura)
WXXYYYYYY: Escribe el registro XX con los datos YYYYYY)
S: Sincroniza el reloj SPI (FFFFFFFE)

eso, la magia la hace la otra plca, inicio y configuración
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 13 de Septiembre de 2011, 12:33:21
En este mensaje deje como realizo la lectura de los registro: http://www.todopic.com.ar/foros/index.php?topic=35036.msg292486#msg292486

nunca me ha dado el problema que comentas.


Respecto a la calibración, los pasos idénticos que indica el datasheet.


Saludos!
Título: Ayuda con SPI y CS5463
Publicado por: medidort en 29 de Diciembre de 2011, 09:14:48
Hola
Estoy tratando de construir un medidor de energia con un PIC 16F690 y un CS5463 utilizando Mplab con HiTech.
Tengo un par de dudas.
Como configuran el SPI. Yo lo estoy configurando al pic como maestro y al cirrus como esclavo. El reloj del cirrus es de 4.096MHz y el del 16F690 es de 4MHz.
Tambien tengo dudas de que asignarle al CKE y al CKP dado que la hoja del cirrus no dice nada. Alguien lo sabe?
Tengo conectado los chips de la siguiente manera.
PIC16F609 ----- CS5463
RC2   ------------> CS
SDO -------------> SDI
SDI  <------------- SDO
SCK ---------------> SCK

Hay que hacer algo mas como conectar resistencias de pull up u alguna otra cosa.

Tambien tengo dudas en los pedidos al cirrus; alguien sabe efectivamente como se hacen las preguntas al CS5463?
Yo estoy pidiendo de la siguiente manera. Esta bien? Si esta mal me podrían decir como lo hacen?

void CIRRUS_readVoltage(void){
   CS = 0;
   SPI_write(0x18);
   datoH = SPI_read();
   SPI_write(0xFF);
   datoM = SPI_read();   
   SPI_write(0xFF);
   datoL = SPI_read();   
   SPI_write(0xFF);
   CS= 1;
}

Las funciones de spi las hice yo leyendo la hoja datos pues no encontré en HiTech librerías para SPI ni para delay. Si alguien las tiene agradeceria que me las pasaran o me dijeran donde.

void SPI_write(char data){                
    SSPBUF = data;   
}

char SPI_read(void){
    char data;
      
    while(!BF){}
    data = SSPBUF;
    return data;
}


void configuracionPuertos(void){
   //PARA SPI
   //1 INPUT / 0 OUTPUT
   //Todo como salida menos el RA0
   TRISA = 0b00100001;
   PORTA = 0x00;
   //PORTB todo como salida
   //SCK (Master mode) must have TRISB<6> bit   cleared
   TRISB = 0b00110000; //RB6-SCK out
   PORTB = 0x00; //APAGADO
   //PORTC, los dos primeros son para la USART
   //SDO must have TRISC<7> bit cleared
   //SS must have TRISC<6> bit set
   TRISC = 0b01000000;
   PORTC = 0x00;
}



void configuracionInterrupciones(void){
   //------PIE1 Bits REGISTRO DE HABILITACION------   
   ADIE   = 0;  //DesHabilito Interrupcion del A/D                     
   RCIE   = 0;    //DesHabilito Interrupcion en la USART               
   TXIE   = 0;  //Deshabilito Interrupcion en la USART               
   SSPIE  = 0;  //DesHabilito Interrupcion en la SPI             
   CCP1IE = 0;  //Deshabilito la interrupcion del comparador                 
   TMR2IE = 0;  //DesHabilito Interrupcion TIMER2                     
   TMR1IE = 0;  //DesHabilito Interrupcion TIMER1 

   //------PIE2 Bits REGISTRO DE HABILITACION------   
   EEIE=0;
   OSFIE = 0;
   C2IE= 0;
   C1IE = 0;

   //---------INTCON Bits REGISTRO DE HABILITACION------                   
   GIE    = 0;     //Interrupciones Globales    
   PEIE   = 0;     //Interrupciones Externas                     
   //T0IE   = 0;   //Termino el Timer 0                             
   //INTE   = 0;   //Cambio en la pata RB0       
    //RABIE   = 0;  //Cambio en el puerto B
}


void configuracionSPI(void){

   //---------SSPCON: SYNC SERIAL PORT CONTROL REGISTER--------------
   SSPCON = 0b00100000;
   SSPSTAT = 0b10000000;
   SSPEN = 1
   

}

Desde ya muchas gracias a todos y felices fiestas
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 29 de Diciembre de 2011, 19:13:48
Lee el siguiente mensaje en detenimiento, mucho de lo que preguntas está allí: http://www.todopic.com.ar/foros/index.php?topic=35036.msg292486#msg292486

Sobre como conectar SPI, la única linea que puede llegar a llevar una resistencia pull-up es CS.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 30 de Diciembre de 2011, 08:26:41
Hola
Leí como me recomendaste nuevamente tu post, ya lo había hecho.
Lo único que no me queda claro es como haces el pedido al CS5463.
Según lo que he leído se debería escribir el comando y luego leer dato, escribir FF, leer dato, escribir FF , leer dato y escribir FF.
Esto es asi?

Que hiciste con la pata PFMON del chip?

Desde ya muchas gracias y feliz año nuevo
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 30 de Diciembre de 2011, 10:09:19
Hola
Leí como me recomendaste nuevamente tu post, ya lo había hecho.
Lo único que no me queda claro es como haces el pedido al CS5463.
Según lo que he leído se debería escribir el comando y luego leer dato, escribir FF, leer dato, escribir FF , leer dato y escribir FF.
Esto es asi?

Deberías leer sobre el protocolo SPI, es full-duplex, o sea mientras envías puedes recibir al mismo tiempo. Entonces envías el comando, y mientras lees envías 0xFF por especificación de datasheet. Las funciones para trabajar con SPI entre C30 y CCS son muy distintas, entonces aprende a trabajarlo en el lenguaje que usas  ;-)

Para FPMON podes leer el datasheet, allí explica como funciona y a partir de ellos podes armar un divisor resistivo para que trabaje. Sino a 5 V y listo.



Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 30 de Diciembre de 2011, 11:30:07
Gracias por todo. La datasheet del CS5463 no dice claramente como hacer los pedidos.
Ahora no me imagino como enviar y recibir al mismo tiempo con el SPI siendo que tiene un solo registro para mandar y enviar el SSPBUF.
Haces algún control entre la lectura y la escritura? dejas pasar algún tiempo?
Gracias
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 30 de Diciembre de 2011, 13:44:29
Bueno, si se ignora como funciona el microcontrolador y además se ignora como trabaja el compilador es un poco complicado  :tongue: Yo como se trabaja en Hi-tech ni idea, pero por ejemplo en C18 se puede implementar:

Código: C
  1. UINT8 ReadDevice(void){
  2.       UINT8 TempVar;
  3.    
  4.       TempVar = SSPBUF;      
  5.       SSPBUF = 0xFF;          
  6.       while (!SSPSTATbits.BF);
  7.       return ( SSPBUF );                
  8. }
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 30 de Diciembre de 2011, 16:11:53
Bueno, si se ignora como funciona el microcontrolador y además se ignora como trabaja el compilador es un poco complicado  :tongue: Yo como se trabaja en Hi-tech ni idea, pero por ejemplo en C18 se puede implementar:

Código: C
  1. UINT8 ReadDevice(void){
  2.       UINT8 TempVar;
  3.    
  4.       TempVar = SSPBUF;      
  5.       SSPBUF = 0xFF;          
  6.       while (!SSPSTATbits.BF);
  7.       return ( SSPBUF );                
  8. }

Una acusacion fuerte. Yo conozco como funciona el micro, lo que no conozco y la hoja de datos no me lo dice no lo puedo saber. Si te fijas en la hoja del cirrus no hay ejemplos de leer y escribir al mismo tiempo. El codigo SPI lo tengo implementado, el tema es que la hoja de datos del CS5463 no dice que modo SPI tiene. Te agradezco el codigo de ejemplo.
Vos aca estas mandando 0xFF primero y después leyendo? Tu primera instruccion TempVar = SSPBUF;   es una lectura dummy?
Gracias por las respuestas.

Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 30 de Diciembre de 2011, 17:12:37
Ejemplo no creo que encuentres en un datasheet, pero por ejemplo para el CS5461A, en su datasheet encuentras el siguiente esquema:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=35036.0;attach=17427)


 :roll: Bastante claro me parece...
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 30 de Diciembre de 2011, 18:21:30
Ejemplo no creo que encuentres en un datasheet, pero por ejemplo para el CS5461A, en su datasheet encuentras el siguiente esquema:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=35036.0;attach=17427)


 :roll: Bastante claro me parece...

Vi esto en la hoja, el tema que el SSPBUF es el mismo para enviar y recibir, segun pienso yo es imposible mandar en el "mismo" SCK, por lo cual o leo o mando, eso entiendo yo. Si yo estoy leyendo en el SSPBUF y al mismo tiempo quiero mandar estaria pisando el dato que estoy recibiendo. Esta mal lo que te estoy diciendo?
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 30 de Diciembre de 2011, 20:04:52
No, no se pisa, sino sería un mal diseño  :mrgreen: Es un registro de desplazamiento, por un "lado" ingresa un bit y por otro sale. Por eso comento que veo poco conocimiento del funcionamiento del microcontrolador.




Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 02 de Enero de 2012, 09:01:11
No, no se pisa, sino sería un mal diseño  :mrgreen: Es un registro de desplazamiento, por un "lado" ingresa un bit y por otro sale. Por eso comento que veo poco conocimiento del funcionamiento del microcontrolador.




Saludos!

Lo lei y tambien lei en la hoja de datos que se puede pisar un dato con el otro.  Como no me quedo claro te lo preguntaba, mal yo por preguntar...
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: MGLSOFT en 02 de Enero de 2012, 09:25:16
Por favor ambos deberían bajar el tono de la conversación, uno que ayuda y otro que es ayudado, ya que de ese modo no avanzaran un solo paso y ambos perderán su propio tiempo... 
Feliz año 2012 !! :mrgreen:
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 02 de Enero de 2012, 10:29:47
No, no se pisa, sino sería un mal diseño  :mrgreen: Es un registro de desplazamiento, por un "lado" ingresa un bit y por otro sale. Por eso comento que veo poco conocimiento del funcionamiento del microcontrolador.

Saludos!

Lo lei y tambien lei en la hoja de datos que se puede pisar un dato con el otro.  Como no me quedo claro te lo preguntaba, mal yo por preguntar...


Se pisa si llega un segundo dato sin leer el anterior, no se pisa el dato que vas a enviar con el que llega... Una mezcla!  :shock:  :D

Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 02 de Enero de 2012, 10:52:06
Ok. Vos decis que si mando y recibo el SSPBUF no se pisa.
Voy a probarlo. Gracias por la info. Eso no fue lo que entendi de la hoja de datos.
Gracias
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 02 de Enero de 2012, 11:57:11
La hoja de datos no suele ser tan detallista, es más que nada sentido común. O sea, si SPI (http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus) es full-duplex no se puede pensar que se pisan los bit que envías con los que recibes  ;-)
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 02 de Enero de 2012, 16:23:31
Hola. Yo le agradezco a SUKY la ayuda que me dio y me esta dando.  Estoy acostumbrado a leer la hoja de datos y de ahí codificar. Como no lo pude resolver escribí en el foro.
Me sigue sin quedar muy claro como es que si yo escribo al mismo registro del que recibo como ese dato no se pisa. Según la hoja el dato lo recibe el SSPSR y cuando esta listo va al SSPBUF marcando la FLAG BF. La hoja de datos no dice nada de la transmisión y como funciona.
Yo deduje que si escribo al mismo SSPBUF en el cual recibo, el registro se pisa.
Me sigue sin quedar claro como cumplir con el diagrama de tiempos del CS5463.  yo tengo dos funciones implementadas y probadas SPI_write(char) y SPI_read().
Si quisiera pedirle al CS5463 voltaje yo tendria que mandar el comando 0x18 haciendo SPI_write(0x18) cuando termine esto que debo hacer? El tema es que si hago SPI_read y luego SPI_write no las hago al mismo tiempo. Hasta que no termino una función no llamo a la otra. Como es que tengo que hacer para poder cumplir con los diagramas de tiempo.
Gracias
Adrian

Estas son mis funciones de lee y escribir SPI.

void SPI_write(char data){

   char dummy=0x00;
                         
   SSPIF =0; 
   dummy=SSPBUF;                   
        SSPBUF = data;   
   while(SSPIF == 0){}     
         
}


char SPI_read(void){
   char data;

    while(!BF){};
      data = SSPBUF;
   return data;
}
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: MGLSOFT en 02 de Enero de 2012, 16:44:44
Si bien el SPI es full duplex, esto solo indica que no debe esperar que se desocupe la linea de transmisión para poder enviar un dato, porque son independientes una de otra.
lo que si va a esperar el integrado del otro lado es que le digas que dato enviar, para poder enviarlo.
para cuando el esclavo transmite su dato vos ya enviaste lo que necesitas recibir, por lo cual sspbuf ya estará vacío o al menos libre para recibir un dato.
Como tu escribes que hace el maestro, tu mismo originas como se produce ese flujo de ida y vuelta, sin encontronazos, por lo tanto no te hagas problemas.

En algunos casos, como conversores AD y otros casos que podria ser el tuyo, hay un comando que se envía por única vez y luego el esclavo transmite con una cadencia determinada el mismo dato continuamente, sin necesidad de volver a pedirlo, luego hay un comando que detiene ese envío, y por supuesto hay que esperar a enviarlo cuando recién termina de recibirse un dato desde el esclavo.
Tampoco en este caso se podrían superponer los datos en tu buffer...
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 02 de Enero de 2012, 16:57:54
El tema es que al escribir en el registro SSPBUF se genera clock para enviar el dato y al mismo tiempo se recibe. Podes verlo como un registro de desplazamiento (http://es.wikipedia.org/wiki/Registro_de_desplazamiento), por un lado ingresa el bit y por el otro sale.

Por ahí quieres hilar muy fino sin ser necesario, si realizas lo que pide el CD5461 aplicando el concepto de la comunicación SPI, con hacer esto basta:

Código: C
  1. char SPI_read(char DataOut){
  2.       char TempVar = SSPBUF;  
  3.    
  4.       SSPBUF = DataOut;           // Se carga dato a enviar
  5.       while (!SSPSTATbits.BF);    // Se espera que envie y a la vez se recibe
  6.       return ( SSPBUF );             // se retorna lectura
  7. }


Código: C
  1. ValueIRMS.HB= SPI_read(0xFF);
  2.         ValueIRMS.MB= SPI_read(0xFF);
  3.         ValueIRMS.LB= SPI_read(0xFF);


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 02 de Enero de 2012, 17:44:50
Ok. entonces supongo que como MASTER yo mando utilizando el SSPBUF antes de que el esclavo me mande su dato que ingresa al SSPSR y luego pasa al SSPBUF, es asi?
Gracias a ambos
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 02 de Enero de 2012, 19:48:44

1. Se carga valor de salida a SSPBUF.
2. Ese dato se carga en SSPSR.
3. Se generan 8 Clocks, donde se envía dato y se recibe a la vez.
4. El dato recibido se mueve a SSPBUF para ser accedido por el usuario.


Es mas o menos así, para hacer funcionar la comunicación no es necesario tratar de entender esto a fondo, necesitas tener más estudio de electrónica.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 05 de Enero de 2012, 20:36:10
Hola muchachos,

Después de mucho tiempo, vuelvo al post, ya que logré escribir y leer perfectamente los

registros del CS5463, pero no estoy pudiendo leer voltaje, ni corriente, ni potencia,

que es lo que más me interesa.

Supongo yo que el problema puede estar en la interfaz analógica, en el filtrado, pero me

gustaría escuchar su opinión. Como sensor de tensión, estoy utilizando un trafo reductor

a 13Vrms, y desde allí (del secundario) me conecto a un divisor de tensión, en cascada

con un filtro pasabajos RC y finalmente un capacitor diferencial.
Para la corriente estoy utilizando un transformador de corriente, conectado en serie a

la carga. Así que la intensidad es transducida en voltaje. Dicho voltaje es disminuído a

través de un divisor, luego un filtro pasabajos, y luego un capacitor diferencial (igual

que con la interfaz de voltaje).

En cuanto al código, debería de estar bien, ya que la comunicación SPI entre el micro y

el CS5463 funciona a la perfección. Antes de comenzar a leer registros, se ejecuta una

rutina de inicialización y configuración del Cirrus:

1- Reseteo del Cirrus con el comando 0x80 (SW reset)
2- Envío de 3 bytes FF y otro FE para la sincronización con el micro
3- Se escribe en el configuration register A2 A0 3D, que activa high pass filters y

selecciona K=1
4- Configuración del N, para un cristal de 4.096MHz, N=4000
5- Se borran los bits de status register
6- Habilito data ready interruptivo
7- El paso más importante: habilitación de conversiones continuas, enviando el comando

0xE8

Luego de estos pasos, el programa se queda en un loop leyendo el voltaje RMS y

enviándolo por SPI.

Les adjunto imágenes del circuito. A alguien se le puede ocurrir algo?

Saludos!!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: MGLSOFT en 05 de Enero de 2012, 21:38:17
Y las imagenes??
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 05 de Enero de 2012, 23:55:11
No pude adjuntarlas, así que las subí

Interfaz:
 (http://img718.imageshack.us/img718/4075/interfazp.jpg) (http://imageshack.us/photo/my-images/718/interfazp.jpg/)

Circuito completo:
 (http://img692.imageshack.us/img692/9637/circuitoqd.png) (http://imageshack.us/photo/my-images/692/circuitoqd.png/)


Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 10 de Enero de 2012, 18:33:44
Ninguna sugerencia? Que les parece la interfaz?

Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 10 de Enero de 2012, 20:08:53
Y PMON? Reset? Con respecto a la interfaz de entrada, implementé lo mismo, con otros valores de r y c, nada más.


Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 11 de Enero de 2012, 18:11:43
Y PMON? Reset? Con respecto a la interfaz de entrada, implementé lo mismo, con otros valores de r y c, nada más.

Qué frecuencia seleccionaste para los filtros de entrada de voltaje y corriente? Como ves, estoy filtrando hasta los 33.9KHz. Y como capacitores diferenciales, que valor sugerís usar?

PFMON olvidé incluirlo en el schematic, pero está soldado en el circuito (a través de dos resistencias de 10k cada una). No utilizo hardware reset, sólo lo hago por software. Por eso no utilizo dicha pata.

Saludos
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 11 de Enero de 2012, 19:18:42
Y PMON? Reset? Con respecto a la interfaz de entrada, implementé lo mismo, con otros valores de r y c, nada más.

Qué frecuencia seleccionaste para los filtros de entrada de voltaje y corriente? Como ves, estoy filtrando hasta los 33.9KHz. Y como capacitores diferenciales, que valor sugerís usar?

No me acuerdo y no tengo los archivos fuentes, pero era como 3kHz o 1.5kHz. Podes testear con un osciloscopio que nivel de señal de entrada ingresa el CS. Porque de alguna manera vas a tener que calibrarlo.


Saludos!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: medidort en 28 de Enero de 2012, 14:58:12
(http://Bibliotecas\Imágenes\spi.png)

Hola
He podido después de mucho tiempo escribir y pedirle al CS5463. Sigo teniendo problemas cuando leo los datos que vuelven del Cirrus al PIC.
Estoy tratando de leer el cycle count register que se que vale 4000 decimal, cuando leo deberia obtener en el MSB 0x00 , el del medio 0x0F y en el LSB 0xA0. Actualmente estoy obteniendo 0x00 0x00 y 0x00.
Sin embargo en el osciloscopio veo perfecto que el cirrus me manda el data que espero.
Como comentaba en post anteriores, me sonaba que iba a ver algún problema en el manejo del buffer al mismo tiempo. Adjunto el código de SPI  y de la rutina que implementé para leer el Cycle Count Register.

CODIGO SPI:
///////////////////////////////////////////////////////////////////
//Retorno:               void
//Parametro:      char ; El dato a enviar
//Descripcion:      Envia un dato por el puerto SPI
///////////////////////////////////////////////////////////////////
void SPI_write(char data){

   char dummy=0x00;
                        
   SSPIF =0;  
   dummy=SSPBUF;                  
        SSPBUF = data;   
   while(SSPIF == 0){}    
            
}

///////////////////////////////////////////////////////////////////
//Retorno:           char ;  el dato recibido
//Parametro:      void
//Descripcion:      Recibe un dato por el puerto SPI
///////////////////////////////////////////////////////////////////
char SPI_read(void){
   char data;

    while(!BF){};
      data = SSPBUF;
   return data;
}
  
CODIGO DE PEDIDO DE LECTURA
//Retorno:           void
//Parametro:      void
//Descripcion:      Funcion para pedir el voltaje el cual devuelvo los datos leidos
//               en los tres registros datoH, datoM, datoL.
//////////////////////////////////////////////////////////////////////////////////////
void CIRRUS_readCycleCountReg(void){

   RC2 = LOW; //CS =0
   SPI_write(0x0A);
   SPI_read();
   SPI_write(0xFF);
   datoH = SPI_read();
   SPI_write(0xFF);
   datoM = SPI_read();   
   SPI_write(0xFF);
   datoL = SPI_read();   
   RC2 = HIGH; //CS =1

}

(http://img99.imageshack.us/img99/5839/spir.th.png) (http://imageshack.us/photo/my-images/99/spir.png/)

Uploaded with ImageShack.us (http://imageshack.us)
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 17 de Febrero de 2012, 10:27:22
Buenas!

Finalmente FUNCIONA todo el sistema. Tenía problemas constructivos simplemente. Estuve realizando medidas, y todas ellas son coherentes.
Lo que sigue a continuación es la calibración. Leí la hoja de datos y no tiene ningún misterio, es seguir el orden establecido por Cirrus. El problema que tengo es que la placa está soldada, y no puedo conectarle a las entradas diferenciales señales de referencia externas (fuentes bien calibradas, para calibración de ganancia), ni cortocircuitar las entradas y ponerlas a tierra para hacer la calibración de offset, si bien no es tan importante (con HPF=1 no hay que hacer DC offset).

Lo que se me ocurre, al menos para hacer calibración de ganancia, es tomar como señales de referencia las entradas de lìnea (los 220v "achicados" por el divisor) y una corriente conocida, por ejemplo la de una bombita de 60w (obviamente achicada también, por el circuito adaptador de corriente).

Como hicieron ustedes? Utilizaron algún zócalo para desmontar el Cirrus y calibrarlo? Si hubiera sido encapsulado DIP...

Saludos
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: Suky en 17 de Febrero de 2012, 15:06:54
En nuestro caso se pensó el hardware con la posibilidad de configurarlo para la calibración  :mrgreen:
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 17 de Febrero de 2012, 15:56:34
En nuestro caso se pensó el hardware con la posibilidad de configurarlo para la calibración  :mrgreen:

 8) eso es previsión....tendré que hacer una placa nueva con switches para calibrar.....saludos
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 02 de Marzo de 2012, 10:30:47
Hola Estimados!

Estoy midiendo voltaje. El registro Vrms me da: 0xAF88B4. Para esto el valor de las entradas VIN+ y VIN- es 77.7mVrms cada una.

Como hago la regla de tres para obtener la medición en Español? Cuál es el fondo de escala de Vrms register? La hoja de datos es un poco confusa..

Gracias!
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 29 de Marzo de 2012, 10:04:49
Hola,

Tengo a todo el sistema funcionando correctamente, ya puedo leer voltaje, corriente, potencia, FP, etc.
Todas las cargas con FP cerca de 1 (resistivas), son medidas a la perfección: Ief, Vef, P, S, FP, etc.  :)

Lo extraño es que con cargas no lineales, cuyo FP es màs bajo, obtengo FP y P con un 10% de error. Será que PC[6:0] (phase compensation) del registro Configuration Register afecta a esto?
En este momento lo tengo configurado como PC[6:0]=000000.

Por otro lado, el bit AFC del Operational Mode Register lo tengo seteado (AFC=automatic line-frequency=1). Con esto detecto la frecuencia de línea automaticamente.

Que recomiendan?

Saludos
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: MGLSOFT en 29 de Marzo de 2012, 10:34:41
Podrías publicar tu hardware y firmware, para acelerar el proceso de los que aun no comenzamos con este tema??
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 29 de Marzo de 2012, 11:12:08
Podrías publicar tu hardware y firmware, para acelerar el proceso de los que aun no comenzamos con este tema??

Claro, aquí va.

Código:

Código: [Seleccionar]
;**********************************************************************
;             ARCHIVO PARA GRABAR EN EL PIC P16F690   *
;   *
; SON LAS RUTINAS PARA MANEJAR EL PROTOCOLO SPI   *
;**********************************************************************
;                                                                     *
;   Nombre de archivo:     spi.asm                                   *
;   Fecha inicio:      15 de noviembre del 2011                  *
;   Última modificación: 29 de marzo de 2012     *
;                                                                     *
;   Autores: FUCHS MONKAS VARELA                       *
;   Proyecto: SIME                                      *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Archivos requeridos: P16F690.INC                                 *
;                                                                     *
;**********************************************************************
;                                                                     *
;    BIBLIOGRAFÍA: AN220: Watt-Hour Meter using PIC16C923 and CS5460  *
;                                                                     *
;**********************************************************************

list p=16f690 ; list directive to define processor


#include <P16F690.inc> ; processor specific variable definitions

; RELOJ INTERNO
; __CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF

; RELOJ DEL CIRRUS
__CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _EC_OSC & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF


;***** VARIABLE DEFINITIONS
w_temp EQU 0x7D ; variable used for context saving
status_temp EQU 0x7E ; variable used for context saving
pclath_temp EQU 0x7F ; variable used for context saving




SPBRG_VAL EQU 0x19 ; BRG = 25 dec


;**********************************CALCULO DEL BAUD RATE*************************************************

;                    FOSC
; Desired Baud Rate =  -------------------
;            16(SPBRGH:SPBRG + 1)

;Despejando,

;       FOSC
;   x =       ----------    - 1
;          Desired Baud Rate
;         ------------------
;       16

; 1) Para FOSC = 4Mhz (INTOSCK),

; x = 25.04. Se utiliza 25d como valor más cercano (19h)

; Con ello, queda un baudrate de baud = 9615,38. Un error del 0.16%.




;************************************************************************************************
dirEEPROM EQU 0x20 ;*******verificar donde es que empieza la EEPROM*****
;************************************************************************************************

; CS5460 variables (string equates)
SYNC0 equ 0xFE ; Sync bytes sent as dummy data during reads
SYNC1 equ 0xFF ; No more than 3 SYNC1 bytes at a time.

VOLTAJE_MSB equ 0x60
VOLTAJE_med equ 0x61
VOLTAJE_LSB equ 0x62
 
cblock 0x20 ; Para guardar variables en la RAM, empezando en 0x20
;SSP variables (SPI mode). Buffer de recepcion desde el CS5463
RXDATA0 ; RXDATA buffer MSB
RXDATA1 ; RXDATA buffer
RXDATA2 ; RXDATA buffer LSB

; TXDATA buffer (SPI mode). Buffer de transmision hacia el CS5463
TXDATA  ; Byte de comando para mandar al CS4563
TXDATA0 ; TXDATA buffer MSB
TXDATA1 ; TXDATA buffer
TXDATA2 ; TXDATA buffer LSB
DIRECCION

endc


#define CS PORTC, 2 ; CS



;**********************************************************************
ORG 0x000 ; processor reset vector
  goto main ; go to beginning of program


ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register


; isr code can go here or be located as a call subroutine elsewhere


movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt


;**********************************************************************
main
call InicioPuertos ; configuro puertos y SPI
call ConfigCirrus ; configuro cirrus
call SetupSerial

call ResetIDCoff
call ResetVDCoff

;********************CALIBRACIONES A REALIZAR EN EL INICIO*************
;call calibrarVgn
;call calibrarIgn
call CargarCalibracionVoltageGain
call CargarCalibracionCorrienteGain
;**********************************************************************
loop
;call delay1s ; HACER!!
call enviarTrama
;call mostrarNormal
goto loop

;**********************************************************************
enviarTrama:
movlw 0X23 ; numeral
call Envia

call direcc; envio byte de direccion (los 5 mas significativos valen 0)

call LeerPotenciaActiva
movf RXDATA0, W
call Envia
movf RXDATA1, W
call Envia
movf RXDATA2, W
call Envia

call LeerCorriente
movf RXDATA0, W
call Envia
movf RXDATA1, W
call Envia
movf RXDATA2, W
call Envia

call LeerFP
movf RXDATA0, W
call Envia
movf RXDATA1, W
call Envia
movf RXDATA2, W
call Envia

call LeerVoltaje
movf RXDATA0, W
call Envia
movf RXDATA1, W
call Envia
movf RXDATA2, W
call Envia

movlw 0X2A ; asterisco
call Envia
return
;**********************************************************************

mostrarNormal:
call mostrarDireccion
movf DIRECCION, W
call Envia

call mostrarCorriente
call LeerCorriente

movf RXDATA0, W
call Envia

movf RXDATA1, W
call Envia

movf RXDATA2, W
call Envia

call mostrarPotenciaActiva
call LeerPotenciaActiva

movf RXDATA0, W
call Envia

movf RXDATA1, W
call Envia

movf RXDATA2, W
call Envia

call mostrarFP
call LeerFP

movf RXDATA0, W
call Envia

movf RXDATA1, W
call Envia

movf RXDATA2, W
call Envia

movlw 0X0D
call Envia
movlw 0X0D
call Envia
movlw 0X0D
call Envia
movlw 0X0D
call Envia

call LeerPotApa

movf RXDATA0, W
call Envia

movf RXDATA1, W
call Envia

movf RXDATA2, W
call Envia

movlw 0X0D
call Envia
movlw 0X0D
call Envia
movlw 0X0D
call Envia
movlw 0X0D
call Envia

movlw 0xAA
call Envia
call LeerVoltaje

movf RXDATA0, W
call Envia

movf RXDATA1, W
call Envia

movf RXDATA2, W
call Envia

movlw 0xBB
call Envia
return

;**********************************************************************
direcc:
bcf STATUS,RP0 ; Banco 0
bcf STATUS,RP1

btfss PORTA,2
goto negative
goto positive
negative
  bsf DIRECCION, 0
goto salida
positive
bcf DIRECCION, 0
goto salida
salida

btfss PORTC,0
goto negative1
goto positive1
negative1
  bcf DIRECCION, 1
goto salida1
positive1
bsf DIRECCION, 1
goto salida1
salida1

btfss PORTC,1
goto negative2
goto positive2
negative2
  bcf DIRECCION, 2
goto salida2
positive2
bsf DIRECCION, 2
goto salida2
salida2

bcf DIRECCION,3
bcf DIRECCION,4
bcf DIRECCION,5
bcf DIRECCION,6
bcf DIRECCION,7
movf DIRECCION, W
call Envia

;DIP SW
;1 - RA2
;2 - RC0
;3 - RC1
return
;**********************************************************************
CargarCalibracionCorrienteOffset
movlw b'01100000'
movwf TXDATA
movlw 0x56
movwf TXDATA0
movlw 0x66
movwf TXDATA1
movlw 0x66
movwf TXDATA2
call SSPWrite
  return
;**********************************************************************
CargarCalibracionVoltajeOffset
movlw b'01100010'
movwf TXDATA
movlw 0xFF
movwf TXDATA0
movlw 0xDE
movwf TXDATA1
movlw 0x10
movwf TXDATA2
call SSPWrite
  return
;**********************************************************************
CargarCalibracionCorrienteGain
movlw b'01000100'
movwf TXDATA
movlw 0x4D
movwf TXDATA0
movlw 0xE0
movwf TXDATA1
movlw 0x1F
movwf TXDATA2
call SSPWrite
  return
;**********************************************************************
CargarCalibracionVoltageGain
movlw b'01001000'
movwf TXDATA
movlw 0x3B
movwf TXDATA0
movlw 0x4E
movwf TXDATA1
movlw 0x06
movwf TXDATA2
call SSPWrite
  return

;**********************************************************************
calibrarIACOFF
movlw b'11001101'
movwf TXDATA
call SSPCmd
return
;**********************************************************************
calibrarVACOFF
movlw b'11010101'
movwf TXDATA
call SSPCmd
return

;**********************************************************************
calibrarVgn
movlw b'11010110'
movwf TXDATA
call SSPCmd
return
;**********************************************************************
calibrarIgn
movlw b'11001110'
movwf TXDATA
call SSPCmd
return

;**********************************************************************
Sincronizo
movlw SYNC1 ; SYNC1 byte (0xFF)
movwf TXDATA
movlw SYNC1 ; SYNC1 byte (0xFF)
movwf TXDATA0
movlw SYNC1 ; SYNC1 byte (0xFF)
movwf TXDATA1
movlw SYNC0 ; SYNC0 byte (0xFE)
movwf TXDATA2
call SSPWrite ; send sync bytes to CS5460
  return
;**********************************************************************

InicioPuertos

; Establezco entradas y salidas en los puertos. '0' indica que es salida, '1' que es entrada
; Sin conectar = 1, no implementado = 0


;DIP SW
;1 - RA2
;2 - RC0
;3 - RC5


bsf STATUS,RP0 ; Banco 1
bcf STATUS,RP1

  movlw b'00010011'
; RA0 = 1 - programador
; RA1 = 1 - programador
; RA2 = 0 - DIP SW
; RA3 = 0 - programador
; RA4 = 0 - OSC2
; RA5 = 0 - OSC1
; RA6 = 0 - unimplemented
; RA7 = 0 - unimplemented
movwf TRISA



bsf STATUS,RP0 ; Banco 1
bcf STATUS,RP1

movlw b'00110000' ; RB0 = 0 - unimplemented
; RB1 = 0 - unimplemented
; RB2 = 0 - unimplemented
; RB3 = 0 - unimplemented
; RB4 = 1 - SDI
; RB5 = 1 - RX (Xbee)
; RB6 = 0 - SCK
; RB7 = 0 - TX (Xbee)
movwf TRISB


bsf STATUS,RP0 ; Banco 1
bcf STATUS,RP1


  movlw b'01111000'
  movwf TRISC
; RC0 = 1 - DP SW
; RC1 = 1 - DP SW
; RC2 = 0 - /SS
; RC3 = 1 - entrada de SCK para testeo
; RC4 = 1 - SDI
; RC5 = 0
; RC6 = 1 - SS must have TRISC<6> bit set (pagina 183 del 16F690)
; RC7 = 0 - SDO

movlw  b'11000000' ;setup SSP Module - input sampled at end of output, xmit on rising SCLK
movwf SSPSTAT
; bit 0 - BF = 0. Buffer Full Status bit
;BF = 1: Receive complete, SSPBUF is full
;BF = 0: Receive not complete, SSPBUF is empty

; bit 1 - no implementado (0)
; bit 2 - no implementado (0)
; bit 3 - no implementado (0)
; bit 4 - no implementado (0)
; bit 5 - no implementado (0)

; bit 6 - CKE = 1. SPI Clock Edge Select bit.
;Si CKP = 0:
;1 = Data transmitted on rising edge of SCK (Microwire alternate)
;0 = Data transmitted on falling edge of SCK
;Si CKP = 1:
;1 = Data transmitted on falling edge of SCK (Microwire default)
;0 = Data transmitted on rising edge of SCK

; bit 7 - SMP = 1. Input data sampled at end of data output time

bcf STATUS,RP0 ;vuelvo al banco 0
bcf STATUS,RP1

movlw b'00100010'
  movwf SSPCON ; SPI master, Fosc/64, SSP enabled, clk idle low


;bit 3-0 SSPM<3:0>: Synchronous Serial Port Mode Select bits
;0000 = SPI Master mode, clock = FOSC/4
;0001 = SPI Master mode, clock = FOSC/16
;0010 = SPI Master mode, clock = FOSC/64
;0011 = SPI Master mode, clock = TMR2 output/2

; bit 4 - CKP: Clock Polarity Select bit. CKP = 0.
;CKP = 1: Idle state for clock is a high level (Microwire default)
;CKP = 0: Idle state for clock is a low level (Microwire alternate)

; bit 5 SSPEN = 1. Habilitacion del SPI

; bit 6 - SSPOV = 0. Receive Overflow Indicator bit. No overflow
;SSPOV = 1: A new byte is received while the SSPBUF register is still
    ;holding the previous data. In case of overflow, the data in SSPSR is lost.
;Overflow can only occur in Slave mode. The user must read the SSPBUF, even if only
;transmitting data, to avoid setting overflow. In Master mode, the overflow bit
;is not set since each new reception (and transmission) is initiated by writing
;to the SSPBUF register.

; bit 7 - WCOL = 0. Write Collision Detect bit. No collision
;WCOL = 1. The SSPBUF register is written while it is
;still transmitting the previous word (must be cleared in software)


;*******************************LAS ENTRADAS SON DIGITALES****************************************************
bcf STATUS, RP0
bsf STATUS, RP1
movlw 0x00
movwf ANSEL
movlw 0x00
movwf ANSELH
;*************************************************************************************************************
; para que funcione el DP SW

bcf STATUS, RP0; BANK 0
bcf STATUS, RP1

BCF CCP1CON, CCP1M0

bcf STATUS, RP0; BANK 2
bsf STATUS, RP1

BCF CM2CON0, C2ON
BCF VRCON, VP6EN;
BCF CCP1CON, CCP1M1
BCF CCP1CON, CCP1M2
BCF CCP1CON, CCP1M3

bsf STATUS, RP0; BANK 3
bsf STATUS, RP1
BCF PSTRCON, STRD
BCF PSTRCON, STRC
BCF PSTRCON, STRB
BCF PSTRCON, STRA

;*************************************************************************************************************
bcf STATUS, RP1
bcf STATUS, RP0

bsf CS ; Set CS5460 /CS

return



;**********************************************************************


ConfigCirrus
call ResetCS5463 ; reset CS4563
call InitCS5463
return


;**********************************************************************
LeerPotenciaActiva
movlw b'00010100'   
movwf TXDATA
call SSPRead
return
;**********************************************************************
LeerCorriente    
movlw b'00010110'   ; corriente RMS
movwf TXDATA
call SSPRead
return
;**********************************************************************
LeerCorrienteInst    
movlw b'00001110'   ; corriente instantanea
movwf TXDATA
call SSPRead
return
;**********************************************************************
LeerVoltaje    
movlw b'00011000'   ; voltaje RMS
movwf TXDATA
call SSPRead
return
;**********************************************************************
LeerVoltajeInst
movlw b'00010000'   ; voltaje instantaneo
movwf TXDATA
call SSPRead
return
;**********************************************************************
LeerPulseRateReg
movlw b'00001100' ;uso como salidas RA2, RC1, y quiero recibir la palabra 0x800000
movwf TXDATA
call SSPRead ; llamo a leer SPI con el byte 00001100, Pulse Rate Register
return
;*********************************************************************
LeerCycleCountReg
movlw b'00001010'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerEpsilonReg
movlw b'00011010'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerIDCoff
movlw b'00000010'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerVgn
movlw b'00001000'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerIgn
movlw b'00000100'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerPotApa
movlw b'00110110'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerFP
movlw b'00110010'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerIACoff
movlw b'00100000'
movwf TXDATA
call SSPRead
return
;*********************************************************************
LeerVACoff
movlw b'00100010'
movwf TXDATA
call SSPRead
return
;*********************************************************************

InitCS5463
movlw 0x40 ; escribo en el configuration register.
movwf TXDATA
movlw 0x00 ; PUEDE HABER PROBLEMA: **** PC[6:0] = 0000000 ****. Igain = 0 (x10)
movwf TXDATA0
movlw 0x00
movwf TXDATA1
movlw 0x01
movwf TXDATA2
call SSPWrite

  ;N=4000 cristal de 4,096MHz
movlw 0x4A ; escribo en el cycle count register
movwf TXDATA
movlw 0x00
movwf TXDATA0
movlw 0x0F ; 0FA0h = 4000d
movwf TXDATA1
movlw 0xA0
movwf TXDATA2
call SSPWrite

  ;Borrar todos los bits de STATUS
movlw 0x5E ; status register
movwf TXDATA
movlw 0x00
movwf TXDATA0
movlw 0x00
movwf TXDATA1
movlw 0x00
movwf TXDATA2
call SSPWrite

  ;Habilito HPFs
movlw 0x64 ; operational mode register
movwf TXDATA
movlw 0x00
movwf TXDATA0
movlw 0x00
movwf TXDATA1
movlw 0x61 ; Habilito HPFs. deteccion de freq de linea automatica
movwf TXDATA2
call SSPWrite
 
; QUITO OFFSET DE POTENCIA
; movlw 0x5C ; POFF
; movwf TXDATA
; movlw 0xFF
; movwf TXDATA0
; movlw 0xC9
; movwf TXDATA1
; movlw 0xE8
; movwf TXDATA2
; call SSPWrite     

;Conversion continua
movlw 0xE8 ; C3=1
movwf TXDATA
call SSPCmd
return

;***************************************************************************
; initialization routines
;***************************************************************************
; Commands the CS5463 to perform a reset cycle via the SPI code.
; After the CS5463 is resets, the serial port is resynchronized by sending SYNC bytes.
;***************************************************************************
; Inputs: none
; outputs: none

ResetCS5463
movlw b'10000000' ; comando de RESET POR SW, 0x80
movwf TXDATA ;
call SSPCmd ; send command to CS5463

;***************************************************************************
; Initialize the CS5460 Serial Port
; Write SYNC1 (0xFF) to the CS4560 up to 3 times followed by
; a SYNC0 (0xFE) to initialize the Serial Port

movlw SYNC1 ; SYNC1 byte (0xFF)
movwf TXDATA
movlw SYNC1 ; SYNC1 byte (0xFF)
movwf TXDATA0
movlw SYNC1 ; SYNC1 byte (0xFF)
movwf TXDATA1
movlw SYNC0 ; SYNC0 byte (0xFE)
movwf TXDATA2
call SSPWrite ; send sync bytes to CS5460

  return

;***************************************************************************
; Read data from the CS4560 through the SSP PORT *
;***************************************************************************
; Inputs: TXDATA (read command specifying which register to read)
; Outputs: RXDATA0, RXDATA1, RXDATA2 (received data buffer)

SSPRead
bcf CS ; CS4560 chip select pin7 low
bcf PIR1,SSPIF ; clear flag

movf TXDATA,W ; CS4560 register to read
movwf SSPBUF ; put it in SSPBUF the start read

btfss PIR1,SSPIF ; wait for SSP to be ready
goto $-1
movf SSPBUF,W ; al pedo!!
bcf PIR1,SSPIF ; clear flag

; send three dummy bytes
; in this case we send "SYNC1"s

movlw SYNC1 ; dummy byte 1
movwf SSPBUF
bcf PIR1,SSPIF
btfss PIR1,SSPIF
goto $-1
movf SSPBUF,W
movwf RXDATA0
bcf PIR1,SSPIF

movlw SYNC1 ; dummy byte 2
movwf SSPBUF
bcf PIR1,SSPIF
btfss PIR1,SSPIF
goto $-1
movf SSPBUF,W
movwf RXDATA1
bcf PIR1,SSPIF

movlw SYNC1 ; dummy byte 3
movwf SSPBUF
bcf PIR1,SSPIF
btfss PIR1,SSPIF ;00010100
goto $-1
movf SSPBUF,W
movwf RXDATA2 ; LSB
bcf PIR1,SSPIF

bsf CS ; CS4560 chip select pin back high

return


;***************************************************************************
; Write data to a CS4560 register *
; The commmand will be in TXDATA and the data will be in *
; TXDATA0 (MSB), TXDATA1, and TXDATA2 (LSB) *
;***************************************************************************
; Inputs: TXDATA, TXDATA1, TXDATA2, TXDATA3
; Outputs: none

SSPWrite

bcf CS ; set CS4560 chip select pin 7 low
bcf PIR1,SSPIF ; clear the flag
movf TXDATA,W ; get command (or register)

movwf SSPBUF ; put it in SSPBUF
btfss PIR1,SSPIF ; wait for SSP to be ready
goto $-1
movf SSPBUF,W ; dummy read, discard byte
bcf PIR1,SSPIF ; command byte sent, clear flag

movf TXDATA0,W ; get first data byte
movwf SSPBUF ; send data byte 0 (MSB)
btfss PIR1,SSPIF ; wait for SSP to be ready
goto $-1
movf SSPBUF,W ; dummy read, discard byte
bcf PIR1,SSPIF ; first data byte sent, clear flag

movf TXDATA1,W
movwf SSPBUF ; send data byte 1
btfss PIR1,SSPIF ; wait for SSP to be ready
goto $-1
movf SSPBUF,W
bcf PIR1,SSPIF ; second data byte sent, clear flag

movf TXDATA2,W
movwf SSPBUF ; send data byte 2 (LSB)
btfss PIR1,SSPIF ; wait for SSP to be ready
goto $-1
movf SSPBUF,W ; dummy read, discard byte
bcf PIR1,SSPIF ; third data byte sent, clear flag

;bsf CS
return

;***************************************************************************
; Write a 1 byte command to the CS4560 *
; The command will be in TXDATA *
;***************************************************************************
; Inputs: TXDATA
; Outputs: none

SSPCmd
bcf CS ; set CS4560 chip select pin 7 low

movf TXDATA,W ; get command
movwf SSPBUF ; send command
bcf PIR1,SSPIF ; clear interrupt flag
btfss PIR1,SSPIF ; loop waiting for command to be sent
goto $-1

movf SSPBUF,W ; command sent

bsf CS ; set CS4560 chip select pin back high

return

;***************************************************************************
cargoEEPROM:
bcf STATUS, RP0
bsf STATUS, RP1 ; voy al banco 2 para escribir en EEPROM

movf dirEEPROM, 0

movwf EEADR ; dirección donde voy a guardar el dato
movf VOLTAJE_MSB, 0 ; cargo RXDATA0 en w
; movf 0xAA, 0
movwf EEDAT ; cargo RXDATA0 en EEDAT
call escriboEEPROM

bcf STATUS, RP0
bsf STATUS, RP1

incf dirEEPROM, 1
movf dirEEPROM, 0

movwf EEADR ; dirección donde voy a guardar el dato
movf VOLTAJE_med, 0 ; cargo RXDATA1 en w
; movf 0xBB, 0
movwf EEDAT ; cargo RXDATA1 en EEDAT
call escriboEEPROM

bcf STATUS, RP0
bsf STATUS, RP1

incf dirEEPROM, 1
movf dirEEPROM, 0

movwf EEADR ; dirección donde voy a guardar el dato
movf VOLTAJE_LSB, 0 ; cargo RXDATA2 en w
; movf 0xCC, 0
movwf EEDAT ; cargo RXDATA0 en EEDAT

call escriboEEPROM
return

;***************************************************************************
escriboEEPROM:
bsf STATUS, RP0 ;bank 3
bsf STATUS, RP1 ;bank 3
BSF EECON1, WREN ; habilito escritura. EECON1 esta en el bank 3
BCF INTCON, GIE ; deshabilito interrupciones
BTFSC INTCON,GIE ; See AN576
GOTO $-2
MOVLW 0x55 ;
MOVWF EECON2 ; Escribo 55h
MOVLW 0xAA ;
MOVWF EECON2 ; Escribo AAh
bsf EECON1,WR ; Seteo bit WR para comenzar escritura
call verificoEscritura
return
;***************************************************************************
verificoEscritura:
btfsc EECON1,WR ; hasta que no haya terminado el tiempo de escritura
goto verificoEscritura ; no entro a la verificación

bcf STATUS, RP0
bsf STATUS, RP1
movf EEDAT, W ; cargo dato en W (pasado como parámetro al inicio)

bsf STATUS, RP0 ;bank 3
bsf STATUS, RP1 ;bank 3
bsf EECON1, RD ; leo dato

bcf STATUS, RP0
bsf STATUS, RP1 ;
subwf EEDAT, W     ; el valor escrito en W es igual al leído en EEDAT?
bsf STATUS, RP0 ;bank 3
bsf STATUS, RP1 ;bank 3
btfss STATUS, Z ; la diferencia es 0?
call errorEscritura ; NO, escribir error
return
;***************************************************************************
errorEscritura:
bcf STATUS, RP1
bcf STATUS, RP0
bsf PORTA, 2
;prendo y apago salida algún led indicando error de verificación de escritura y retomo al punto donde estaba
return

;********************CONFIGURACION DEL PUERTO SERIE**************************************
SetupSerial:
bsf STATUS, RP0
bcf STATUS, RP1

;-------------------------TXSTA: TRANSMIT STATUS AND CONTROL REGISTER---------------------------

;bit 7 CSRC: Clock Source Select bit
; Asynchronous mode:
; Don’t care
; Synchronous mode:
; 1 = Master mode (clock generated internally from BRG)
; 0 = Slave mode (clock from external source)

;bit 6 TX9: 9-bit Transmit Enable bit
; 1 = Selects 9-bit transmission
; 0 = Selects 8-bit transmission

;bit 5 TXEN: Transmit Enable bit(1)
; 1 = Transmit enabled
; 0 = Transmit disabled

;bit 4 SYNC: EUSART Mode Select bit
; 1 = Synchronous mode
; 0 = Asynchronous mode

;bit 3 SENDB: Send Break Character bit.
; Asynchronous mode:
; 1 = Send Sync Break on next transmission (cleared by hardware upon completion)
; 0 = Sync Break transmission completed
; Synchronous mode:
; Don’t care

;bit 2 BRGH: High Baud Rate Select bit
; Asynchronous mode:
; 1 = High speed
; 0 = Low speed
; Synchronous mode:
; Unused in this mode

;bit 1 TRMT: Transmit Shift Register Status bit
; 1 = TSR empty
; 0 = TSR full

;bit 0 TX9D: Ninth bit of Transmit Data
; Can be address/data bit or a parity bit.

;ME JODEN EL BIT 3 Y EL 1
; ERA movlw b'00100010'
movlw b'00100100' ; BRGH = 1 !!!
movwf TXSTA ;TXSTA: ver pagina 160

;------------------------------------------------------------------------------------

bcf STATUS, RP0
bcf STATUS, RP1

movlw b'10010110' ;habilita puerto serie y recepcion
movwf RCSTA

bsf STATUS, RP0
bcf STATUS, RP1

;---------------------------------BAUDCTL: BAUD RATE CONTROL REGISTER---------------------------------------

;bit 7 ABDOVF: Auto-Baud Detect Overflow bit
;Asynchronous mode:
;1 = Auto-baud timer overflowed
;0 = Auto-baud timer did not overflow
;Synchronous mode:
;Don’t care

;bit 6 RCIDL: Receive Idle Flag bit
;Asynchronous mode:
;1 = Receiver is Idle
;0 = Start bit has been received and the receiver is receiving
;Synchronous mode:
;Don’t care

;bit 5 Unimplemented: Read as ‘0’

;bit 4 SCKP: Synchronous Clock Polarity Select bit
;Asynchronous mode:
;1 = Transmit inverted data to the RB7/TX/CK pin
;0 = Transmit non-inverted data to the RB7/TX/CK pin
;Synchronous mode:
;1 = Data is clocked on rising edge of the clock
;0 = Data is clocked on falling edge of the clock

;bit 3 BRG16: 16-bit Baud Rate Generator bit
;1 = 16-bit Baud Rate Generator is used
;0 = 8-bit Baud Rate Generator is used. USAMOS ESTE

;bit 2 Unimplemented: Read as ‘0’

;bit 1 WUE: Wake-up Enable bit
;Asynchronous mode:
;1 = Receiver is waiting for a falling edge. No character will be received byte RCIF will be set. WUE will
;automatically clear after RCIF is set.
;0 = Receiver is operating normally
;Synchronous mode:
;D;on’t care

;bit 0 ABDEN: Auto-Baud Detect Enable bit
;Asynchronous mode:
;1 = Auto-Baud Detect mode is enabled (clears when auto-baud is complete)
;0 = Auto-Baud Detect mode is disabled
;Synchronous mode:
;Don’t care

movlw b'00000000'   ;BRG16 = 0: 8-bit Baud Rate Generator is used. PROBAR EL MSB con 1
;movlw b'00001010'   ; ERA
movwf BAUDCTL

;-------------------------------------------------------------------------------------------------------
movlw SPBRG_VAL ;cargo un baud rate de 9600 para un XT de 4.096Mhz. Justificado arriba
movwf SPBRG

bcf STATUS, RP0
return
;***************************************************************************
TransmitSerial:
bsf STATUS, RP0
bcf STATUS, RP1
bsf TXSTA, TXEN

bcf STATUS, RP0
bcf STATUS, RP1
loopTX
btfss PIR1,TXIF ;check if transmitter busy
goto loopTX ;return if transmitter busy
movf 0xAA, W
;movf VOLTAJE_med, W ;get the data to be transmitted VOLTAJE_med
movwf TXREG ;and transmit
return
;***************************************************************************
Envia:
  ; movlw VOLTAJE_LSB
; movlw b'10101010'
movwf TXREG ; envia Dato.-
bsf STATUS,RP0 ; Banco 1
esperar
btfss TXSTA,TRMT   ; chequea si esta listo
    goto esperar ; Esperamos  a que se desocupe.-
    bcf STATUS,RP0 ; Banco 0
  return

;***************************************************************************
mostrarDireccion
movlw 0x0D
call Envia
movlw 0x0D
call Envia
movlw 0x44
call Envia
movlw 0x49
call Envia
movlw 0x52
call Envia
movlw 0x0D
call Envia
movlw 0x0D
call Envia
return
;***************************************************************************
mostrarCorriente
movlw 0x0D
call Envia
movlw 0x0D
call Envia
movlw 0x43
call Envia
movlw 0x4F
call Envia
movlw 0x52
call Envia
movlw 0x52
call Envia
movlw 0x49
call Envia
movlw 0x45
call Envia
movlw 0x4E
call Envia
movlw 0x54
call Envia
movlw 0x45
call Envia
movlw 0x0D
call Envia
movlw 0x0D
call Envia
return
;***************************************************************************
mostrarPotenciaActiva
movlw 0x0D
call Envia
movlw 0x0D
call Envia
movlw 0x50
call Envia
movlw 0x4F
call Envia
movlw 0x54
call Envia
movlw 0x45
call Envia
movlw 0x4E
call Envia
movlw 0x43
call Envia
movlw 0x49
call Envia
movlw 0x41
call Envia
movlw 0x0D
call Envia
movlw 0x0D
call Envia
return
;***************************************************************************
mostrarFP
movlw 0x0D
call Envia
movlw 0x0D
call Envia
movlw 0x46
call Envia
movlw 0x50
call Envia
movlw 0x0D
call Envia
movlw 0x0D
call Envia
return
;***************************************************************************
ORG 0x2100 ; data EEPROM location
DE 1,2,3,4 ; define first four EEPROM locations as 1, 2, 3, and 4

END                     ; directive 'end of program'

Hardware:


(http://img99.imageshack.us/img99/9279/interfaz.th.png) (http://img99.imageshack.us/i/interfaz.png/)
(http://img140.imageshack.us/img140/1256/cirrus.th.png) (http://img140.imageshack.us/i/cirrus.png/)
(http://img818.imageshack.us/img818/9910/picqi.th.png) (http://img818.imageshack.us/i/picqi.png/)


Tener en cuenta que la impedancia de entrada del canal de corriente no es muy grande (vale 20KOhm), por lo tanto las señales caen en un 0.8 aproximadamente. Es por ello que el valor de Ign vale 0x4DE01F. Esto levanta la señal de corriente en 1.2 veces aproximadamente, arrojando resultados perfectos.



Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: bolso103 en 29 de Marzo de 2012, 11:18:11
Imagen que faltó:

(http://img17.imageshack.us/img17/4534/cirruscs5463.png) (http://imageshack.us/photo/my-images/17/cirruscs5463.png/)

Uploaded with ImageShack.us (http://imageshack.us)
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: AZUL8 en 29 de Marzo de 2012, 19:17:05
Imagen que faltó:

(http://img17.imageshack.us/img17/4534/cirruscs5463.png) (http://imageshack.us/photo/my-images/17/cirruscs5463.png/)

Uploaded with ImageShack.us (http://imageshack.us)
hola soy principiante en el foro, espero que me puedan ayudar


disculpen que los interrumpa, pues ya tienen adelantado el tema, pero tengo un problema  similar con la conexión de un ade7754 con un pic18f2550, seria de gran ayuda que alguien me diera una pista para la comunicación spi, ya hecho varias pruebas , las cuales no han dado frutos, he utilizado, spi_write,spi_read, spi_xfer como ustedes veo q lo han utilizado.

la diferencia con el integrado (cs5463) y el ade son los procesos de inicialización  que el ade no se utilizan y para escribir el registro y leerlo en el ade dependen de los dos bits mas significativos, 10 para escritura y 00 para la lectura.

antes de cualquier cosa me cerciore con osciloscopio de que el pic estuviera enviando sus pulsos correspondientes como maestro y lo esta haciendo perfectamente.

si alguien me pudiera dar pistas, seria de gran ayuda.


les agradesco mucho, su atención y ojala alguien me pueda ayudar.


gracias
Título: Re: (Solucionado) Ayuda con SPI y CS5463
Publicado por: alan_lima en 16 de Julio de 2016, 11:34:28
Imagen que faltó:

(http://img17.imageshack.us/img17/4534/cirruscs5463.png) (http://imageshack.us/photo/my-images/17/cirruscs5463.png/)

Uploaded with ImageShack.us (http://imageshack.us)

Buenos días, estoy trabajando en un proyecto con el CS5463 y encontramos este foro, pero las fotos que posteaste ya no están disponibles, si resulta que todavía tienen estas imágenes podrían colocar de nuevo o me envía. Me sería de gran aprecio. alanlimadasilva232@hotmail.com