A sine wave generator using AD9833 and AD9850 using STM32F103RB
This is a sine wave generator using DDS IC' AD9833 and AD9850. The STM32F1 microcontroller produces the SPI commands for the two DDS.
Learn more about STM32F1 in my blog: https://www.teachmemicro.com
AD9833.h@2:602f7589c53e, 2017-11-21 (annotated)
- Committer:
- roland_tmm
- Date:
- Tue Nov 21 19:18:25 2017 +0000
- Revision:
- 2:602f7589c53e
- Parent:
- 0:6069c0f2a245
Edited comments/description;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
roland_tmm | 2:602f7589c53e | 1 | /* AD9833 library for STM3F103 |
roland_tmm | 0:6069c0f2a245 | 2 | * AD9833.h |
roland_tmm | 2:602f7589c53e | 3 | * Roland Pelayo |
roland_tmm | 2:602f7589c53e | 4 | * |
roland_tmm | 2:602f7589c53e | 5 | * Based on the library from Bill Williams <wlwilliams1952@gmail.com, github/BillWilliams1952> |
roland_tmm | 2:602f7589c53e | 6 | * |
roland_tmm | 0:6069c0f2a245 | 7 | * This program is free software; you can redistribute it and/or modify |
roland_tmm | 0:6069c0f2a245 | 8 | * it under the terms of the GNU General Public License as published by |
roland_tmm | 0:6069c0f2a245 | 9 | * the Free Software Foundation; either version 2 of the License, or |
roland_tmm | 0:6069c0f2a245 | 10 | * (at your option) any later version. |
roland_tmm | 0:6069c0f2a245 | 11 | * |
roland_tmm | 0:6069c0f2a245 | 12 | * This program is distributed in the hope that it will be useful, |
roland_tmm | 0:6069c0f2a245 | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
roland_tmm | 0:6069c0f2a245 | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
roland_tmm | 0:6069c0f2a245 | 15 | * GNU General Public License for more details. |
roland_tmm | 0:6069c0f2a245 | 16 | * |
roland_tmm | 0:6069c0f2a245 | 17 | * You should have received a copy of the GNU General Public License |
roland_tmm | 0:6069c0f2a245 | 18 | * along with this program; if not, write to the Free Software |
roland_tmm | 0:6069c0f2a245 | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
roland_tmm | 0:6069c0f2a245 | 20 | * MA 02110-1301, USA. |
roland_tmm | 0:6069c0f2a245 | 21 | * |
roland_tmm | 0:6069c0f2a245 | 22 | * |
roland_tmm | 0:6069c0f2a245 | 23 | */ |
roland_tmm | 0:6069c0f2a245 | 24 | |
roland_tmm | 0:6069c0f2a245 | 25 | #ifndef __AD9833__ |
roland_tmm | 0:6069c0f2a245 | 26 | |
roland_tmm | 0:6069c0f2a245 | 27 | #define __AD9833__ |
roland_tmm | 0:6069c0f2a245 | 28 | |
roland_tmm | 0:6069c0f2a245 | 29 | #include "mbed.h" |
roland_tmm | 0:6069c0f2a245 | 30 | |
roland_tmm | 0:6069c0f2a245 | 31 | //#define FNC_PIN 4 // Define FNC_PIN for fast digital writes |
roland_tmm | 0:6069c0f2a245 | 32 | |
roland_tmm | 0:6069c0f2a245 | 33 | //#ifdef FNC_PIN |
roland_tmm | 0:6069c0f2a245 | 34 | // Use digitalWriteFast for a speedup |
roland_tmm | 0:6069c0f2a245 | 35 | // #include "digitalWriteFast.h" |
roland_tmm | 0:6069c0f2a245 | 36 | // #define WRITE_FNCPIN(Val) digitalWriteFast2(FNC_PIN,(Val)) |
roland_tmm | 0:6069c0f2a245 | 37 | //#else // otherwise, just use digitalWrite |
roland_tmm | 0:6069c0f2a245 | 38 | // #define WRITE_FNCPIN(Val) digitalWrite(FNCpin,(Val)) |
roland_tmm | 0:6069c0f2a245 | 39 | //#endif |
roland_tmm | 0:6069c0f2a245 | 40 | |
roland_tmm | 0:6069c0f2a245 | 41 | #define pow2_28 268435456L // 2^28 used in frequency word calculation |
roland_tmm | 0:6069c0f2a245 | 42 | #define BITS_PER_DEG 11.3777777777778 // 4096 / 360 |
roland_tmm | 0:6069c0f2a245 | 43 | |
roland_tmm | 0:6069c0f2a245 | 44 | #define RESET_CMD 0x0100 // Reset enabled (also CMD RESET) |
roland_tmm | 0:6069c0f2a245 | 45 | /* Sleep mode |
roland_tmm | 0:6069c0f2a245 | 46 | * D7 1 = internal clock is disabled |
roland_tmm | 0:6069c0f2a245 | 47 | * D6 1 = put DAC to sleep |
roland_tmm | 0:6069c0f2a245 | 48 | */ |
roland_tmm | 0:6069c0f2a245 | 49 | #define SLEEP_MODE 0x00C0 // Both DAC and Internal Clock |
roland_tmm | 0:6069c0f2a245 | 50 | #define DISABLE_DAC 0x0040 |
roland_tmm | 0:6069c0f2a245 | 51 | #define DISABLE_INT_CLK 0x0080 |
roland_tmm | 0:6069c0f2a245 | 52 | |
roland_tmm | 0:6069c0f2a245 | 53 | #define PHASE_WRITE_CMD 0xC000 // Setup for Phase write |
roland_tmm | 0:6069c0f2a245 | 54 | #define PHASE1_WRITE_REG 0x2000 // Which phase register |
roland_tmm | 0:6069c0f2a245 | 55 | #define FREQ0_WRITE_REG 0x4000 // |
roland_tmm | 0:6069c0f2a245 | 56 | #define FREQ1_WRITE_REG 0x8000 |
roland_tmm | 0:6069c0f2a245 | 57 | #define PHASE1_OUTPUT_REG 0x0400 // Output is based off REG0/REG1 |
roland_tmm | 0:6069c0f2a245 | 58 | #define FREQ1_OUTPUT_REG 0x0800 // ditto |
roland_tmm | 0:6069c0f2a245 | 59 | |
roland_tmm | 0:6069c0f2a245 | 60 | typedef enum { SINE_WAVE = 0x2000, TRIANGLE_WAVE = 0x2002, |
roland_tmm | 0:6069c0f2a245 | 61 | SQUARE_WAVE = 0x2028, HALF_SQUARE_WAVE = 0x2020 } WaveformType; |
roland_tmm | 0:6069c0f2a245 | 62 | |
roland_tmm | 0:6069c0f2a245 | 63 | typedef enum { REG0, REG1, SAME_AS_REG0 } Registers; |
roland_tmm | 0:6069c0f2a245 | 64 | |
roland_tmm | 0:6069c0f2a245 | 65 | class AD9833 { |
roland_tmm | 0:6069c0f2a245 | 66 | |
roland_tmm | 0:6069c0f2a245 | 67 | public: |
roland_tmm | 0:6069c0f2a245 | 68 | |
roland_tmm | 0:6069c0f2a245 | 69 | AD9833 (uint32_t referenceFrequency = 25000000UL ); |
roland_tmm | 0:6069c0f2a245 | 70 | |
roland_tmm | 0:6069c0f2a245 | 71 | // Must be the first command after creating the AD9833 object. |
roland_tmm | 0:6069c0f2a245 | 72 | void Begin ( void ); |
roland_tmm | 0:6069c0f2a245 | 73 | |
roland_tmm | 0:6069c0f2a245 | 74 | // Setup and apply a signal. Note that any calls to EnableOut, |
roland_tmm | 0:6069c0f2a245 | 75 | // SleepMode, DisableDAC, or DisableInternalClock remain in effect |
roland_tmm | 0:6069c0f2a245 | 76 | void ApplySignal ( WaveformType waveType, Registers freqReg, |
roland_tmm | 0:6069c0f2a245 | 77 | float frequencyInHz, |
roland_tmm | 0:6069c0f2a245 | 78 | Registers phaseReg = SAME_AS_REG0, float phaseInDeg = 0.0 ); |
roland_tmm | 0:6069c0f2a245 | 79 | |
roland_tmm | 0:6069c0f2a245 | 80 | // Resets internal registers to 0, which corresponds to an output of |
roland_tmm | 0:6069c0f2a245 | 81 | // midscale - digital output at 0. See EnableOutput function |
roland_tmm | 0:6069c0f2a245 | 82 | void Reset ( void ); |
roland_tmm | 0:6069c0f2a245 | 83 | |
roland_tmm | 0:6069c0f2a245 | 84 | // Update just the frequency in REG0 or REG1 |
roland_tmm | 0:6069c0f2a245 | 85 | void SetGENFrequency ( Registers freqReg, float frequency ); |
roland_tmm | 0:6069c0f2a245 | 86 | |
roland_tmm | 0:6069c0f2a245 | 87 | // Increment the selected frequency register by freqIncHz |
roland_tmm | 0:6069c0f2a245 | 88 | void IncrementFrequency ( Registers freqReg, float freqIncHz ); |
roland_tmm | 0:6069c0f2a245 | 89 | |
roland_tmm | 0:6069c0f2a245 | 90 | // Update just the phase in REG0 or REG1 |
roland_tmm | 0:6069c0f2a245 | 91 | void SetPhase ( Registers phaseReg, float phaseInDeg ); |
roland_tmm | 0:6069c0f2a245 | 92 | |
roland_tmm | 0:6069c0f2a245 | 93 | // Increment the selected phase register by phaseIncDeg |
roland_tmm | 0:6069c0f2a245 | 94 | void IncrementPhase ( Registers phaseReg, float phaseIncDeg ); |
roland_tmm | 0:6069c0f2a245 | 95 | |
roland_tmm | 0:6069c0f2a245 | 96 | // Set the output waveform for the selected frequency register |
roland_tmm | 0:6069c0f2a245 | 97 | // SINE_WAVE, TRIANGLE_WAVE, SQUARE_WAVE, HALF_SQUARE_WAVE, |
roland_tmm | 0:6069c0f2a245 | 98 | void SetWaveform ( Registers waveFormReg, WaveformType waveType ); |
roland_tmm | 0:6069c0f2a245 | 99 | |
roland_tmm | 0:6069c0f2a245 | 100 | // Output based on the contents of REG0 or REG1 |
roland_tmm | 0:6069c0f2a245 | 101 | void SetOutputSource ( Registers freqReg, Registers phaseReg = SAME_AS_REG0 ); |
roland_tmm | 0:6069c0f2a245 | 102 | |
roland_tmm | 0:6069c0f2a245 | 103 | // Turn ON / OFF output using the RESET command. |
roland_tmm | 0:6069c0f2a245 | 104 | void EnableOutput ( bool enable ); |
roland_tmm | 0:6069c0f2a245 | 105 | |
roland_tmm | 0:6069c0f2a245 | 106 | // Enable/disable Sleep mode. Internal clock and DAC disabled |
roland_tmm | 0:6069c0f2a245 | 107 | void SleepMode ( bool enable ); |
roland_tmm | 0:6069c0f2a245 | 108 | |
roland_tmm | 0:6069c0f2a245 | 109 | // Enable / Disable DAC |
roland_tmm | 0:6069c0f2a245 | 110 | void DisableDAC ( bool enable ); |
roland_tmm | 0:6069c0f2a245 | 111 | |
roland_tmm | 0:6069c0f2a245 | 112 | // Enable / Disable Internal Clock |
roland_tmm | 0:6069c0f2a245 | 113 | void DisableInternalClock ( bool enable ); |
roland_tmm | 0:6069c0f2a245 | 114 | |
roland_tmm | 0:6069c0f2a245 | 115 | // Return actual frequency programmed in register |
roland_tmm | 0:6069c0f2a245 | 116 | float GetActualProgrammedFrequency ( Registers reg ); |
roland_tmm | 0:6069c0f2a245 | 117 | |
roland_tmm | 0:6069c0f2a245 | 118 | // Return actual phase programmed in register |
roland_tmm | 0:6069c0f2a245 | 119 | float GetActualProgrammedPhase ( Registers reg ); |
roland_tmm | 0:6069c0f2a245 | 120 | |
roland_tmm | 0:6069c0f2a245 | 121 | // Return frequency resolution |
roland_tmm | 0:6069c0f2a245 | 122 | float GetResolution ( void ); |
roland_tmm | 0:6069c0f2a245 | 123 | |
roland_tmm | 0:6069c0f2a245 | 124 | private: |
roland_tmm | 0:6069c0f2a245 | 125 | |
roland_tmm | 0:6069c0f2a245 | 126 | //Write to FNCpin |
roland_tmm | 0:6069c0f2a245 | 127 | void FNCWrite(int val); |
roland_tmm | 0:6069c0f2a245 | 128 | void WriteRegister ( int16_t dat ); |
roland_tmm | 0:6069c0f2a245 | 129 | void WriteControlRegister ( void ); |
roland_tmm | 0:6069c0f2a245 | 130 | uint16_t waveForm0, waveForm1; |
roland_tmm | 0:6069c0f2a245 | 131 | uint8_t outputEnabled, DacDisabled, IntClkDisabled; |
roland_tmm | 0:6069c0f2a245 | 132 | uint32_t refFrequency; |
roland_tmm | 0:6069c0f2a245 | 133 | float frequency0, frequency1, phase0, phase1; |
roland_tmm | 0:6069c0f2a245 | 134 | Registers activeFreq, activePhase; |
roland_tmm | 0:6069c0f2a245 | 135 | }; |
roland_tmm | 0:6069c0f2a245 | 136 | |
roland_tmm | 0:6069c0f2a245 | 137 | #endif |