PIC18 LaurTec Library  3.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.2
5 Date : 08/12/2012
6 
7 Last Update: Mauro Laurenti
8 Last Update: 15/12/2014
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 acknowledgement 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 AD9833_write_data(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 AD9833_compose_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 // AD9833_initialize
153 //*********************************************
154 void AD9833_initialize (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 // AD9833_set_frequency
177 //*********************************************
178 void AD9833_set_frequency (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 = AD9833_compose_control_word(0);
215  AD9833_write_data (control_word);
216  AD9833_write_data (freq_reg_value_l);
217  AD9833_write_data (freq_reg_value_h);
218 
219 }
220 
221 
222 //*********************************************
223 // AD9833_tuning_frequency
224 //*********************************************
225 void AD9833_tuning_frequency (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 = AD9833_compose_control_word(8);
256  AD9833_write_data (control_word);
258 
259 }
260 
261 //*********************************************
262 // AD9833_set_phase
263 //*********************************************
264 void AD9833_set_phase (unsigned 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  AD9833_write_data (phase_reg);
287 
288 }
289 
290 //*********************************************
291 // AD9833_set_function
292 //*********************************************
293 void AD9833_set_function (unsigned char function_type){
294 
295  unsigned int function;
296 
297  switch(function_type){
298 
299  case AD9833_SIN:
300  function = AD9833_compose_control_word(1);
301  AD9833_write_data (function);
302  break;
303 
304  case AD9833_TRIANGLE:
305  function = AD9833_compose_control_word(2);
306  AD9833_write_data (function);
307  break;
308 
309  case AD9833_SQUARE:
310  function = AD9833_compose_control_word(3);
311  AD9833_write_data (function);
312  break;
313 
315  function = AD9833_compose_control_word(4);
316  AD9833_write_data (function);
317  break;
318 
320  function = AD9833_compose_control_word(5);
321  AD9833_write_data (function);
322  break;
323 
324  case AD9833_PHASE0_OUT:
325  function = AD9833_compose_control_word(6);
326  AD9833_write_data (function);
327  break;
328 
329  case AD9833_PHASE1_OUT:
330  function = AD9833_compose_control_word(7);
331  AD9833_write_data (function);
332  break;
333 
334  case AD9833_SLEEP_MODE:
335  function = AD9833_compose_control_word(9);
336  AD9833_write_data (function);
337  break;
338 
339  case AD9833_POWER_ON:
340  function = AD9833_compose_control_word(10);
341  AD9833_write_data (function);
342  break;
343  }
344 }
345 
346 
347 
348