View previous topic :: View next topic |
Author |
Message |
Milhaus
Joined: 20 Oct 2007 Posts: 9
|
AD9833 |
Posted: Fri Dec 07, 2007 5:07 am |
|
|
Hi all,
i am looking for driver for DDS chip AD9833.
Can you help me ?
Milos |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Guest
|
|
Posted: Sun Jan 20, 2008 1:02 pm |
|
|
I have written following library:
[deleted]
This does work, but the frequency dont change after calling following SetDDSFrequency functions. Please could you help me ?
Thanks
Milos |
|
|
Milhaus
Joined: 20 Oct 2007 Posts: 9
|
|
Posted: Sun Jan 20, 2008 1:07 pm |
|
|
I have written following library:
Please ignore previous post. It is not displayed correctly.
Code: |
// AD9833 definitions
#define FREQ0 0x4000 // Select FREQ0 register
#define FREQ1 0x8000 // select FREQ1 register
#define PHASE0 0xC000 // select PHASE0 register
#define PHASE1 0xE000 // select PHASE1 register
// Control register bits
#define B28 (1<<13)
#define HLB (1<<12)
#define FSELECT (1<<11)
#define PSELECT (1<<10)
#define ADRESET (1<<8)
#define SLEEP1 (1<<7)
#define SLEEP12 (1<<6)
#define OPBITEN (1<<5)
#define DIV2 (1<<3)
#define ADMODE (1)
// Func prototypes
void AD9833_Write(unsigned int16 value);
void SetDDSFrequency(float Freq);
void AD9833_reset();
void AD9833_Write(unsigned int16 value)
{
int8 clsb, cmsb;
clsb = (int8)value;
cmsb = value >> 8;
output_low(FSYNC);
delay_us(5);
spi_write(cmsb);
spi_write(clsb);
delay_us(5);
output_high (FSYNC);
}
void AD9833_reset()
{
AD9833_Write(B28|ADRESET|OPBITEN|DIV2); //reset
AD9833_Write(B28|OPBITEN|DIV2); // square wave
}
void SetDDSFrequency(float Freq)
{
unsigned long i,lsb,msb;
Freq = Freq / 0.093132258; // for 25Mhz osc
i = (unsigned long)Freq;
lsb = (i & 0x3fff) + FREQ0;
msb = ((i>>14) & 0x3fff) + FREQ0;
AD9833_Write(lsb);
AD9833_Write(msb);
}
|
In my main code i have:
Code: |
#include <16F819.h>
#device PASS_STRINGS = IN_RAM
#fuses NOWDT, INTRC_IO, NOPROTECT,NOBROWNOUT,NOMCLR,NODEBUG
#use delay(clock=8M)
#use fast_io(a)
#use fast_io(b)
void main (){
int32 i;
SET_TRIS_B(195);
SET_TRIS_A(255);
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H |SPI_SS_DISABLED | SPI_CLK_DIV_4 );
AD9833_reset();
SetDDSFrequency(10000);
delay_ms(2000);
SetDDSFrequency(2000);
delay_ms(2000);
SetDDSFrequency(4000);
delay_ms(2000);
SetDDSFrequency(500);
delay_ms(2000);
}
|
This does work, but the frequency dont change after calling following SetDDSFrequency functions. Please could you help me ?
Thanks
Milos |
|
|
marcoscab1166
Joined: 19 May 2019 Posts: 6
|
|
Posted: Thu Jan 02, 2020 8:33 am |
|
|
Anonymous wrote: | I have written following library:
[deleted]
This does work, but the frequency dont change after calling following SetDDSFrequency functions. Please could you help me ?
Thanks
Milos |
Hello there. You're not using the #use SPI line
In that line you define the pins and the way of function of the SPI.
Without it, doesn't matter if you configure it with setup_spi |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jan 03, 2020 9:40 am |
|
|
Er. Sorry, but wrong.
The 'older' CCS way of setting up SPI, is setup_spi. This is used with
the spi_read and spi_write functions. Only works with the hardware ports.
The 'newer' way is #USE SPI, with the spi_xfer functions. This supports
both hardware and software SPI.
What is posted is perfectly acceptable and sets up the SPI with the
setup_spi line. However as posted it'll only work with the hardware SPI1
port.
An issue though is using the 'unsigned long' designation. On a PIC16,
unsigned long is only a 16bit variable. It is much safer and better in general
to be explicit and use lengths like unsigned int32.
Now since this is a 16bit variable, this line:
msb = ((i>>14) & 0x3fff) + FREQ0;
can only return the upper 2 bits of 'i'.
Also the values given by the division are always overflowing the integer.
So 10000/0.093132258 = 107374 which won't fit in a 16bit integer.....
Then you are generating 16bit results and putting these into variables
called lsb and msb, and writing just the low 8bits of these.
Understand spi_write writes a _byte_ only.
So:
Code: |
#define FREQ0 0x4000 // Select FREQ0 register
void AD9833_Write(unsigned int16 value)
{
int8 clsb, cmsb, dummy;
clsb = make8(value,0); //faster than rotations etc..
cmsb = make8(value,1);
output_low(FSYNC);
delay_us(1);
dummy=spi_read(cmsb);
dummy=spi_read(clsb); //Using read forces the transfer to complete
//before returning. Removes the need for delays
output_high (FSYNC);
}
void SetDDSFrequency(float Freq)
{
unsigned int32 i, lsw, msw;
i = Freq * 10.737418; // for 25Mhz osc
//Multiplication is always faster than division.
lsw= (i & 0x3FFF) | FREQ0; //low 14 bits
msw = (i & 0xFFFC000) >>14; //Upper 14 bits
msw |= FREQ0;
AD9833_write(0x2000); //Control word write
AD9833_Write(lsw); //Low 14 bits
AD9833_Write(msw); //High 14 bits
}
|
|
|
|
|