PIC18 LaurTec Library  3.1
Open Source C Library for PIC18 Microcontrollers based on C18 - XC8 Compilers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
AD9833.c
Go to the documentation of this file.
1 /*******************************************************************************
2 
3 Author : Dario Di Turi
4 Version : 1.1
5 Date : 08/12/2012
6 
7 Last Update: Mauro Laurenti
8 Last Update: 02/02/2013
9 
10 ********************************************************
11 SOFTWARE LICENSE AGREEMENT
12 ********************************************************
13 
14 The usage of the supplied software imply the acceptance of the following license.
15 
16 The software supplied herewith by Dario Di Turi (the Author) is intended for
17 use solely and exclusively on Microchip PIC Microcontroller (registered mark).
18 The software is owned by the Author, and is protected under applicable
19 copyright laws. All rights are reserved.
20 Any use in violation of the foregoing restrictions may subject the
21 user to criminal sanctions under applicable laws, as well as to civil liability
22 for the breach of the terms and conditions of this license.
23 Commercial use is forbidden without a written acknowledgment with the Author.
24 Personal or educational use is allowed if the application containing the
25 following software doesn't aim to commercial use or monetary earning of any kind.
26 
27 THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
28 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
29 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT,
31 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
32 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
33 *************************************************************/
34 
35 #ifdef __XC8
36  #include <xc.h>
37 #endif
38 
39 #include "AD9833.h"
40 
41 unsigned int K;
42 unsigned int register_word;
43 unsigned int tuning_freq;
44 
45 
46 //*********************************************
47 // write_register
48 //*********************************************
49 void write_data_AD9833(unsigned int data){
50 
51  OpenSPI(SPI_FOSC_64,MODE_10,SMPMID);
52 
53  //FSYNC low, load word into the device
54  FSYNC=0;
55 
56  //MSB data
57  while(WriteSPI(data>>8));
58  //LSB data
59  while(WriteSPI(data));
60 
61  //FSYNC high, load word completed
62  FSYNC=1;
63  CloseSPI();
64 
65 }
66 
67 
68 //*********************************************
69 // compose_AD9833_control_word
70 //*********************************************
71 unsigned int compose_AD9833_control_word(unsigned char function_type){
72 
73 
74  // Write frequency register
75  if(function_type==0){
76  register_word=register_word | 0b0010000000000000;
77  return(register_word);
78  }
79 
80  // Sinusoidal waveform
81  if(function_type==1){
82  register_word=register_word & 0b1111111111000000;
83  return(register_word);
84  }
85 
86  // Triangular waveform
87  if(function_type==2){
88  register_word=register_word & 0b1111111111000000;
89  register_word=register_word | 0b0000000000000010;
90  return(register_word);
91  }
92 
93  // Square waveform
94  if(function_type==3){
95  register_word=register_word & 0b1111111111000000;
96  register_word=register_word | 0b0000000000101000;
97  return(register_word);
98 
99  }
100  // FREQ0 out
101  if(function_type==4){
102  register_word=register_word & 0b1111011111111111;
103  return(register_word);
104 
105  }
106  // FREQ1 out
107  if(function_type==5){
108  register_word=register_word & 0b1111011111111111;
109  register_word=register_word | 0b0000100000000000;
110  return(register_word);
111 
112  }
113  // PHASE0 out
114  if(function_type==6){
115  register_word=register_word & 0b1111101111111111;
116  return(register_word);
117 
118  }
119  // PHASE1 out
120  if(function_type==7){
121  register_word=register_word & 0b1111101111111111;
122  register_word=register_word | 0b0000010000000000;
123  return(register_word);
124 
125  }
126  // Write LSB frequency register
127  if(function_type==8){
128  register_word=register_word & 0b0000111111111111;
129  return(register_word);
130 
131  }
132  // Sleep mode
133  if(function_type==9){
134  register_word=register_word & 0b1111111100111111;
135  register_word=register_word | 0b0000010011000000;
136  return(register_word);
137 
138  }
139  // Power ON
140  if(function_type==10){
141  register_word=register_word & 0b1111111100111111;
142  return(register_word);
143 
144  }
145 
146  // This return is never executed but it removes a compiler warning.
147  return (0);
148 }
149 
150 
151 //*********************************************
152 // init_AD9833
153 //*********************************************
154 void initialize_AD9833(unsigned char fmclk){
155 
156  register_word=0x0000;
157  tuning_freq=0x0000;
158 
159  K=268435456/(fmclk*100000); //2^28/(fmclk*100000)
160 
166 
167 
171 
172 }
173 
174 
175 //*********************************************
176 // set_frequency_AD9833
177 //*********************************************
178 void set_frequency_AD9833(unsigned long freq_value, unsigned char frequency_register){
179 
180  unsigned long freq_reg_value;
181  unsigned int freq_reg_value_l,freq_reg_value_h;
182  unsigned int control_word;
183 
184  freq_reg_value = (freq_value/10) * K; //2^28/(fmclk)
185 
186  freq_reg_value = freq_reg_value << 2;
187  freq_reg_value_l = freq_reg_value;
188  freq_reg_value_h = freq_reg_value >> 16;
189  freq_reg_value_l = freq_reg_value_l >> 2;
190 
191  // Save the LSB frequency register for the tuning function
192  tuning_freq=freq_reg_value_l;
193 
194  // Write into FREQ0 register
195  if(frequency_register==0){
196 
197  freq_reg_value_l = freq_reg_value_l & 0x7FFF; //0b0111,1111,1111,1111
198  freq_reg_value_l = freq_reg_value_l | 0x4000; //0b0100,0000,0000,0000
199 
200  freq_reg_value_h = freq_reg_value_h & 0x7FFF;
201  freq_reg_value_h = freq_reg_value_h | 0x4000;
202  }
203 
204  // Write into FREQ1 register
205  if(frequency_register==1){
206 
207  freq_reg_value_l = freq_reg_value_l & 0xBFFF; //0b1011,1111,1111,1111
208  freq_reg_value_l = freq_reg_value_l | 0x8000; //0b1000,0000,0000,0000
209 
210  freq_reg_value_h = freq_reg_value_h & 0xBFFF;
211  freq_reg_value_h = freq_reg_value_h | 0x8000;
212  }
213 
214  control_word=compose_AD9833_control_word(0);
215  write_data_AD9833(control_word);
216  write_data_AD9833(freq_reg_value_l);
217  write_data_AD9833(freq_reg_value_h);
218 
219 }
220 
221 
222 //*********************************************
223 // tuning_frequency_AD9833
224 //*********************************************
225 void tuning_frequency_AD9833(unsigned char tuning_step, unsigned char direction,unsigned char frequency_register ){
226 
227  unsigned int control_word;
228 
229  //tuning DOWN
230  if(direction==0){
231 
232  tuning_freq=tuning_freq-tuning_step;
233  }
234  //tuning UP
235  if(direction==1){
236 
237  tuning_freq=tuning_freq+tuning_step;
238  }
239  // Write into FREQ0 register
240  if(frequency_register==0){
241 
242  tuning_freq = tuning_freq & 0x7FFF; //0b0111,1111,1111,1111
243  tuning_freq = tuning_freq | 0x4000; //0b0100,0000,0000,0000
244 
245  }
246 
247  // Write into FREQ1 register
248  if(frequency_register==1){
249 
250  tuning_freq = tuning_freq & 0xBFFF; //0b1011,1111,1111,1111
251  tuning_freq = tuning_freq | 0x8000; //0b1000,0000,0000,0000
252 
253  }
254 
255  control_word=compose_AD9833_control_word(8);
256  write_data_AD9833(control_word);
258 
259 }
260 
261 //*********************************************
262 // set_phase_AD9833
263 //*********************************************
264 void set_phase_AD9833(unsigned short long phase_value, unsigned char phase_register){
265 
266  unsigned int phase_reg;
267 
268  phase_value=(phase_value*1137)/1000;
269 
270  phase_reg=phase_value;
271 
272  // Write into PHASE0 register
273  if(phase_register==0){
274 
275  phase_reg=phase_reg & 0xFFF; //0b0000111111111111
276  phase_reg=phase_reg | 0xC000; //0b1100000000000000
277  }
278 
279  // Write into PHASE1 register
280  if(phase_register==1){
281 
282  phase_reg=phase_reg & 0xFFF; //0b0000111111111111
283  phase_reg=phase_reg | 0xE000; //0b1110000000000000
284  }
285 
286  write_data_AD9833(phase_reg);
287 
288 }
289 
290 //*********************************************
291 // set_function_AD9833
292 //*********************************************
293 void set_function_AD9833(unsigned char function_type){
294 
295  unsigned int function;
296 
297  switch(function_type){
298 
299  case SIN:
300  function=compose_AD9833_control_word(1);
301  write_data_AD9833(function);
302  break;
303 
304  case TRIANGLE:
305  function=compose_AD9833_control_word(2);
306  write_data_AD9833(function);
307  break;
308 
309  case SQUARE:
310  function=compose_AD9833_control_word(3);
311  write_data_AD9833(function);
312  break;
313 
314  case FREQUENCY0_OUT:
315  function=compose_AD9833_control_word(4);
316  write_data_AD9833(function);
317  break;
318 
319  case FREQUENCY1_OUT:
320  function=compose_AD9833_control_word(5);
321  write_data_AD9833(function);
322  break;
323 
324  case PHASE0_OUT:
325  function=compose_AD9833_control_word(6);
326  write_data_AD9833(function);
327  break;
328 
329  case PHASE1_OUT:
330  function=compose_AD9833_control_word(7);
331  write_data_AD9833(function);
332  break;
333 
334  case SLEEP_MODE:
335  function=compose_AD9833_control_word(9);
336  write_data_AD9833(function);
337  break;
338 
339  case POWER_ON:
340  function=compose_AD9833_control_word(10);
341  write_data_AD9833(function);
342  break;
343  }
344 
345 }
346 
347 
348 
349