Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

AD9850 Dev Board Serial Issue

Status
Not open for further replies.

MrAl

Well-Known Member
Most Helpful Member
Hello,

Recently i had purchased an AD9850 dev board from the net. The device is supposed to be capable of serial or parallel load operation. That means we should be able to load a 40 bit word that sets the frequency (and a few other things) either in a serial fashion or parallel.

Despite all attempts to get the serial mode to work, everything fails. The frequency output appears to have nothing to do with the 40 bit word, and flipping a bit in some codes does nothing to alter the frequency.

In parallel mode, it worked with the first try.

There is nothing particularly complex about the word format or comm protocol for either serial or parallel. Serial (I2C like) programming usually works pretty simple, and it's worked with displays for example quite easily.

Any ideas what might be happening? I can only suspect a partially defective chip at the moment.
 
First: You should have linked to the datasheet. https://download.siliconexpert.com/pdfs/source/qd/adi/34008438159094ad9850_h.pdf
There are two evaluation modules, not one.
It's obsolete.

I think that's easy enough.

The evaluation module is designed to connect to a printer port.
U2 and it's strobe kinda messes up the ability to serial control quite a bit. It's kinda tough to use pins 2,3. and 4 which are data pins to set serial mode when they are connected when U2 is in the way. I would assume 2,3 and 4 are read on power up.
 
Hello there KISS,

Apparently there is more than one dev board. The new ones are much simpler and dont have that funny printer port interface (wow that's funny, a throwback to the 80's ha ha).

The new dev boards just have a pin breakout to female connectors, and a few parts on board like a crystal, a 70MHz low pass filter (multi pole with SMD parts), a pot to adjust the comparator set point, a red LED to indicate power.
In fact, this board looks like a very tiny Arduino Uno board, with the headers on either side of the board except these headers have male not female pins (see photo).

I was thinking maybe others had this issue too and it was already hunted down and resolved. I see lots of examples on the web that claim to work right, so maybe it's just this one chip.
The timing is ultra simple because it's not even RS232. Bring up the data bit, pulse the clock, bring up the next bit, pulse the clock, then when all 40 bits are sent pulse the secondary clock which they call the Update clock, which then updates the internal registers to set the new frequency phase. The only timing spec's are to leave enough time between clocks, but that is a tiny time period relative to the uC ability to output pulses and change bits on output pins (the spec is in less than tens of nanoseconds).
 

Attachments

  • AD9850_Board-2b.jpg
    AD9850_Board-2b.jpg
    12.1 KB · Views: 207
Hello again KISS,

Thanks. The Electro Freaks library is one lib i reviewed after finding that the serial interface software i wrote myself did not work correctly with the chip. After review however, i found that my code was almost the same as theirs and furthermore did all the clocking the same, as per the data sheet also. I also tried adding longer delays even though the data sheet indicates that is not necessary because the specs are all much faster than the Arduino lib for digitalWrite() allows.

There is something left out on that link page however, and that is the three pins that need to be pulled either way in order to enter serial mode. Two pins get pulled high, another gets pulled low. Failure to do that (data sheet) will mean the chip will not enter serial mode. Thus the schematic shown on that page should not work until the jumpers are added.

The only reasonable conclusion is that the chip is not functioning properly. I can guess that maybe it does not actually switch into serial mode but interprets D7 (the data bit for serial mode) as part of an 8 bit parallel word. I could check to see if the codes match that scenario i guess, but it will take some time to work that all out. I have several codes logged for comparison.
The data sheet specifies that in parallel mode the words will be interpreted one by one as expected, but if additional words are pumped in that will mean all the bits are shifted and thus the wrong frequency will result. If the chip is stuck in parallel mode, it will see probably a bunch of 1's followed by a changing D7 (would change with the real bits being sent) but it would take in the whole word instead of just that one bit. That would mess up the code badly, and give the wrong frequency, and only allow several distinct frequencies to be output (this is what happens). Just a guess at this point, but i will check this idea out soon.
It could be interpreting all the unconnected data inputs as zero though too. But this is all guesswork at this point, and if it really does not go into serial mode then that means the chip is partially defective because i took every precaution and checked and rechecked several times to make sure everything met with the data sheet specs.
 
Last edited:
Mr Al

Are you aware that the AD9850 has to be initialised into serial mode?

Data bits W0 (pin4) and W1 (pin 3) should be set to 1, W2 (pin 2) set to 0,
pulse the W-CLK,
pulse the FQ_UD.
The AD9850 is now in serial mode, and you can send the 40bits to it and it will (should!) work.

Page 12 on my version of the datasheet (REV E)

JimB
 
Hi,

Well thank you Jim, but yes, i knew about those pins and mentioned something like that in my previous post. After that the serial input method looks simpler than some others i have seen so this should be a snap. Displays work fine.
Have you worked with one of these chips in the past?
 
I've used 4 or 5 of these, not had that problem.
What has happened on a couple though was on power up I had to do a reset using the reset pin, otherwise nothing happened, they are sposed to reset themselves on power up, but for some reason these didnt or messed up again afterwards.
 
Hey MrAI, I have been wanting to use one of the devices for awhile as I thought it might make a good function Gen. Let us know how it goes, and give a review would be cool. :)
 
Have you worked with one of these chips in the past?
Yes.
I have a simple RF signal source which uses one, and I have an old radio transceiver or two which requires crystals for transmit and receive, I have used a 9850 as a replacement for multiple crystals. Works reasonably well but there can be problems with phase noise when the signal is multiplied up to VHF.
I use PICs to load the 40 databits into the 9850.

JimB
 
I've used 4 or 5 of these, not had that problem.
What has happened on a couple though was on power up I had to do a reset using the reset pin, otherwise nothing happened, they are sposed to reset themselves on power up, but for some reason these didnt or messed up again afterwards.

Hi,

My sequence is as follows:
Power up
Reset
Clock once
Clock the update line once
Load the 40 bit data
Clock the update line once more.

That is what is given on the data sheet and in code i found elsewhere so that's what i used. The data sheet doesnt say that the clock has to be continuous so it should not matter if the bits are sent with different time spacings, unless they didnt mention that on the data sheet.

I'd be interested to hear how you are doing it, the sequence that is.
 
Yes.
I have a simple RF signal source which uses one, and I have an old radio transceiver or two which requires crystals for transmit and receive, I have used a 9850 as a replacement for multiple crystals. Works reasonably well but there can be problems with phase noise when the signal is multiplied up to VHF.
I use PICs to load the 40 databits into the 9850.

JimB

Hi Jim,

Would be interested to hear how your sequence goes too, if you can, thanks.
 
Hey MrAI, I have been wanting to use one of the devices for awhile as I thought it might make a good function Gen. Let us know how it goes, and give a review would be cool. :)

Hi Mike,

Yeah sure, no problem. From what i tested so far, the output is pretty clean on this board. I think that is because they use what must be a 5 pole (or more) elliptic filter on the output. Three inductors and like 7 capacitors, two resistors make up the filter. I can not see any noise at any of the frequencies i tried. I had to stay below 2MHz however because my scope only goes up to 10MHz, and that means if i go too high i wont see the noise anyway. The highest i can test this right now though is 20MHz because that's as high as my frequency counter goes :)
As you probably guessed, i am working with fairly old test equipment except for my meters and some other little test things. Old scope, and my function generator only goes up to 1MHz (sine, triangle, square). That's one reason why i wanted to get this going.
Works really nice in the parallel mode though. The program word (40 bits) sets the frequency precisely from about 0.03Hz (below 1Hz) to about 62.5MHz, in increments of 0.03Hz. That's pretty cool if you ask me. That means you can set it for 10000000Hz or for 10000000.03Hz roughly.

Oh yeah one small detail. If you get one make sure you get one with a 125MHz crystal. If you get something lower it will limit the top end frequency. The top end frequency is half of the crystal frequency, but from what i have read the closer you get near the top end the more harmonics show up. I dont know how bad it is because i cant test that high with my old scope.

Just to restate the problem again, a little differently...
Sending the word 0x00008638 (that's hex):
in parallel the frequency that comes out looks like a perfect sine wave at 1KHz, and that is the correct frequency,
in serial mode the frequency that comes out is something like 1Hz or lower (could not measure it it was so low).
That word should cause the output to go to 1000.0007Hz or something like that, and that would show up on my frequency counter as 1000Hz. In parallel mode it works exactly like that, yet in serial mode it is just bonkers.
Also, if one bit is changed in serial mode such as:
0x00108638
it may have no effect at all on the output frequency, when for that code it should change drastically.
Also strange is this problem is completely repeatable...if i send the same code i get the same bad frequency out, no matter what i do, including send the bits using a different method, and swapping jumper leads.
 
Hi Jim,
Would be interested to hear how your sequence goes too, if you can, thanks.

Here is my AD9850 initialisation routine, the appropriate bits are hard wired to 0v and +5v as discussed before.
Code:
;*****************************************************************************
Initialise_DDS
    bsf    DDS_port, DDS_W_Clk
    bcf    DDS_port, DDS_W_Clk
    bsf    DDS_port, DDS_FQ_UD
    bcf    DDS_port, DDS_FQ_UD    ;set the DDS into serial load mode
    return
;*****************************************************************************


To set the output frequency of the AD9850, The 32 frequency setting bits are in registers DDS_data+0 through to DDS_data+3, DDS_data+4 is set to 0.
DDS_data+0 contains the least significant frequency bits and DDS_data+3 contains the most significant frequency bits.

Code:
;******************************************************************************  
;Update DDS

;Write 40 bits of serial data to the DDS chip

UpdateDDS
        movf    DDS_data+0, W  
        call    send_a_byte
        movf    DDS_data+1, W      
        call    send_a_byte
        movf    DDS_data+2, W  
        call    send_a_byte
        movf    DDS_data+3, W  
        call    send_a_byte
        movf    DDS_data+4, W  
        call    send_a_byte
        bsf    DDS_port, DDS_FQ_UD        ;pulse the FQ_UD line
        bcf    DDS_port, DDS_FQ_UD
        return  
  
send_a_byte                        ;the byte to send should be in the W reg already
        movwf    Scratch
        movlw    8                ;set 8 data bits
        movwf    DDS_temp_1
tx_next
        rrf    Scratch, F
        btfsc    STATUS, C            ;test the bit to send
        bsf    DDS_port, DDS_Data         ;it is a 1
        btfss    STATUS, C            ;test the bit to send
        bcf    DDS_port, DDS_Data        ;it is a 0
        bsf    DDS_port, DDS_W_Clk        ;pulse the W_Clk line
        bcf    DDS_port, DDS_W_Clk
        decfsz    DDS_temp_1, F            ;if count is zero send a stop bit
        goto    tx_next                ;send next bit  
        return

;*******************************************************************************


Oh yeah one small detail. If you get one make sure you get one with a 125MHz crystal. If you get something lower it will limit the top end frequency. The top end frequency is half of the crystal frequency, but from what i have read the closer you get near the top end the more harmonics show up. I dont know how bad it is because i cant test that high with my old scope.
It gets a bit more complicated than that, when you look with a spectrum analyser you will see harmonics of the intended frequency, as you would expect.
But the real pain comes from the aliases, byproducts of the sampling process which is used to generate the fundamental waveform. The aliases do some funny things, some of them go down in frequency as the fundamental goes up in frequency, if you go up far enough they will become the same frequency as the fundamental and then cross over each other.

Note that there are also AD9851 modules available, these are fitted with a 30MHz oscillator, but, the AD9851 has a clock multiplier built-in and when this is enabled, the effective clock frequency is 180MHz, allowing a higher output frequency to be used before the aliases come and get you!

JimB
 
2 bits are off limits (Internal test) per the datasheet. Is the Endianness (Big/Little Endian) right?

Hello again,

That's a very good point. I tried setting bits to determine what might be going on, and then tried swapping the order of the 8 bit groups as well as swapping the whole 40 bit group (left to right and right to left for both tests) and nothing worked.
Furthermore, the code 0x0000008638 (showing the control byte also now) which should have generated 1000Hz, then swapping to: 0x0086390000 caused the SAME frequency output, which was some very low frequency less than 1Hz.
What's more is, even if the bits were swapped by keeping the first and last bytes of the 32 bit frequency control word as zeros, it would still produce some recognizable bytes. For example, the 32 bit code:
0x00863800 would produce the frequency for 0x00388600 if the bytes were swapped, and if the bits were swapped it would produce either the frequency for 0xx00311C00 or 0x001C3100, with the only assumption is that the bits are all sent the same way and in order from either left to right or right to left. None of these frequencies was observed, and it was always extremely far off.
I will look at the other posts here next and see if there is a difference.
 
Here is my AD9850 initialisation routine, the appropriate bits are hard wired to 0v and +5v as discussed before.
Code:
;*****************************************************************************
Initialise_DDS
    bsf    DDS_port, DDS_W_Clk
    bcf    DDS_port, DDS_W_Clk
    bsf    DDS_port, DDS_FQ_UD
    bcf    DDS_port, DDS_FQ_UD    ;set the DDS into serial load mode
    return
;*****************************************************************************


To set the output frequency of the AD9850, The 32 frequency setting bits are in registers DDS_data+0 through to DDS_data+3, DDS_data+4 is set to 0.
DDS_data+0 contains the least significant frequency bits and DDS_data+3 contains the most significant frequency bits.

Code:
;****************************************************************************** 
;Update DDS

;Write 40 bits of serial data to the DDS chip

UpdateDDS
        movf    DDS_data+0, W 
        call    send_a_byte
        movf    DDS_data+1, W     
        call    send_a_byte
        movf    DDS_data+2, W 
        call    send_a_byte
        movf    DDS_data+3, W 
        call    send_a_byte
        movf    DDS_data+4, W 
        call    send_a_byte
        bsf    DDS_port, DDS_FQ_UD        ;pulse the FQ_UD line
        bcf    DDS_port, DDS_FQ_UD
        return 
 
send_a_byte                        ;the byte to send should be in the W reg already
        movwf    Scratch
        movlw    8                ;set 8 data bits
        movwf    DDS_temp_1
tx_next
        rrf    Scratch, F
        btfsc    STATUS, C            ;test the bit to send
        bsf    DDS_port, DDS_Data         ;it is a 1
        btfss    STATUS, C            ;test the bit to send
        bcf    DDS_port, DDS_Data        ;it is a 0
        bsf    DDS_port, DDS_W_Clk        ;pulse the W_Clk line
        bcf    DDS_port, DDS_W_Clk
        decfsz    DDS_temp_1, F            ;if count is zero send a stop bit
        goto    tx_next                ;send next bit 
        return

;*******************************************************************************



It gets a bit more complicated than that, when you look with a spectrum analyser you will see harmonics of the intended frequency, as you would expect.
But the real pain comes from the aliases, byproducts of the sampling process which is used to generate the fundamental waveform. The aliases do some funny things, some of them go down in frequency as the fundamental goes up in frequency, if you go up far enough they will become the same frequency as the fundamental and then cross over each other.

Note that there are also AD9851 modules available, these are fitted with a 30MHz oscillator, but, the AD9851 has a clock multiplier built-in and when this is enabled, the effective clock frequency is 180MHz, allowing a higher output frequency to be used before the aliases come and get you!

JimB

Hello Jim,

Thanks for the detailed code.

I am doing that same sequence, and also i have tried different delays between pin transitions, from 4us to 50us and nothing changed.

Just one question though. In your code near the end where the counter reaches zero, you have a rem statement:
";if count is zero send a stop bit"

yet there appears to be nothing sent out after the last bit. Are you sending something later or is this just a remnant from a different project? The data sheet does not mention anything about a stop bit.

Thanks.
 
Hold it! Right now, think in binary.

You have 40 bits e,g 10.........1011 and I think the lsb is supposed to be first, so you have to clock in 1101.......01
There is a transformation between words, bits, endian that you might not be getting.

https://www.analog.com/media/en/technical-documentation/data-sheets/AD9850.pdf pdf page 12. W32 and W33 must both be zero and NOTE your clocking in the LSB first, I think. i.e. I think W0 is the less weighted bit or lsb.

Between table III PDF:10 and table IV PDF:12, the order is reversed.

I think, you could't be mixing up little and big endian as well as which bit gets clocked in first and combine that with bits that must be zero.
 
yet there appears to be nothing sent out after the last bit. Are you sending something later or is this just a remnant from a different project? The data sheet does not mention anything about a stop bit.

On PDF page 12, it certainly does mention a "start" and "stop" bit.

First you have to select serial mode with fixed voltages on pins 2,3 and 4.

The you enable serial mode with a pulse on FQ_UD
Clock in your 50 bits of data and another pulse on EQ_UD loads those 40 bits.

If you look closely at figure 10, it suggests a reset, but at that point I'm a little confused.
 
Just one question though. In your code near the end where the counter reaches zero, you have a rem statement:
";if count is zero send a stop bit"
yet there appears to be nothing sent out after the last bit. Are you sending something later or is this just a remnant from a different project?

Well spotted MrAl !
That code fragment send_a_byte is something recycled and modified from an earlier project which did indeed have a stop bit as per asynchronous communications.
The lines of code which send the stop bit were removed, but obviously not the comment.
Looks like I wrote the original about 16 years ago. Where does time go when you are enjoying yourself?

JimB
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top