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 CCS Technical Support

Help translating AD9833 code from C18 (?) to CCS

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



Joined: 19 May 2019
Posts: 6

View user's profile Send private message Send e-mail Visit poster's website

Help translating AD9833 code from C18 (?) to CCS
PostPosted: Thu Jan 02, 2020 8:05 am     Reply with quote

Hi, i found this code on some chinese website for the AD9833 spi comunication.
I liked it because it seems preety simple, at least for start.
But im having troubles translating it to CCS. If anyone can help me with this ill be thankfull.
Or, if you have already a library for the AD9833 writen for CCS ill be even more thankfull.

The code:

Code:

#include<p18f4550.h>   

void            ConfigureProcessor  (void);             /* Configuring the processor for 8 Mhz internal clock */
void            SpiComm         (void);             /* Function for SPI transmission */   
void            ConfigureSPI        (void);             /* Configuring the SPI Module */   
unsigned char       WriteSPI        ( unsigned char );   
   
void main (void)   
 {   
   
    ConfigureProcessor();   
    ConfigureSPI();   
   
     while(1)   
        {   
        SpiComm();   
        }   
 }   
   
void ConfigureProcessor (void)   
 {   
    OSCTUNEbits.INTSRC  = 0;   
    OSCCONbits.SCS0     = 0;   
    OSCCONbits.SCS1     = 1;   
    OSCCONbits.IRCF0    = 1;    /* 8 MHz Internal Clock */   
    OSCCONbits.IRCF1    = 1;   
    OSCCONbits.IRCF2    = 1;   
    INTCON2bits.RBPU    = 0;   
    PORTEbits.RDPU      = 0;   
    TRISB               = 0;   
    STATUS          = 0;   
 }   
   
void ConfigureSPI (void)   
 {   
   
    TRISBbits.TRISB1         =  0;  /* SCK = Output */   
    TRISBbits.TRISB0         =  1;  /* SDI = Output, as PIC is only doing SPI transmission */   
                        /* in master mode, So configured with opposite value */   
   
    TRISCbits.TRISC7        =  0;   /* SDO = Output */   
    TRISAbits.TRISA5        =  0;   /* SS pin disabled as SPI is in master mode */   
   
    SSPSTATbits.CKE     =  0;   /* Data is transmitted on falling clock edge as per AD9833 datasheet */   
    SSPSTATbits.SMP     =  0;   /* Sampling of data occurs in the middle */   
   
    SSPCON1         =  0x30;  /* SSPSEN = 1 and Clock Idle is HIGH, and FOSC/4 */   
   
 }   
   
void SpiComm (void)   
 {   
   
    PORTBbits.RB2  = 0;     /* Making FSYNC of AD9833 LOW before writing to Control Register */   
    WriteSPI(0b00100001);   /* D15 - D8, Writing to Control Regsiter */   
    WriteSPI(0b00000000);   /* Setting for Sine Wave Output  D5 = 0, and D1 = 0*/   
    PORTBbits.RB2  = 1;     /* Making FSYNC of AD9833 HIGH after writing 16 bits to Control Register */   
   
     // Here I am Writing 01100010010011 (D13 - D0), 14 LSB bits to FREQ0 Register   
   
    PORTBbits.RB2  = 0;     /* Making FSYNC of AD9833 LOW before writing the 14 bit LSBs to FREQ0 */   
    WriteSPI(0b01011000);   /* D15 = 0, D14 = 1 represents FREQ0 and D13 to D0 represents 14 LSBs */   
    WriteSPI(0b10010011);   /* D7 - D0 */   
    PORTBbits.RB2  = 1;     /* Making FSYNC of AD9833 HIGH after writing the 14 bit LSBs to FREQ0 */   
   
    // Here I am writing 00000000000010 (D13 to D0), 14 MSB bits to FREQ0 Register   
   
    PORTBbits.RB2  = 0;     /* Making FSYNC of AD9833 LOW before writing the 14 bit MSBs to FREQ0 */   
    WriteSPI(0b01000000);   /* D15 = 0, D14 = 1 represents FREQ0 and D13 to D0 represents 14 MSBs */   
    WriteSPI(0b00000010);   /* D7 - D0 */   
    PORTBbits.RB2  = 1;     /* Making FSYNC of AD9833 HIGH after writing the 14 bit MSBs to FREQ0 */   
   
    PORTBbits.RB2  = 0;     /* Making FSYNC of AD9833 LOW before writing to the Phase Register */   
    WriteSPI(0b11000000);   /* Configured for Zero Degree Phase Shift */   
    WriteSPI(0b00000000);   
    PORTBbits.RB2  = 1;     /* Making FSYNC of AD9833 HIGH after  writing to the Phase Register */   
   
    PORTBbits.RB2  = 0;     /* Making FSYNC of AD9833 LOW before writing to Control Register, HERE RESETTING THE AD9833, as D8 = 0 */   
    WriteSPI(0b00100000);   /* D15 - D8, Writing to Control Regsiter */   
    WriteSPI(0b00000000);   /* Setting for Sine Wave Output */   
    PORTBbits.RB2  = 1;     /* Making FSYNC of AD9833 HIGH after writing 16 bits to Control Register */   
   
 }   
   
   
unsigned char WriteSPI( unsigned char data_out )    /* From C18 Compiler Library */   
{   
  SSPBUF = data_out;           // write byte to SSPBUF register   
  if ( SSPCON1 & 0x80 )        // test if write collision occurred   
   return ( -1 );              // if WCOL bit is set return negative #   
  else   
  {   
    while( !SSPSTATbits.BF );  // wait until bus cycle complete   
  }   
  return ( 0 );                // if WCOL bit is not set return non-negative#   
}   
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jan 02, 2020 8:21 am     Reply with quote

Sorry I don't hve that peripheral to test with, but....You should look at the examples CCS supplies as well as the manual. From those, you'll be able to reduce that cumbersome code into 4-6 lines of CCS C !
One 'trick' is to copy the 'SPI mode defines' posted here. Maybe 'search' for them as I can't recall if they're in this forum or the 'code library.
marcoscab1166



Joined: 19 May 2019
Posts: 6

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jan 02, 2020 5:46 pm     Reply with quote

Ok, so i get tired of trying to translate. I started my own code with some pieces of other peoples code.
Most of the things come from here
https://www.ccsinfo.com/forum/viewtopic.php?t=54297
And this other link, that is on the topic above but i think its very important for people to read it all.
http://hades.mech.northwestern.edu/index.php/Waveform_Generation_with_AD9833
Sorry for creating another topic about this, but i'm trying to make it more like a library so other people can have a little easier job.
Tomorrow i'll be testing it with the AD9833 module, but for now the SPI function works pretty well.
After testing it and correcting the probable issues im gonna upload the fixed version and data of tests.
Code:

// D15, D14
#define FREQ1_WR  set(control_reg, 15);clear(control_reg, 14)
#define FREQ0_WR  clear(control_reg, 15);set(control_reg, 14)
#define PHASE     set(control_reg, 15);set(control_reg, 14)
#define CONTROL   clear(control_reg, 15);clear(control_reg, 14)
// D13 if D15, D14 = 00
#define INDIVIDUAL      clear(control_reg, 13)
#define CONSECUTIVELY   set(control_reg, 13)
// D13 if D15, D14 = 11
#define PHASE0_WR 0  clear(control_reg, 13)
#define PHASE1_WR 1  set(control_reg, 13)
// D12
#define LSB_IND   clear(control_reg, 12)
#define MSB_IND   set(control_reg, 12)
// D11
#define FREQ0_OUT clear(control_reg, 11)
#define FREQ1_OUT set(control_reg, 11)
// D10
#define PHASE0_OUT clear(control_reg, 10)
#define PHASE1_OUT set(control_reg, 10)
//D9 is reserved, is 0
// D8
#define RES_OFF clear(control_reg, 8)
#define RES_ON  set(control_reg, 8)
// D7
#define INTCLK_ON  clear(control_reg, 7)
#define INTCLK_OFF set(control_reg, 7)
// D6
#define DAC_ON  clear(control_reg, 6)
#define DAC_OFF set(control_reg, 6)
// D5
#define OUT_SQ set(control_reg, 5)
#define OUT_D1 clear(control_reg, 5)
// D4 is reserved, must be 0
// D3
#define SQ_DIV2 clear(control_reg, 3)
#define SQ_NRML set(control_reg, 3)
// D2 reserved, must be 0
// D1 if D5 is 1
#define OUT_D5  clear(control_reg, 1)
#define OUT_SN  clear(control_reg, 1)
#define OUT_TR  set(control_reg, 1)
// D0 is reserved, must be 0

#define SQUARE       0
#define SINE         1
#define TRIANGULAR   2

unsigned int16 control_reg;
unsigned int16 module_config[2];
int8 signal_type = SQUARE;

#define spi_14(x) spi_xfer(AD9833, (x & 0x3FFF) | 0x4000 , 16)   //for frequency registers
#define spi_15(x) spi_xfer(AD9833, (x & 0x3FFF) | 0xC000 , 16)   //for phase registers

// To determine in wich unit will be passed the frequency ( MHz, KHz or just Hz)
// change the following define:
// 1 for MHz, 1000 for KHz and 1000000 for Hz
#define FREQ_EXP 1 //

void AD9833_set(unsigned int module, unsigned int32 frequency, unsigned int32 phase_rad, signal_type){
   float frequency_register;
   float phase_register;
   CONTROL;
   CONSECUTIVELY;
   LSB_IND;
   FREQ0_OUT;
   PHASE0_OUT;
   RES_ON;
   INTCLK_ON;
   SQ_NRML;
   if(signal_type==SQUARE){
      DAC_OFF;
      OUT_SQ;
      OUT_D5;
   }  else if(signal_type==SINE){
      DAC_ON;
      OUT_D1;
      OUT_SN;
   }  else if(signal_type==TRIANGULAR){
      DAC_ON;
      OUT_D1;
      OUT_TR;
   }
   spi_xfer(AD9833, control_reg , 16);
   frequency_register = (frequency * 268435456) / ( 25 * FREQ_EXP);
   //Do the maths to send 28bits to freg - more reliable than DIY
   spi_14((unsigned int32)frequency_register); //send 14 LSb's
   spi_14(((unsigned int32)frequency_register>>14)); //then the next 14 bits
   phase_register=(phase_rad * 4096) / 360;
   spi_15((unsigned int32)phase_register); //send 12 bits of phase
   RES_OFF;
   spi_xfer(AD9833, control_reg , 16);
   module_config[module]=control_reg;
   module_frequency[module]=frequency;
}
marcoscab1166



Joined: 19 May 2019
Posts: 6

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sun Jan 05, 2020 3:58 pm     Reply with quote

Well, i fixed the code in the last message, changing the formula to convert the frequency value in MHz, KHz or Hz to their respective register values.
The unit that will be considered is set by the #define FREQ_EXP.
It also can be changed to use a variable so you can change the unit on the go, but i work just in MHz on this case so i preferred to keep it that way.
I dunno if the phase formula works properly, so if anyone wants to keep an eye on that, I'll be thankful. I'm in a rush for finishing this job and the phase register is not relevant for me right now.
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