Tengo una librería en CCS para un DDS AD9850 que funciona correctamente, la estoy traduciendo a XC8, y no me funciona:
Librería CCS:
#define FREC_CLK 125//Suitable for 125MHz Crystal
/******************************************************************************/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AD9850_Init()
{
output_drive(REST);//Define como salida
output_drive(FQUP);//Define como salida
output_drive(CLK);//Define como salida
output_drive(BitData);//Define como salida
output_bit(REST, 0);
output_bit(FQUP, 0);
output_bit(CLK, 0);
output_bit(BitData, 0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AD9850_Reset_Serial()
{
output_bit(CLK, 0);
output_bit(FQUP, 0);
//Reset signal
output_bit(REST, 0);
output_bit(REST, 1);
output_bit(REST, 0);
//Clk signal
output_bit(CLK, 0);
output_bit(CLK, 1);
output_bit(CLK, 0);
//Fq-up signal
output_bit(FQUP, 0);
output_bit(FQUP, 1);
output_bit(FQUP, 0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Enviamos frecuencia en Hz al DDS.
void AD9850_WR_Serial(int8 w0,int32 frequence)
{
int8 i,w;
int32 y;
UINT64 x,aux;
//Calculate the frequency of the HEX value
aux = ui64Mult32x32(frequence,START_X); //el dato sigue cabiendo en la var de 64 bits
x = ui64Cast32x64(FREC_CLK);
aux = ui64Div64x64(aux,x);//no pierde tanta precisión porque se sigue trabajando en un recipiente de 64 bits
x = ui64Cast32x64(1000000);
aux = ui64Div64x64(aux,x);//ya pierde precisión pero el dato se entrega a int, así que no hay de otra
y = aux;
//write w4
w=(y>>=0);
for(i=0; i<8; i++)
{
output_bit(BitData, (w>>i)&0x01);
output_bit(CLK, 1);
output_bit(CLK, 0);
}
//write w3
w=(y>>8);
for(i=0; i<8; i++)
{
output_bit(BitData, (w>>i)&0x01);
output_bit(CLK, 1);
output_bit(CLK, 0);
}
//write w2
w=(y>>16);
for(i=0; i<8; i++)
{
output_bit(BitData, (w>>i)&0x01);
output_bit(CLK, 1);
output_bit(CLK, 0);
}
//write w1
w=(y>>24);
for(i=0; i<8; i++)
{
output_bit(BitData, (w>>i)&0x01);
output_bit(CLK, 1);
output_bit(CLK, 0);
}
//write w0
w=w0;
for(i=0; i<8; i++)
{
output_bit(BitData, (w>>i)&0x01);
output_bit(CLK, 1);
output_bit(CLK, 0);
}
output_bit(FQUP, 1);
output_bit(FQUP, 0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Y mi traducción a XC8:
#ifndef VAR_64BIT_H_
#include "Variables_64bits.h"
#endif
#include "DDS_AD9850.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AD9850_Init()
{
TRIS_REST = 0;//Define como salida
TRIS_FQUP = 0;//Define como salida
TRIS_CLK = 0;//Define como salida
TRIS_BitData = 0;//Define como salida
REST = 0;
FQUP = 0;
CLK = 0;
BitData = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AD9850_Reset_Serial()
{
CLK = 0;
FQUP = 0;
//Reset signal
REST = 0;
REST = 1;
REST = 0;
//Clk signal
CLK = 0;
CLK = 1;
CLK = 0;
//Fq-up signal
FQUP = 0;
FQUP = 1;
FQUP = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Enviamos frecuencia en Hz al DDS.
void AD9850_WR_Serial(unsigned char w0, unsigned long long frequence)
{
unsigned char i,w;
unsigned long long y;
UINT64 x,aux;
//Calculate the frequency of the HEX value
aux = ui64Mult32x32(frequence,START_X); //el dato sigue cabiendo en la var de 64 bits
x = ui64Cast32x64(FREC_CLK);
aux = ui64Div64x64(aux,x);//no pierde tanta precisión porque se sigue trabajando en un recipiente de 64 bits
x = ui64Cast32x64(1000000);
aux = ui64Div64x64(aux,x);//ya pierde precisión pero el dato se entrega a int, así que no hay de otra
y = aux.Dword[0];
//write w4
w=(y>>=0);
for(i=0; i<8; i++)
{
BitData = (w>>i)&0x01;
CLK = 1;
CLK = 0;
}
//write w3
w=(y>>8);
for(i=0; i<8; i++)
{
BitData = (w>>i)&0x01;
CLK = 1;
CLK = 0;
}
//write w2
w=(y>>16);
for(i=0; i<8; i++)
{
BitData = (w>>i)&0x01;
CLK = 1;
CLK = 0;
}
//write w1
w=(y>>24);
for(i=0; i<8; i++)
{
BitData = (w>>i)&0x01;
CLK = 1;
CLK = 0;
}
//write w0
w=w0;
for(i=0; i<8; i++)
{
BitData = (w>>i)&0x01;
CLK = 1;
CLK = 0;
}
FQUP = 1;
FQUP = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El archivo de cabecera:
#ifndef DDS_AD9851_H
#define DDS_AD9851_H
#include <xc.h> // include processor files - each processor file is guarded.
#define START_X 4294967295 //2 ^ 32 - 1
/******************************************************************************/
/* Pines y frec DDS.Para control. */
#define REST LATC0
#define FQUP LATC1
#define CLK LATC2
#define BitData LATC5
//Para definir como salida.
#define TRIS_REST TRISC0
#define TRIS_FQUP TRISC1
#define TRIS_CLK TRISC2
#define TRIS_BitData TRISC5
//-----
#define FREC_CLK 125//Suitable for 125MHz Crystal
/******************************************************************************/
void AD9850_Init(void);
void AD9850_Reset_Serial(void);
void AD9850_WR_Serial(unsigned char w0, unsigned long long frequence);
#endif /* DDS_AD9851_H */
El codigo en CCS funciona bien en un PIC18F4550 a 48MHz, e y el de XC8 lo estoy probando en un PIC18F26K80 con oscilador interno a 16MHz, entonces pienso que no es problema de transiciones muy rápidas en el cambio de estado de las lineas de control, pues donde da problemas es en el PIC más lento.
No veo cual puede ser el problema, la traducción parece correcta. La librería de manejo de variables de 64bit también descarto que esté mal, probé a poner un valor constante en este punto:
y = 34.359.738;//aux.Dword[0]; Cte para 1MHz.
y no genera la frecuencia de 1MHz.
El módulo DDS funciona, pues con el otro PIC y el código en CCS funciona correctamente.
Gracias!!! un saludo.