AnsweredAssumed Answered

AD9837 with PIC18F

Question asked by Den123 on May 8, 2017
Latest reply on May 18, 2017 by LouijieC

Hi, i need some help with programming AD9837. I need to generate frequences between 12050Hz - 20050Hz. MCLK=15MHz. I'm using PIC18F47J53 to program AD9837 and mikroC. I've written some functions for this, sometimes it looks that AD works well, but sometimes it generates triangle at the output, when i program to generate sine wave, sometimes it generates pulse width, but sometimes it generates sine wave with another frequency. I don't know what is the problem because all timing requirements performed. 

I'm sending to AD regs this:

0) 0x2100;

1) 0x65C6;

2)0x4088;

3)0xC001;

4)0xC000;

5)0x2000;

 

The code that i've written have tis functions:

 

unsigned long temp_freq;

unsigned int part1,part2;

 unsigned short send_l,send_h;

 

//calculating regs values

void freq_calc(unsigned long freq, unsigned short reg_num) //reg_num - freq0 or freq1 register
{
temp_freq = freq+125000;
temp_freq = temp_freq*coeff; //coeff=2^28/15MHz=17.896
part1 = loword(temp_freq) & 0x3FFF; //LSB
if (reg_num==0) part1 = part1 | 0x4000; 
else if (reg_num==1) part1 = part1 | 0x8000;
part2 = hiword(temp_freq) & 0x3FFF; //MSB
part2 = part2 << 2; 
temp_int = loword (temp_freq);
temp_int = temp_int>>14;
part2 = part2 + temp_int;
if (reg_num==0) part2 = part2 | 0x4000; 
else if (reg_num==1) part2 = part2 | 0x8000;
}

 

//sending to AD9837 function

void send_adv(unsigned int info, unsigned short flag)
{
unsigned short j1;
send_h = info>>8;
send_l = info;

PORTB.B4=1;//SCLK
delay_us(1);
PORTE.B2=0;// chip select
for(j1=0;j1<8;j1++)
{
PORTB.B4=1;
delay_us(1);
PORTC.B7=send_h.B7;//DATA
send_h<<=1;
delay_us(1);
PORTB.B4=0;
delay_us(2); //
}

for(j1=0;j1<8;j1++)
{
PORTB.B4=1;
delay_us(1);
PORTC.B7=send_l.B7;
send_l<<=1;
delay_us(1);
PORTB.B4=0;
delay_us(2);
if (j1==7)
{
PORTB.B4=1;
delay_us(1);
PORTE.B2=1;
if (flag==1) delay_us(20);
}
}
}

 

//writing to AD9837 function 

void Freq_write(unsigned short reg)
{
SSP1CON1.B5 = 0;
PIE1.TMR2IE = 0;
Port1_Sel();
if (reg==0) send_adv(0x2100,0); //2168
else if (reg==1) send_adv(0x2D00,0);
send_adv(part1,0); //part1
send_adv(part2,0); //part2
if (reg==0) { send_adv(0xC001,0); send_adv(0xC000,0); send_adv(0x2000,1); }
else if (reg==1) {send_adv(0xE001,0); send_adv(0xE000,0); send_adv(0x2C00,1); }
SSP1CON1.B5 = 1;
PIE1.TMR2IE = 1;
delay_ms(1);
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);

}

 

A have another peripherial at SPI1 port, thus i've disabled SSP1CON1.B5 = 0 at  transition time, as you can see i've disabled my interrupts PIE1.TMR2IE = 0 too(i'm using only timer 2 interrupt).

Attached files - photo with my oscilloscope results. (Sorry, it has only two chanels). 

Blue - data, yellow - SCLK

IMG_1 - all my transitions to AD9837. IMG_5 -  first and second words. IMG_6  - third and fourth words,  IMG_6  - fifth and sixth words.

 

May be someone help me , what is my error?

Attachments

Outcomes