If anyone has experience of the AD9833 or AD9837 DDS chip then I should be grateful for a little help. In principal, this chip can provide sine, square wave, and sawtooth signals at any frequency below 12.5MHz, and is simple to control from a microcontroller.
But I am having problems and am running out of things to try. The attached program should display each waveform, at 400Hz, for five seconds, in rotation. In practice, it does display a square wave but it and the sine is at the wrong frequency and the sawtooth never appears.
The coding is based on the specific instructions in AN-1070 from Analogue Devices, the manufacturer. The example I am using is on a module from China, the actual chip being about 2mm square and has 10 leads, way beyond my assembly skills.
There are many products based on this chip so it should be simple to use. The sertxd output confirms that the bit stream sent to it conforms to AN-1070 but the results obviously don't.
I imagine that the problem is a simple oversight on my part but I have spent too much time on this and now seek input from this amazing forum.
Areas of uncertainty remain:
- is it really hspi mode11? Is that mode2?
- do I have the right bit patterns for the control words?
For debugging in the simulator, the program logs the commands to serttxd so they can be analysed and they seem fine to me.
Help gratefully received! Particularly, working Picaxe code!
But I am having problems and am running out of things to try. The attached program should display each waveform, at 400Hz, for five seconds, in rotation. In practice, it does display a square wave but it and the sine is at the wrong frequency and the sawtooth never appears.
The coding is based on the specific instructions in AN-1070 from Analogue Devices, the manufacturer. The example I am using is on a module from China, the actual chip being about 2mm square and has 10 leads, way beyond my assembly skills.
There are many products based on this chip so it should be simple to use. The sertxd output confirms that the bit stream sent to it conforms to AN-1070 but the results obviously don't.
I imagine that the problem is a simple oversight on my part but I have spent too much time on this and now seek input from this amazing forum.
Areas of uncertainty remain:
- is it really hspi mode11? Is that mode2?
- do I have the right bit patterns for the control words?
For debugging in the simulator, the program logs the commands to serttxd so they can be analysed and they seem fine to me.
Help gratefully received! Particularly, working Picaxe code!
Code:
#picaxe 28X2
#no_data
setfreq em64
#terminal 76800
symbol HO_AD9833_fsync = B.1
symbol B_AD9833_MSB = b1
symbol B_AD9833_LSB = b0
symbol B_mask = b4
symbol C_freq_mult = 8 'default 8MHz, actual 64MHz
symbol C_2S = C_freq_mult * 2000
symbol C_5S = C_freq_mult * 5000
do
call start_sine
pause C_5S
call start_square
pause C_5S
call start_saw
pause C_5S
loop
end
'=================================================================
' Should cycle through sine, square and sawtooth waveforms all at
' 400Hz (with 25MHz xtal), whilst logging transfers to serial terminal
'==================================================================
writeregister: 'sends a little-endian 16 bit register to the AD9833
'ad9833 data states:
' clock must be high when fsync goes low - implies idle high
' sample taken on falling edge. Thus CPOL=1, CPHA=0
'this is wikipedia mode2, hspi mode 11 (I think)
hspisetup spimode11, spifast 'setup each time in case changed
low HO_AD9833_fsync 'fsync/cs low before writing
pauseus 10 'let it get ready
sertxd(#bit15,#bit14,#bit13,#bit12," ",#bit11,#bit10,#bit9,#bit8,_
" ",#bit7,#bit6,#bit5,#bit4," ",#bit3,#bit2,#bit1,#bit0,cr,lf)
hspiout (B_AD9833_LSB, B_AD9833_MSB) 'write 16 bits LSB first
high HO_AD9833_fsync 'deselect chip as all done
return
'==================================================================
start_saw:
sertxd("starting saw",cr,lf)
'set control register
sertxd("control: ")
B_AD9833_MSB = %00100001
B_AD9833_LSB = %00100010
call writeregister
'set freq and phase
call set_freq_both
call set_zero_phase_both
'unreset
sertxd("control: ")
B_AD9833_MSB = %00100000
B_AD9833_LSB = %00100010
call writeregister 'exit reset
sertxd("done saw",cr,lf)
return
'==================================================================
start_square:
sertxd("starting square",cr,lf)
'set control register
sertxd("control: ")
B_AD9833_MSB = %00101001
B_AD9833_LSB = %00101000
call writeregister
'set freq and phase
call set_freq_both
call set_zero_phase_both
'unreset
sertxd("control: ")
B_AD9833_MSB = %00101000
B_AD9833_LSB = %00101000
call writeregister 'exit reset
sertxd("done square",cr,lf)
return
'==================================================================
start_sine:
sertxd("starting sine",cr,lf)
'set control register
sertxd("control: ")
B_AD9833_MSB = %00100001
B_AD9833_LSB = %00000000
call writeregister
'set freq and phase
call set_freq_both
call set_zero_phase_both
'unreset
sertxd("control: ")
B_AD9833_MSB = %00100000
B_AD9833_LSB = %00000000
call writeregister 'exit reset
sertxd("done sine",cr,lf)
return
'==========================================================
set_zero_phase_both:
sertxd("phase0 : ")
B_AD9833_MSB = %11000000
B_AD9833_LSB = %00000000
call writeregister 'set phase register
sertxd("phase1 : ")
B_AD9833_MSB = %11100000
B_AD9833_LSB = %00000000
call writeregister 'set phase register
return
'==========================================================
set_freq_both: 'to 25kHz if clock is 25MHz
'set freq0 LSW
sertxd("freq0 : ")
B_AD9833_MSB = %01010000
B_AD9833_LSB = %11000111
call writeregister 'set frequency register 0 LSBs
'set freq0 MSW
sertxd("freq0 : ")
B_AD9833_MSB = %01000000
B_AD9833_LSB = %00000000
call writeregister 'set frequency register 0 MSBs
'set freq1 LSW
sertxd("freq1 : ")
B_AD9833_MSB = %10010000
B_AD9833_LSB = %11000111
call writeregister 'set frequency register 1 LSBs
'set freq1 MSW
sertxd("freq1 : ")
B_AD9833_MSB = %10000000
B_AD9833_LSB = %00000000
call writeregister 'set frequency register 1 MSBs
return