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

3 phase , frequency agile, ULTRA high purity sine generator

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

3 phase , frequency agile, ULTRA high purity sine generator
PostPosted: Sun Feb 22, 2015 5:44 pm     Reply with quote

This code generates a 3 phase high purity ( harmonics ~-60dBsc),
or arbitrary phase sine wave locked to better than 250nsec absolute phase.

The AD9833 NCO is the target chip and uses just 5 lines on a single PIC port
or addressable latch. There are 3 chips in total - one for each phase - with clock and load/shift common to all 3.
There is separate data for a,b and c chips .

Phase is set to one part in 4096 of 360 degrees by altering the vars:
phaseA, phaseB, phaseC, before a call to change frequency.

Better than one hz resolution is available using an 8.388 mhz input to the
AD 9833 chip clock, for output frequencies below 512khz with rock solid amplitude and vanishingly low distortion.
a single master oscillator is required to feed all three NCO's...

Code:

//
// to alter oscillator phase on the fly-  change phase (a) (b)(c) values and call
//   DNO_FREQSET_LL();
//
//  this does basic init of oscillator trio of AD9833 NCO 10 bit sine
//  wave generators clocked at 8388608  hz
// 
//
//           |---A (REF) data B2
//           ||--B OSC         B3
//           |||-C OSC        B4
//           ||||-- 9833 CLOCK  to all 3 chips B1
//           |||||----not load/shift B0
//           |||||
byte  oscl 0b00000011;    // b port phantom control var
unsigned int32 infreq=0;  // master frequency
//                           global phase angle values follow
unsigned int16 phasea=0,phaseb=1365,phasec=2731;  // 120 degree
// unsigned int16 phasea=0,phaseb=1023,phasec=3072;  // dual quadrature
unsigned int16    lopart=0x1000;   // actual divisors w/o added 4000 hex
unsigned int16    hipart=0x1f;     // for 16 khz default frequency at INIT
unsigned int32    outdiv=0;     
#define DL8 delay_cycles(8)
// above delay for 64 mhz clock used in 18f46k22 test PIC

// ------------------
//  phase adjusting driver
//  flag==0 means use individual phase words ,flag==1 set all to 'Q'
// ------------------
//
VOID DNOdrVP(int1 flag , unsigned int16 Q){
     unsigned INT8 I=0;
     unsigned int16 MPA=0b1100000000000000;
     unsigned int16 MPB=0b1100000000000000;
     unsigned int16 MPC=0b1100000000000000;
     #BIT OBIT=Q.15
     #bit PHSA=MPA.15
     #bit PHSB=MPB.15
     #bit PHSC=MPC.15
      if(0==flag){
            MPA |=phasea;             MPB |=phaseb;       MPC |=phasec;
      }
      else{
            MPA |=Q;    MPB |=Q;      MPC |=Q;  // note Q for all phases
     }
     oscl |=0b00010011; //  raise clock &loadshift
     output_b(oscl);
     DL8;  // 
     output_low(pin_b0);
     do{              // do both a and b data

        if (PHSA) output_high(pin_b2); // oscl |=0b00000111;   
        else      output_low(pin_B2);  // oscl &=0b11111011;   
        if (PHSb) output_high(pin_b3); //oscl |=0b00001011;   
        else      output_low(pin_B3 ); // oscl &=0b11110111;   
        if (PHSC) output_high(pin_b4); //oscl |=0b00001011;   
        else      output_low(pin_B4 ); // oscl &=0b11110111;   
        output_low(pin_b1); // low clock
        DL8;
        output_high(pin_b1); // raise then  shift bits
        MPA <<=1;  MPB <<=1; MPC <<=1;                       
        I++;
       }WHILE (I<16);

      output_low(pin_B2); output_low(pin_B3); output_low(pin_B4);
      DL8;
      output_high(pin_b0);
      oscl |=0b00010011; //  RAISE loadshift
      output_B(oscl);    //
}
// frequency changer
VOID DNOdrV(unsigned int16 Q){
     #BIT OBIT=Q.15
     unsigned INT8 I=0;
     oscl |=0b00010011; //  raise clock &loadshift
     output_B(oscl);   
     DL8;
     output_low(pin_b0);
     DL8;
     do{              // do both a and b data

        if (OBIT) { output_high(pin_B2); output_high(pin_B3);output_high(pin_B4);}
        else      { output_low(pin_B2); output_low(pin_B3); output_low(pin_B4);}
        DL8;
        output_low(pin_b1); // low clock
        DL8;               ///delay_cycles(8);
        output_high(pin_b1); // raise
        DL8;               ///delay_cycles(8);
        Q <<=1;            //shift bits
        I++;
       }WHILE (I<16);
      output_low(pin_B2); output_low(pin_B3);
      DL8;       output_high(pin_b0);
      oscl |=0b00010011; //  RAISE loadshift
      output_B(oscl);    //
}

void LLfreq (void){
     DNOdrvP(0,0);                     delay_us(4);
     DNOdrv( (0x4000+lopart ));        delay_us(4);
     DNOdrv( (0x4000+hipart ));
}

void DNO_FREQSET_LL(void ){
     hipart=  (infreq >> 9);      lopart=  ((infreq<<5)&16383 ); //
     LLfreq();
}
//
// DNO_mode: ALWAYS sine wave for this app
// CALL THIS BEFORE ANY OTHER CALL to PREP/INIT
//  the 9833's or reset them 
void setupDNO(void ){  // mode
        //  setup    this resets the chip to a ready state

         DNOdrv(0x2100);  // send RESET SIN word case 0 and 1 for now
         delay_US ( 10 );   
         llfreq();
         DNOdrvP(1,0xC000); // PHASE CTL word to mid scale
         // send the two block  prep word for curr mode
         DNOdrv(0x2000);   // send RESET SIN word case 0 and 1 for now
         delay_US ( 10 );   // dp 911 was 4 us add delay
         llfreq();
}
// change all 3 NCO sine frequencies with this call
// while maintaining accurate phase relationships
// update phase a,b,c  by altering the values of each var
// before calling this master function
//** 'option' is the INTEGER frequency you want to set
void dnofreqset( unsigned int32 option ){
   infreq=option;   DNO_FREQSET_LL();
}
freedom



Joined: 10 Jul 2011
Posts: 54

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 26, 2015 9:00 am     Reply with quote

Thanks a lot asmboy for posting 3 phase , frequency agile, ULTRA high purity sine generator

1. What do you mean by NCO (ref: AD9833 NCO) ?

Quote:
" Phase is set to one part in 4096 of 360 degrees by altering the vars: "

2. Please explain the above statement.

3. Can this code can be used for 3 phase AC motor inverter ?

4. Would you like to post an example circuit ?

thanks
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Nov 26, 2015 10:52 am     Reply with quote

1. NCO = Numerically controlled oscillator aka DNO Digital numeric Oscillator.
The mfgr: calls their version of the technology
DDS -Direct Digital Synthesis

Their description says

The AD9833 is a low power, programmable waveform generator
capable of producing sine, triangular, and square wave outputs.

Call it whatever you like ;-))

2. From the AD9833 datasheet - the phase control word is 12bits -
and the vars are phasea,b,c --- got it ?

3. YES - IF you have a suitable power amplifier circuit.
// This circuit has MUCH lower harmonic content than the usual source for a power inverter however.

4. circuit for what ?
This design was created for a multi-channel synchronous demodulator.
basic circuit examples are in the AD datasheet. This allows a reference channel and 'X' and 'Y' with quadrature or any other phase relationships you desire -plus phase offsets in 12 bit space.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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