AD9833 Module: Seamless Up/Down Frequency Sweep with a Sinewave Output

Started by GDeSantis, Feb 06, 2024, 06:50 PM

Previous topic - Next topic

GDeSantis

This is an update from an earlier posting which uses a PIC16F18323 to control an AD9833 Direct Digital Synthesis (DDS) module via an SPI interface. 

This program provides a sinewave up/down sweep frequency output from 1,000 Hz to 5,000 Hz at a fixed sweep rate.
To facilitate a seamless sweep, the program alternately updates the lower 14 bits of AD9833 frequency registers 0 and 1 with increasing values (Sweep Up) or decreasing values (Sweep Down).

'****************************************************************
'*  Micro    : PIC16F18323                                      *
'*  Name     : AD9833_FREQUENCY_SWEEP BETWEEN 1KHz TO 5KHz      *
'*  Date:    : 05 Feb 2024                                      *
'*  Comment  : MCU Clock = 32 MHz Internal RC Oscillator        *
'*  Comment  : AD9833 Module connected to pins RC0, RC1 & RC2   *
'*  Comment  : Alternately increase the value stored in         *
'*  Comment  : Frequency Registers 0 and 1 while cycling        *
'*  Comment  : between the Registers                            *
'*  Version  : 1.0                                              *
'*                 __________                                   *
'*                !          !                                  *
'*  (Vdd)    1  x--Vdd    Vss--x  14  (GND)                     *
'*           2  x--RA5    RA0--x  13                            *
'*           3  x--RA4    RA1--x  12                            *
'*  (MCLR)   4  x--RA3    RA2--x  11                            *
'*           5  x--RC5    RC0--x  10  (SPI CLOCK)               *
'*           6  x--RC4    RC1--x   9  (SPI_DATA)                *
'*           7  x--RC3    RC2--x   8  (FSYNC)                   *
'*                !__________!                                  *
'*                                                              *
'****************************************************************

    Device = 16F18323             ;Define device as 16F18323
    Declare Xtal = 32             ;Inform compiler of MCU clock frequency

    Config1  FEXTOSC_OFF,RSTOSC_HFINT32,CLKOUTEN_OFF,CSWEN_OFF,FCMEN_OFF
    Config2  MCLRE_ON,PWRTE_ON,WDTE_OFF,LPBOREN_OFF,BOREN_ON,BORV_HIGH,_
             PPS1WAY_OFF,STVREN_OFF,DEBUG_OFF
    Config3  WRT_ALL,LVP_OFF
    Config4  CP_ON,CPD_ON

    OSCCON1  = 0
    OSCFRQ   = %00000110          ;HFINTOSC WITH 2X PLL (32 MHZ)

    TRISA    = %001000            ;PORTA Data Direction
    TRISC    = %000000            ;PORTC Data Direction
    ANSELA   = 0                  ;Disable PORTA ADC Module
    ANSELC   = 0                  ;Disable PORTC ADC Module

    Dim CLK      As PORTC.0       ;CONNECT TO AD9833 MODULE
    Dim DAT      As PORTC.1       ;CONNECT TO AD9833 MODULE
    Dim FSYNC    As PORTC.2       ;CONNECT TO AD9833 MODULE
   
    Dim F_DELTA  As Byte          ;SWEEP FREQUENCY STEP
   
    Dim F_LOW    As Dword         ;SWEEP FREQUENCY LOW
    Dim F_HIGH   As Dword         ;SWEEP FREQUENCY HIGH
    Dim F_TEMP   As Dword         ;SWEEP FREQUENCY TEMP
    Dim F_RAMP   As Dword
   
    Dim CNTRL    As Word
    Dim pPHASE   As Word
    Dim F_LSB    As Word
    Dim F_MSB    As Word
    Dim pRESET   As Word
   
    F_LOW    = $000029F1          ;F_LOW  = 1KHz
    F_HIGH   = $0000D167          ;F_HIGH = 5KHz
    F_DELTA  = 40                 ;SWEEP FREQUENCY STEP
      
    DelayMS 500                   ;STABILIZATION PERIOD
           
    GoSub SET_UNUSED_PORT_PINS_LOW
   
    FSYNC = 1        
    GoSub DDS_RESET               ;RESET AD9833 MODULE
   
Main:
    F_LOW = $000029F1             ;F_LOW  = 1KHz     
    GoSub SWEEP_UP
    GoSub SWEEP_DOWN
    GoTo Main
    End 

;= = = = = = = = = = = = = = = = = = = = = = = = =
; SWEEP AD9833 OUTPUT FREQUENCY FROM 1KHz to 2KHz
;= = = = = = = = = = = = = = = = = = = = = = = = =

SWEEP_UP:
    Repeat
      GoSub LOAD_FREQ_REG0
      GoSub DDS_FREQ_REG0
      F_RAMP = F_RAMP + F_DELTA
      DelayUS 10
     
      GoSub LOAD_FREQ_REG1
      GoSub DDS_FREQ_REG1
      F_RAMP = F_RAMP + F_DELTA
      DelayMS 10  
    Until F_RAMP >= F_HIGH
    Return

SWEEP_DOWN:
    Repeat
      GoSub LOAD_FREQ_REG0
      GoSub DDS_FREQ_REG0
      F_RAMP = F_RAMP - F_DELTA
      DelayUS 10
     
      GoSub LOAD_FREQ_REG1
      GoSub DDS_FREQ_REG1
      DelayMS 10
      F_RAMP = F_RAMP - F_DELTA
    Until F_RAMP <= F_LOW
    Return

LOAD_FREQ_REG0:
    F_TEMP = F_RAMP
    F_LSB  = F_TEMP.LowWord
    F_LSB  = F_LSB << 2
    F_LSB  = F_LSB >> 2
    F_LSB  = F_LSB + $4000
    F_TEMP = F_TEMP << 2
    F_MSB  = F_TEMP.HighWord
    F_MSB  = F_MSB << 2
    F_MSB  = F_MSB >> 2
    F_MSB  = F_MSB + $4000    
    Return

LOAD_FREQ_REG1:
    F_TEMP = F_RAMP
    F_LSB  = F_TEMP.LowWord
    F_LSB  = F_LSB << 2
    F_LSB  = F_LSB >> 2
    F_LSB  = F_LSB + $8000
    F_TEMP = F_TEMP << 2   
    F_MSB  = F_TEMP.HighWord
    F_MSB  = F_MSB << 2
    F_MSB  = F_MSB >> 2
    F_MSB  = F_MSB + $8000
    Return

DDS_FREQ_REG0:
    CNTRL   = $2000               ;SELECT FREQUENCY REG0
    F_LSB   = F_LSB               ;LOAD LSB FREQ REGISTER
    F_MSB   = F_MSB               ;LOAD MSB FREQ REGISTER   
    pPHASE  = $C000               ;LOAD PHASE REGISTER 0
    pRESET  = $2000               ;EXIT RESET   
    GoSub DDS_OUT
    Return

DDS_FREQ_REG1:
    CNTRL   = $2800               ;SELECT FREQUENCY REG1
    F_LSB   = F_LSB               ;LOAD LSB FREQ REGISTER
    F_MSB   = F_MSB               ;LOAD MSB FREQ REGISTER
    pPHASE  = $C000               ;LOAD PHASE REGISTER 0
    pRESET  = $2800               ;EXIT RESET
    GoSub DDS_OUT
    Return

DDS_OUT:
    FSYNC = 0                     ;DATA TRANSFER STARTS WHEN FSYNC LOW
    DelayUS 10                  
    SHOut DAT, CLK, 5, [CNTRL\16] : DelayUS 10
    SHOut DAT, CLK, 5, [F_LSB\16] : DelayUS 10
    SHOut DAT, CLK, 5, [F_MSB\16] : DelayUS 10
    SHOut DAT, CLK, 5, [pPHASE\16]: DelayUS 10
    SHOut DAT, CLK, 5, [pRESET\16]: DelayUS 10
    FSYNC = 1
    Return

DDS_RESET:
    FSYNC = 0                     ;DATA TRANSFER STARTS WHEN FSYNC LOW
    DelayUS 10
    CNTRL = $0100                 ;
    SHOut DAT, CLK, 5, [CNTRL\16] ;RESET when CNTRL = $0100
    FSYNC = 1   
    Return
   
SET_UNUSED_PORT_PINS_LOW:
    PORTA.0 = 0                   ;Set Low
    PORTA.1 = 0                   ;Set Low
    PORTA.2 = 0                   ;Set Low
    PORTA.4 = 0                   ;Set Low
    PORTA.5 = 0                   ;Set Low
    PORTC   = 0                   ;Set Low
    Return

;= = = = = = = = = = = = = = = = = = = = = = = = = =
; AD9833 contains two 32-bit Frequency Registers, i.e.
; Frequency Register 0 and Frequency Register 1. Two
; 16-bit writes are required to update each register
; and bits DB15 and DB14 determine the active register,
; If DB15 & DB14 = '01' Frequency Register 0 is active.
; If DB15 & DB14 = '10' Frequency Register 1 is active.
; Refer to Application Note AN-1070 for further information.
;
;= = = = = = = = = = = = = = = = = = = = = = = = = =