CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Arduino to CCS AD9850 DDSgen.library (<<operator prob)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
danirebollo



Joined: 10 Oct 2011
Posts: 22

View user's profile Send private message MSN Messenger

Arduino to CCS AD9850 DDSgen.library (<<operator prob)
PostPosted: Sun Jun 03, 2012 10:48 am     Reply with quote

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:
Code:

 w=(y>>=0);

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

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 12:17 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Sun Jun 03, 2012 2:57 pm     Reply with quote

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.
Code:
X<<n
to c code was
Code:
X*(2^n)
and
Code:
X>>n
to c code was
Code:
X/(2^n)
.
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: 19215

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 3:05 pm     Reply with quote

>>, 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

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 3:10 pm     Reply with quote

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:
Code:
w = y;

or
Code:
w = (char)y;

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: 9093
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 3:50 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Sun Jun 03, 2012 5:16 pm     Reply with quote

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: 9093
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 5:48 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Sun Jun 03, 2012 6:08 pm     Reply with quote

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: 9093
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 6:17 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 03, 2012 6:54 pm     Reply with quote

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: 19215

View user's profile Send private message

PostPosted: Mon Jun 04, 2012 2:09 am     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Mon Jun 04, 2012 5:06 am     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Mon Jun 04, 2012 8:05 am     Reply with quote

I made a review here: http://danirebollo.blogspot.com.es/2012/06/ad9850-cmos-125-mhz-complete-dds.html
when i finished project i post them.

Best Wishes
diogoc



Joined: 12 Feb 2008
Posts: 19

View user's profile Send private message Visit poster's website MSN Messenger

PostPosted: Wed Aug 29, 2012 8:12 am     Reply with quote

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;
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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