打印

DDS输出频率在特定点错误

[复制链接]
486|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
iamafighter|  楼主 | 2016-9-25 11:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
目前在做一个基于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;
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

14

帖子

0

粉丝