#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);
}
>f8
=FF
>26fefefe
=5FFFF000
>f8
=00
>26fefefe
=00000000
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;
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;
}
La gente de Cirrus todavía no me responde los correos que envié antes de postear en el foro.
#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);
}
#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);
}
}
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!
No es necesario, es un adicional que se ofrece.
Saludos!
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...
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
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
#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);
}
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?
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
UINT8 ReadDevice(void){ UINT8 TempVar; TempVar = SSPBUF; SSPBUF = 0xFF; while (!SSPSTATbits.BF); return ( SSPBUF ); }
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...
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!
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...
Y PMON? Reset? Con respecto a la interfaz de entrada, implementé lo mismo, con otros valores de r y c, nada más.
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?
En nuestro caso se pensó el hardware con la posibilidad de configurarlo para la calibración :mrgreen:
Podrías publicar tu hardware y firmware, para acelerar el proceso de los que aun no comenzamos con este tema??
;**********************************************************************
; 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'
Imagen que faltó:hola soy principiante en el foro, espero que me puedan ayudar
(http://img17.imageshack.us/img17/4534/cirruscs5463.png) (http://imageshack.us/photo/my-images/17/cirruscs5463.png/)
Uploaded with ImageShack.us (http://imageshack.us)
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)