目前在做一个基于51单片机和CPLD的DDS信号源。单片机是STC的51,CPLD是EPM240。
基本结构是单片机负责按键输入和显示参数,CPLD负责DDS合成波形输出,最高频率2MHz
按键输入频率值,由单片机计算出频率字通过SPI发送给CPLD。
现在碰到的问题是,当设置输出频率的万位数为“7/8/9”时,输出频率就不对,其他情况都对。
比如频率值为X6-X5-X4-X3-X2-X1-X0,仅当X4取值为“7/8/9”时就出错,60000或1969999时没问题,
但是70000就输出4464,17000输出104464,117000输出1104464,也就是说除了X4之外高位变化
都是正确的。更奇葩的是80000时输出14464,90000输出24464,都是按照10000递增,好像也没错。
也考虑过是不是在转换频率字的过程中,数据类型出错的原因,如果给CPLD发送整数而不是存储计算值的
变量,输出也是对的。最后附上关键代码,请高手指正!
/////////////////////////////////////////////////////////////
#define FREQCONS (4294967296.0/50000000.0) //频率字计算常数,DDS累加器位宽32位,系统时钟50MHz
unsigned long BinFreq, TxsFreq; //频率值二进数和转换后的数
unsigned char NumFreq[7] //用于显示的频率值BCD码数组
BinFreq = NumFreq[6]*1000000 + NumFreq[5]*100000 + NumFreq[4]*10000 + NumFreq[3]*1000 + NumFreq[2]*100 + NumFreq[1]*10 + NumFreq[0];
TxsFreq = (((float)(BinFreq))*FREQCONS);
SendCpld(TxsFreq); //发送频率字给CPLD,万位为7/8/9出错
//SendCpld(6012954); //直接发送计算好的常数,则输出正确,这里为输出70000的频率字
Fout = 2^32/50M * 70K = 6012954
///////////////////////////////////////////////////////////
void SendCpld(unsigned long parm2)
{
unsigned long DataBuf2;
unsigned char i=0; //循环变量
/* 初始化接口 */
F_nLK = 1;
F_nCS = 1;
F_SCK = 1;
F_SDA = 1;
DataBuf2 = parm2;
/* ---------------------------------------------------- */
F_nCS = 0; //传输开始
for (i=0; i<32; i++) //每组32位频率字
{
if (DataBuf2 & 0x80000000) //判断当前位状态
F_SDA = 1;
else
F_SDA = 0;
F_SCK = 0; //产生串行时钟
F_SCK = 1;
F_SCK = 0;
DataBuf2 <<= 1; //左移一位,传送下一位
}
F_nCS = 1; //传输结束
/* ---------------------------------------------------- */
F_nLK = 0; //产生锁存信号
F_nLK = 1;
}
|