// DDS.c
// DDS-routines
// Pros 2008
#define FSEL0 0x6000
#define FSEL1 0x6800
#define DDS_STOP 0xF800
#define DDS_START 0xC000
#define SET_SYNC 0xB000
#define FREG0_L_LSB 0x3000
#define FREG0_L_MSB 0x2100
#define FREG0_H_LSB 0x3200
#define FREG0_H_MSB 0x2300
#define FREG1_MASK 0x0400
#define PHASE0_L_LSB 0x1800
#define PHASE0_L_MSB 0x0900
#define PHASE0_H_LSB 0x1A00
#define PHASE0_H_MSB 0x0B00
void DDS_WRITE(unsigned int data)
{
char cnt;
sbi(DDS_C_PORT, DDS_CLK); // CLK hoog
cbi(DDS_E_PORT, DDS_EN); // FSYNC laag
delay(5);
for (cnt = 0; cnt < 16; cnt++) {
if ((data & 0x8000) == 0) {
cbi(DDS_D_PORT, DDS_D);
} else {
sbi(DDS_D_PORT, DDS_D);
}
delay(5);
cbi(DDS_C_PORT, DDS_CLK); // CLK laag
data = data << 1;
delay(5);
sbi(DDS_C_PORT, DDS_CLK); // CLK hoog
}
sbi(DDS_E_PORT, DDS_EN); // FSYNC hoog
delay(5);
}
// Stel een nieuwe dds_frequentie in.
// Om zonder haperen over te gaan van de ene naar de andere frequentie,
// plaatsen we de nieuwe gegevens in het frequentie-register dat momenteel
// niet in gebruik is, waarna we switchen
void FREQ_WORD_WRITE(unsigned long freq_word)
{
unsigned int BYTE;
if (FSEL == 0) {
FSEL = FREG1_MASK;
} else {
FSEL = 0;
}
BYTE = (unsigned int) (freq_word & 0x000000FF);
DDS_WRITE(FREG0_L_LSB | FSEL | BYTE); // FREG-L-LSB in defer-register
BYTE = (unsigned int) ((freq_word >> 8) & 0x000000FF);
DDS_WRITE(FREG0_L_MSB | FSEL | BYTE); // FREG-L-MSB + defer-register
BYTE = (unsigned int) ((freq_word >> 16) & 0x000000FF);
DDS_WRITE(FREG0_H_LSB | FSEL | BYTE); // FREG-H-LSB in defer-register
BYTE = (unsigned int) ((freq_word >> 24) & 0x000000FF);
DDS_WRITE(FREG0_H_MSB | FSEL | BYTE); // FREG-H-MSB + defer-register
if (FSEL == FREG1_MASK) {
DDS_WRITE(FSEL1);
} else {
DDS_WRITE(FSEL0);
}
}
// Schrijf naar een PHASE-register
void PHASE_WORD_WRITE(unsigned long freq_word)
{
unsigned int BYTE;
BYTE = (unsigned int) (freq_word & 0x000000FF);
DDS_WRITE(PHASE0_L_LSB | BYTE); // PHASE-L-LSB in defer-register
BYTE = (unsigned int) ((freq_word >> 8) & 0x000000FF);
DDS_WRITE(PHASE0_L_MSB | BYTE); // PHASE-L-MSB + defer-register
BYTE = (unsigned int) ((freq_word >> 16) & 0x000000FF);
DDS_WRITE(PHASE0_H_LSB | BYTE); // PHASE-H-LSB in defer-register
BYTE = 0; // Er zijn maar 12 bits
DDS_WRITE(PHASE0_H_MSB | BYTE); // PHASE-H-MSB + defer-register
}
// De gewenste frequentie wordt opgegeven in (Hz *100), en wordt eerst
// met 2 vermenigvuldigd, omdat de DDS gevolgd wordt door een tweedeler.
// DDS_word = ((DDS_frequency / MCLK) * PH_MAX + 0.5);
void set_DDS(double freq)
{
freq *= 171.79869184; // DDS_word = dds_frequentie * (((2^32 / 50000000) / 100) * 2)
freq += 0.5;
DDS_word = (unsigned long) freq;
FREQ_WORD_WRITE(DDS_word);
}