|
|
View previous topic :: View next topic |
Author |
Message |
danirebollo
Joined: 10 Oct 2011 Posts: 22
|
Arduino to CCS AD9850 DDSgen.library (<<operator prob) |
Posted: Sun Jun 03, 2012 10:48 am |
|
|
Hello! I look for libraries to control AD9850 and only find Arduino libraries. I try this (and have error...), so, and I make some modifications:
Code: |
#define CLK 9
#define FQUP 10
#define REST 11
#define BitData 8
void setup()
{
AD9850_AD9850(CLK, FQUP, REST, BitData);
AD9850_init();
AD9850_reset();
AD9850_wr_serial(0x00, 1000); //Set 1000Hz frequency
Serial.begin(9600);
Serial.println("Encendiendo comunicacion serie");
// delay(1000);
}
void AD9850_AD9850(int D_CLK, int D_FQUP, int D_REST, int D_BitData)
{
pinMode(D_REST, OUTPUT);
pinMode(D_FQUP, OUTPUT);
pinMode(D_CLK , OUTPUT);
pinMode(D_BitData, OUTPUT);
int a=0;
int b=0;
int c=0;
int d=0;
}
void AD9850_init(void)
{
digitalWrite(REST, 0);
digitalWrite(FQUP, 0);
digitalWrite(CLK, 0);
digitalWrite(BitData, 0);
}
void AD9850_reset(void)
{
digitalWrite(CLK, 0);
digitalWrite(FQUP, 0);
//Reset signal
digitalWrite(REST, 0);
digitalWrite(REST, 1);
digitalWrite(REST, 0);
//Clk signal
digitalWrite(CLK, 0);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
//Fq-up signal
digitalWrite(FQUP, 0);
digitalWrite(FQUP, 1);
digitalWrite(FQUP, 0);
}
void AD9850_wr_serial(unsigned char w0,double frequence)
{
unsigned char i,w;
long int y;
double x;
//Calculate the frequency of the HEX value
x=4294967295/125;//Suitable for 125M Crystal
frequence=frequence/1000000;
frequence=frequence*x;
y=frequence;
//write w4
w=(y>>=0);
for(i=0; i<8; i++)
{
digitalWrite(BitData, (w>>i)&0x01);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
//write w3
w=(y>>8);
for(i=0; i<8; i++)
{
digitalWrite(BitData, (w>>i)&0x01);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
//write w2
w=(y>>16);
for(i=0; i<8; i++)
{
digitalWrite(BitData, (w>>i)&0x01);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
//write w1
w=(y>>24);
for(i=0; i<8; i++)
{
digitalWrite(BitData, (w>>i)&0x01);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
//write w0
w=w0;
for(i=0; i<8; i++)
{
digitalWrite(BitData, (w>>i)&0x01);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
digitalWrite(FQUP, 1);
digitalWrite(FQUP, 0);
}
void AD9850_wr_parrel(unsigned char w0,double frequence)
{
}
int x; // integer x decalaraion
char p, *l; // declaration for charecter p and pointer to charecter l
int q=0;
int w=0;
int e=0;
int r=0;
int t=0;
int y=0;
int z=0;
int o=0;
int u=0;
long psp=0;
int qw=0;
int qe=0;
byte incomingByte=0;
int i=0;
void loop()
{
//Serial.print("loop");
//delay (1000);
if (Serial.available() > 0)
{
o = Serial.read();
Serial.print("He recibido: ");
Serial.print(o-48);
switch (i)
{
case 0:
q=o-48;
Serial.println(i);
i++;
break;
case 1:
w=o-48;
Serial.println(i);
i++;
break;
case 2:
e=o-48;
Serial.println(i);
i++;
break;
case 3:
r=o-48;
Serial.println(i);
i++;
break;
case 4:
t=o-48;
Serial.println(i);
i++;
break;
case 5:
y=o-48;
Serial.println(i);
i++;
break;
case 6:
u=o-48;
Serial.println(i);
i++;
break;
case 7:
qw=o-48;
Serial.println(i);
i++;
break;
case 8:
qe=o-48;
Serial.println(i);
i=0;
psp=(q*100000000+w*10000000+e*1000000+r*100000+t*10000+y*1000+u*100+qw*10+qe);
q=0;
w=0;
e=0;
r=0;
t=0;
y=0;
u=0;
qw=0;
qe=0;
Serial.print("Captura terminada: ");
Serial.println(psp);
break;
}
Serial.flush(); //vacia el buffer serie
delay(200);
}
//int x=0;
//Serial.println(x);
//AD9850_wr_serial(0x00, psp);
int paso=100; //segundos
int minsw=20;
int maxsw=20000;
int delaysw=100;
boolean rw=false;
for(int iz=minsw; iz<maxsw; iz=iz+maxsw/paso)
{
AD9850_wr_serial(0x00, iz);
delay(delaysw);
}
if (rw==true)
{
for(int iz=maxsw; iz>minsw; iz=iz-maxsw/paso)
{
AD9850_wr_serial(0x00, iz);
delay(delaysw);
}
}
}
|
This is my code (main code are awesome sweep function xD). My trouble are AD9850_wr_serial function, more exactly this:
Why w and y are char?? I read on some forums says << are logic operator to move bytes (I don't know if its true...) like asembler, but I dont know why uses char instide boolean (example 1011).
And other question are what makes this part of code. I read datasheet and ad9850 havent any serial protocol ( :( i like I2C...), this are normal serial comunication and the only bytes change are Data, FQ and CLK (reset are always the same if no isue). Why not use Data (BitData in this code) like CLK? (put 0 or 1 directly, not <<...)
what are traduction code of
Code: |
w=(y>>=0);
for(i=0; i<8; i++)
{
digitalWrite(BitData, (w>>i)&0x01);
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
} | ??
datasheet are here http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
info are here http://alhin.de/arduino/index.php?n=7
http://www.elecfreaks.com/2110.html
http://www.elecfreaks.com/wiki/index.php?title=DDS_Module_-_AD9850#Pin_definition_and_Rating
http://www.qsl.net/pa3ckr/signalgenerator/
http://www.qsl.net/pa3ckr/signalgenerator/dds36.txt
http://www.ccsinfo.com/forum/viewtopic.php?t=47110
http://dl.dbank.com/c07zd7grto
http://www.ebay.com/itm/AD9850-DDS-signal-generator-module-circuit-diagram-/170572409806?pt=BI_Signal_Sources&hash=item27b6e86bce#ht_4500wt_984
http://www.ebay.com/itm/New-AD9850-DDS-Signal-Generator-Module-Circuit-Diagram-Code-For-Arduino-MCU-2560-/180837570689?pt=LH_DefaultDomain_0&hash=item2a1ac25881#ht_4408wt_952
http://elecfreaks.com/store/download/datasheet/breakout/DDS/DDS-ADI.pdf
Thanx for all and sorry foy my english (¬¬) |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Sun Jun 03, 2012 12:17 pm |
|
|
Hi,
A lot of that Arduino code can easily be translated into CCS 'C', and yet it appears that you haven't tried to do any of it yourself! Why not convert what you can, and then come back here and ask for help in the areas you need it? This forum is not intended to do your work for you!
John |
|
|
danirebollo
Joined: 10 Oct 2011 Posts: 22
|
|
Posted: Sun Jun 03, 2012 2:57 pm |
|
|
I can't like c code without any work... in fact, i have all code but it dont works because i comment uknown operators (with //)...
Im engineer student, i like to investigate, but y only know "<<" or ">>" characters to find anything on google...
looking for this, NOW i found this operator are called "bitshift" ( http://arduino.cc/es/Reference/Bitshift ) like bitshift in assembler (i ignore this name. In spanish this are "desplazar" or "rotar" similar to "rotate". for example, "shift register" says "registro de desplazamiento")
Then, now i think this:
01010<<1 = 10100, and 01010>>1 are 00101.
to c code was and to c code was .
But, shift registers (when feedback) rotate all: first bite comes to last bite when rotate and last to first... i read that in c# or java, when bitshift, new bite (incoming bite) always are 0.
Is it? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sun Jun 03, 2012 3:05 pm |
|
|
>>, and << are bitwise shifts.
Can be applied to any size data. int8, int16, int32.
result = val>>1
Effectively divides the value by 2 (assuming MSb is on the left, which depends on the processor), and stores this in result.
On some processors the shifts 'wrap', while on others the bits off the end are lost. processor dependant.
Now you can in C, always write a value back into itself from an arithmetic operation. So:
val>>=1
Would put val shifted right by one, back into itself.
Also the result could be copied to another variable at the same time:
result=(val>>=1)
Would divide val by two, and put the result back into both val, and result.
However using '0'as the shift value, would almost certainly be optimised away by any normal compiler. It is basically meaningless.
It is just being used rather inefficiently as a way to copy the low byte of the variable. However in this case the PIC is much more efficient at doing transfers, and bit tests, so:
Code: |
void write_byte(int8 valtowrite){
int i;
for(i=0; i<8; i++){
digitalWrite(BitData, bit_test(valtowrite,i));
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
}
void AD9850_wr_serial(unsigned char w0,double frequence) {
unsigned char w;
int bnum;
int32 y; //Must be int32
double x;
//Remember double does nothing unless you are using a DSPIC
//Calculate the frequency of the HEX value
x=4294967295/125;//Suitable for 125M Crystal
frequence=frequence/1000000;
frequence=frequence*x;
y=frequence;
for (bnum=0;bnum<4;bnum++) {
write_byte(make8(y,bnum));
}
digitalWrite(FQUP, 1);
digitalWrite(FQUP, 0);
}
|
Note also you need to use int32, instead of long int for y. Same applies at several other points in the code.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 03, 2012 3:10 pm |
|
|
I noticed Ttelmah posted his reply while I was composing mine, but I'll
post it anyway.
I agree that you need to convert the code mostly by yourself. You need
to learn Arduino (at least somewhat, especially the size of their data
types) and you need to learn CCS (again, with special attention to data types).
To answer your questions:
Quote: |
w=(y>>=0);
Why w and y are char??
|
'w' is a char, but 'y' is a long int. You didn't post your PIC, so I'll assume
it's a 16F or 18F. For the CCS compiler, the equivalent data type would
be a 'signed int32'. See the code that you posted below. It clearly
shows 'y' is a long int:
Quote: |
void AD9850_wr_serial(unsigned char w0,double frequence)
{
unsigned char i,w;
long int y;
double x;
|
'w' is a char because they are sending 8-bit data from the PIC to the
DDS chip, so they extract each byte from 'y' and put it into a char ('w')
before they send it.
Quote: |
w=(y>>=0);
I read on some forums says << are logic operator to move bytes
|
The above construct is not necessary. It just loads 'w' with the LSB of 'y'.
He could have written:
or
They do the same thing.
Quote: | I read datasheet and ad9850 havent any serial protocol
|
It sure does. Right on the first page it says:
Quote: |
The frequency tuning, control, and phase modulation words are loaded
into the AD9850 via a parallel byte or serial loading format. Serial loading
is accomplished via a 40-bit serial data stream on a single pin.
|
On page 9 it says this:
Quote: |
In serial load mode, subsequent rising edges of W_CLK shift the 1-bit data
on Pin 25 (D7) through the 40 bits of programming information. After 40
bits are shifted through, an FQ_UD pulse is required to update the output
frequency (or phase).
|
http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Sun Jun 03, 2012 3:50 pm |
|
|
also...
If you press F11 while your project is open, the CCS HELP screens magically appear ! Keeping it open, will allow you instant access to probably 90% of what you need to know about CCS C.
I leave it to you to explore, search and inhale the wealth of info there...
the other 9% comes from this forum !! |
|
|
danirebollo
Joined: 10 Oct 2011 Posts: 22
|
|
Posted: Sun Jun 03, 2012 5:16 pm |
|
|
PCM programmer wrote: |
Quote: | I read datasheet and ad9850 haven't any serial protocol
|
It sure does. Right on the first page it says:
Quote: |
The frequency tuning, control, and phase modulation words are loaded
into the AD9850 via a parallel byte or serial loading format. Serial loading
is accomplished via a 40-bit serial data stream on a single pin.
|
On page 9 it says this:
Quote: |
In serial load mode, subsequent rising edges of W_CLK shift the 1-bit data
on Pin 25 (D7) through the 40 bits of programming information. After 40
bits are shifted through, an FQ_UD pulse is required to update the output
frequency (or phase).
|
http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf |
This are confusion for my bad english xD. I say dds chip haven't any serial protocol like I2C or SPI. dds chip have serial communication, but they are are "unbranded" serial communication XD and 4 wires... I2C are only 2.
I post new code when migrate to c.
I use pic 16f877, maybe later MSP430, but this programmer, CCS, aren't this CCS xd. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Sun Jun 03, 2012 5:48 pm |
|
|
It has both serial and parallel inputs,datasheet says so.
It's very,very simple to implement a 'driver' for it but first you have to choose whether you want serial(2 pins) or parallel(9 pins).
Either way it is NOT difficult to program the chip.
If you search this forum, there is a 'driver' for it.Or at least good code to start from. |
|
|
danirebollo
Joined: 10 Oct 2011 Posts: 22
|
|
Posted: Sun Jun 03, 2012 6:08 pm |
|
|
Code: | digitalWrite(BitData, (w>>i)&0x01); | this are w>>I anded 1? why anded? in this case (constant 1) are the same |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Sun Jun 03, 2012 6:17 pm |
|
|
I don't see any code for the function digitalWrite(Bitdata,xx).
Without seeing that function code can't figure it out. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 03, 2012 6:54 pm |
|
|
Temtronic,
It's an Arduino function. He's trying to translate Arduino to CCS without
knowing anything about either one of them.
danirebollo,
You need to download the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
And bookmark the Arduino reference page:
http://arduino.cc/en/Reference/HomePage
Then you can see that the DigitalWrite() function is very similar to the
output_bit() function in CCS. Arduindo and CCS use different methods
of identifying i/o pins. In CCS, you use pin constants, as given in the
.h file for your PIC.
Quote: | this are w>>I anded 1? why anded?
|
It's a common method of isolating the desired bit in a byte.
You need to study the C language some more, before attempting to
do this project. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Jun 04, 2012 2:09 am |
|
|
danirebollo wrote: | Code: | digitalWrite(BitData, (w>>i)&0x01); | this are w>>I anded 1? why anded? in this case (constant 1) are the same |
It is doing a bit test. Rotating the byte 'i' bits to the right, then testing the bottom bit of this. bit_test in CCS C, is easier.
In fact the coding is rather inelegant in any C. Given that it is just outputting the 32 individual bits. it'd be more efficient just rotate this each time, and do the whole thing with just a singe 32* loop. So:
Code: |
//alternative to what I posted before
void AD9850_wr_serial(unsigned char w0,double frequence) {
int bnum;
int32 y; //Must be int32
double x;
//Remember double does nothing unless you are using a DSPIC
//Calculate the frequency of the HEX value
x=4294967295/125;//Suitable for 125M Crystal
frequence=frequence/1000000;
frequence=frequence*x;
y=frequence;
for (bnum=0;bnum<32;bnum++) {
digitalWrite(BitData, shift_right(&y,4,0));
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}
digitalWrite(FQUP, 1);
digitalWrite(FQUP, 0);
}
}
|
The shift_right function, is similar to the >> operator, but returns the bit shifted out the bottom, which is much easier to use here, getting rid of the need to test for this being 0/1 (the & in the original code).
Best Wishes |
|
|
danirebollo
Joined: 10 Oct 2011 Posts: 22
|
|
Posted: Mon Jun 04, 2012 5:06 am |
|
|
hi!
i test new code and works well:
Code: |
///////////////////////// ad9850.h ////////////////////////////
#define CLK PIN_C5
#define FQUP PIN_C4
#define BitData PIN_D3
#define REST PIN_D2
void AD9850_init(void)
{
output_bit(REST, 0);
output_bit(FQUP, 0);
output_bit(CLK, 0);
output_bit(BitData, 0);
}
void AD9850_reset(void)
{
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);
}
void AD9850_wr_serial(unsigned char w0,double frequence)
{
unsigned char i,w;
int32 y;
double x;
//Calculate the frequency of the HEX value
x=4294967295/125;//Suitable for 125M Crystal
frequence=frequence/1000000;
frequence=frequence*x;
y=frequence;
//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);
}
void AD9850_wr_parrel(unsigned char w0,double frequence)
{
}
void AD9850_off(void)
{
AD9850_wr_serial(0b00000100, 100000);
}
void AD9850_sweep(int32 minsw, int32 maxsw, int16 delaysw, int16 swtime=200, boolean rw)
{
// swtime = duracion sweep (segundos)
// minsw = min sweep frec.
// maxsw = max sweep frec.
// delaysw = delay entre cada operacion
// rw = vuelta activada (sweep inverso)
float iz=0;
for(iz=minsw; iz<=maxsw; iz=iz+(maxsw/swtime))
{
AD9850_wr_serial(0x00, iz);
delay_ms(delaysw);
}
if (rw==true)
{
for(iz=maxsw; iz>=minsw; iz=iz-maxsw/swtime)
{
AD9850_wr_serial(0x00, iz);
delay_ms(delaysw);
}
}
}
|
|
|
|
danirebollo
Joined: 10 Oct 2011 Posts: 22
|
|
|
diogoc
Joined: 12 Feb 2008 Posts: 19
|
|
Posted: Wed Aug 29, 2012 8:12 am |
|
|
that code only works for frequencies above 1MHz.
I think that way works between 1Hz and 40MHz:
Code: |
//Calculate the frequency of the HEX value
x=4294967295*frequence ;
x=x/125000000; //Suitable for 125M Crystal
y=x;
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|