Do you have a C debugger in order to watch the variables contents ?
1. Do you need to cast "INPUT*53.687091" ? Try to direct assign 53 to TUNINGWORD before calling send40bit function and notes the Fout value.
2. Are you sure after shifting TUNINGWORD "x" times to right, the temp variable (unsigned char) hold b7-b0 of 32bits TUNINGWORD ?
3. Are you sure after "data=temp" the RC0 (it's only a bit) will get the LSBit of "temp" (unsigned char) ? How the C compiler handles these assignments ? Have you ever killed your curiosity about how the compiled code looks in assembler ?
This is a stupid sequence or a bad C skill programmer (and as a result a waste of memory code ) if I'm doing this way ?
Definitely shifting 4 concatenated registers (TUNINGWORD>>31) will be waste of execution times rather than memory code.
Code:
for (i = 0; i < 32; i++)
{
if ((TUNINGWORD & 1) == 1)
data=1; //the most stupid embedded C assignment
else
data=0;
tuning_word = tuning_word >> 1;
w_clk=1; w_clk=0; //these are stupid as well, you can write in assembler as well
}
If you're not sure how C compiler handles the code (and never complains about them) let's write in HighLevelLanguage style.
I mean "if"......"else"...... rather than skip next instruction if bit is set or reset (assembler style).
You wrote that for input 1 you got 128 Hz and for input 10 -> output 1,28KHz.
It's quite linear, isn't ?. Hence a straight look at the bit streams delivered to AD9850 will clear your confussion :
it's a bug in code or AD9850 don't behaves as expected ?
For input 1 the bit stream should look like 0000000000110101 or 53 decimal for 0,987Hz output frequency, but you got 128Hz output.
If the bit stream looks like 0001101011010111 or 6871 decimal (for input 1), then you have a software bug.
Just play a little and can solve the problem yourself.