1) Why not use Atmel for new designs?
I have used Atmels (90S8515,90S2313) in the last millennium. But i dont like the way how they handle their data spaces :-).
If a project make use of them, i have no problems with them.
Most of my projects include some form of signal processing and require features like arithmetic saturation,
extended address capabilities and so on. For this i used in early days the Motorola 56002 and later
Texas Instruments C5000 and C2000 series.
On the lower end i would use the PIC16F15xx which have really neat peripherals like
a NCO (Numerical Controlled Oscillator) or CLC's (Configurable Logic Cell).
For this project i used the MSP430 because of its 16 bit capabilities, the possibility to drive a passive 14 segment LCD,
integrated ADC's, DAC's and OPV's (MSP430FG4618).
2) Maybe I've made it to complicated. I've done that once or twice before.
I think I am arriving at the same place. I was going to use an encoder of some type to generate a interrupt. If the interrupt then sees another pin HI, we will increment. Pin LO is a decrement. I can start from a pre-loaded state when I turn the VFO on or from the last frequency remembered when I turned it off.
I'll probably increment by your F100 unless I select (push button) otherwise. So each step of the encoder will generate an interrupt that increments or decrements F100 hz.
So, let's say I'm at 10 mhz (F10M) as my starting position. I bump my knob to increment 100 hz (F100).
LAST_FREQ + F100 --> TEMP_DDS_REGISTER-->shift out the SPI to the DDS
DISP_FREQ + 100hz --> convert to ascii --> parallel out to display
If this is correct, that would be a lot simpler than what I had originally done. I originally had programmed in assembler with a Freescale micro just to jump between a number of preselected channels at a predetermined time. Then I wanted to build a really, really fast zero-crossing switch so I would "jump" when the input to the mixer crossed zero. My VFO in assembler was becoming very difficult very quickly.
I purchased two "crystal-plexed" 11 meter radios to use as a development system. I was able to fire them up on 10M with just some "tweaking." I had a couple contacts just to make sure everything worked and all was stable. So my simple project has become about 5 projects all based on the DDS VFO.
So, what do you think? Anyone else have any comments?
My design is around two registers.
There is one for the actual frequency and a register for the increment. Both registers can hold 16 digits.
Only the 8 most significant digits are used for the calculation.
The other 8 spaces hold only digits, so they do not get lost if a register is shifted right.
(Which would divide the frequency by ten.)
The register hold their values as a representation of their digit value: '0' becomes 0 and '9' becomes 9.
The frequency 31.415926 MHz would look like:
R10M R1M R100k R10k R1k R100 R10 R1 O1 O2 O3 O4 O5 O6 O7 O8
3 1 4 1 5 9 2 6 0 0 0 0 0 0 0 0
To calculate the DDS controlword You have to multiply each value with the appropriate constant and take the sum of all products.
controlword = sum(R10M * F10M + R1M * F1M + R100k * F100k + R10k * F10k + R1k * F1k + R100 * F100 + R10 * F10 + R1 * F1)
Since the coefficients are small, in the range from 0 to 9, there is no really penalty if you do a simple repeated add of the constants.
So the controlword becomes:
F10M DL 0147ae148h
F1M DL 020c49bah
F100k DL 0346dc5h
F10k DL 053e2dh
F1k DL 08638h
F100 DL 0d6ch
F10 DL 0158h
F1 DL 022h
(0147ae148h+0147ae148h+0147ae148h) + (020c49bah) + (0346dc5h+0346dc5h+0346dc5h+0346dc5h) + (053e2dh) + \
(08638h+08638h+08638h+08638h+08638h) + (0d6ch+0d6ch+0d6ch+0d6ch+0d6ch+0d6ch+0d6ch+0d6ch+0d6ch) + \
(0158h+0158h) + (022h+022h+022h+022h+022h+022h)
gives: 4056fe33h (without warranty :-)
Since i want arbitrary step values, and not only a step by digits there is second register which holds this increment.
To do a step up the increment register has to be added to the frequency register.
For a simple VCO in a receiver this might not be necessary and simpler approach, as You described may be used.
All operation is done on the frequency register and the controlword is always calculated from this register.
To display the frequency, You can simply add 030h (aka '0') to each digit to get its ASCII representation.
Direct manipulation of the control word would be useful for FM-modulation or logarithmic sweeps.
The bad news about all this are rounding errors. You can get rid of them, if You extend the constants by
two hexadecimal digits and do 8 bit right shift on the control word before You write it to the DDS.
Thats up to You... :-)
For fast switching between arbitrary values You should consider the AD9856 and its family members.
They can hold 4 controlwords for their DDS and switch between them.
No math (but hardware) involved :-)