论坛风格切换切换到宽版
  • 5640阅读
  • 11回复

AD9851 控制程序  帮忙看看哪里不对 [复制链接]

上一主题 下一主题
离线bg9elj
 
发帖
20
只看楼主 倒序阅读 0楼 发表于: 2013-09-06

#include<msp430g2553.h>
#define ad9851_w_clk P2DIR|=BIT2          //WLK  P2.2
#define ad9851_w_clk_h P2OUT|=BIT2
#define ad9851_w_clk_l P2OUT&=~BIT2
#define ad9851_fq_up P2DIR|=BIT1          //FU  P2.1
#define ad9851_fq_up_h P2OUT|=BIT1
#define ad9851_fq_up_l P2OUT&=~BIT1
#define ad9851_rest P2DIR|=BIT0             //RST  P2.0
#define ad9851_rest_h P2OUT|=BIT0
#define ad9851_rest_l P2OUT&=~BIT0
#define ad9851_bit_data P1DIR|=BIT7         //DAT  P1.7
#define ad9851_bit_data_h P1OUT|=BIT7
#define ad9851_bit_data_l P1OUT&=~BIT7

void daley(int t){
    int bc,i;
    for(i=0;i<t;i++)
      for(bc=15;bc>0;bc--);
}

void ad9851_reset()
  {
    ad9851_w_clk;
    ad9851_w_clk_l;
    daley(5);
    ad9851_w_clk_h;
    daley(5);
    ad9851_w_clk_l;
    ad9851_fq_up;
    ad9851_fq_up_l;
    daley(5);
    ad9851_fq_up_h;
    daley(5);
    ad9851_fq_up_l;
    //ad9851_w_clk;
    ad9851_w_clk_h;
    daley(5);
    ad9851_w_clk_l;
    daley(5);
    ad9851_fq_up_h;
    daley(5);
    ad9851_fq_up_l;
}

void ddsfreq(unsigned long freqdata)//发送频率控制字
{
  unsigned char i;
  unsigned long updata;
  unsigned long p=0x00000001;
  updata=freqdata;
  for(i=0;i<32;i++)
  {
    if(updata&p) ad9851_bit_data_h;
    else ad9851_bit_data_l;
    ad9851_w_clk_l;
    daley(5);
    ad9851_w_clk_h;
    updata=updata>>1;
  }
}
void ctrlword(unsigned char phctl)//控制字发送
{
  unsigned char word;
  unsigned char i;
  //unsigned char p=0x01;
  //if(sleep==0)word=0x01;//正常输出
  //if(sleep==1)word=0x05;//关闭模式
  word=phctl;
  for(i=0;i<8;i++)
  {
    if(word&0x01) ad9851_bit_data_h;
    else ad9851_bit_data_l;
    ad9851_w_clk_l;
    daley(5);
    ad9851_w_clk_h;
    word=word>>1;
  }
  //ad9851_fq_up;
  ad9851_fq_up_h;
  ad9851_fq_up_l;
}

void ad9851_wr_Serial(volatile unsigned char w0,volatile double frequence)
    {
            unsigned char i,w;
            long int y;
            double x;
            //计算频率的HEX值
            x=4294967295/179998;//适合180M晶振/180为最终时钟频率(或30M六倍频)
            //如果时钟频率不为180MHZ,修改该处的频率值,单位MHz  !!!
            frequence=frequence/1000;
            frequence=frequence*x;
            y=frequence;
            ad9851_bit_data;
            //ad9851_w_clk;
            //ad9851_fq_up_l;
            //写w4数据
            w=(y>>=0);
            for(i=8;i>0;i--)
            {
                if((w>>i)&0x01)
                        ad9851_bit_data_h;
                else
                        ad9851_bit_data_l;
                ad9851_w_clk_l;
                daley(5);
                ad9851_w_clk_h;
                daley(5);
            }
            //写w3数据
            w=(y>>8);
            for(i=8;i>0;i--)
            {
                if((w>>i)&0x01)
                        ad9851_bit_data_h;
                else
                        ad9851_bit_data_l;
                ad9851_w_clk_l;
                daley(5);
                ad9851_w_clk_h;
                daley(5);
            }
            //写w2数据
            w=(y>>16);
            for(i=8;i>0;i--)
            {
              if((w>>i)&0x01)
                      ad9851_bit_data_h;
              else
                      ad9851_bit_data_l;
              ad9851_w_clk_l;
              daley(5);
              ad9851_w_clk_h;
              daley(5);
            }
            //写w1数据
            w=(y>>24);
            for(i=8;i>0;i--)
            {
              if((w>>i)&0x01)
                      ad9851_bit_data_h;
              else
                      ad9851_bit_data_l;
              ad9851_w_clk_l;
              daley(5);
              ad9851_w_clk_h;
              daley(5);
            }
            //写w0数据
            w=w0;
            for(i=8;i>0;i--)
            {
              if((w>>i)&0x01)
                      ad9851_bit_data_h;
              else
                      ad9851_bit_data_l;
              ad9851_w_clk_l;
              daley(5);
              ad9851_w_clk_h;
              daley(5);
            }
            //移入始能
            ad9851_w_clk_l;
            ad9851_fq_up;
            ad9851_fq_up_h;
            ad9851_fq_up_l;
}

/*
void Dad9851_wr(volatile double frequence)
    {
            unsigned char i,w;
            long int y;
            double x;
            //计算频率的HEX值
            x=4294967295/179998;//适合180M晶振/180为最终时钟频率(或30M六倍频)
            //如果时钟频率不为180MHZ,修改该处的频率值,单位MHz  !!!
            frequence=frequence/1000;
            frequence=frequence*x;
            y=frequence;
            ad9851_bit_data;
            //ad9851_w_clk;
            //ad9851_fq_up_l;
            //写w4数据
            w=(y>>=0);
            for(i=8;i>0;i--)
            {
                if((w>>i)&0x01)
                  ad9851_bit_data_h;
                else
                  ad9851_bit_data_l;
                ad9851_w_clk_l;
                daley(5);
                ad9851_w_clk_h;
                daley(5);
            }
            //写w3数据
            w=(y>>8);
            for(i=8;i>0;i--)
            {
                if((w>>i)&0x01)
                        ad9851_bit_data_h;
                else
                        ad9851_bit_data_l;
                ad9851_w_clk_l;
                daley(5);
                ad9851_w_clk_h;
                daley(5);
            }
            //写w2数据
            w=(y>>16);
            for(i=8;i>0;i--)
            {
              if((w>>i)&0x01)
                      ad9851_bit_data_h;
              else
                      ad9851_bit_data_l;
              ad9851_w_clk_l;
              daley(5);
              ad9851_w_clk_h;
              daley(5);
            }
            //写w1数据
            w=(y>>24);
            for(i=8;i>0;i--)
            {
              if((w>>i)&0x01)
                      ad9851_bit_data_h;
              else
                      ad9851_bit_data_l;
              ad9851_w_clk_l;
              daley(5);
              ad9851_w_clk_h;
              daley(5);
            }
            //写w0数据
            w=w0;
            for(i=8;i>0;i--)
            {
              if((w>>i)&0x01)
                      ad9851_bit_data_h;
              else
                      ad9851_bit_data_l;
              ad9851_w_clk_l;
              daley(5);
              ad9851_w_clk_h;
              daley(5);
            }
            //移入始能
            ad9851_w_clk_l;
            ad9851_fq_up;
            ad9851_fq_up_h;
            ad9851_fq_up_l;
    }

*/
void W0_wr(int W0){
  int i;
  ad9851_fq_up_l;
    for(i=8;i>0;i--)
    {
      if((W0>>i)&0x01)
              ad9851_bit_data_h;
      else
              ad9851_bit_data_l;
      ad9851_w_clk_l;
      daley(5);
      ad9851_w_clk_h;
      daley(5);
    }
    //移入始能
    ad9851_w_clk_l;
    ad9851_fq_up;
    ad9851_fq_up_h;
    ad9851_fq_up_l;
}

void main(void)
  {
    unsigned long fq,xh;
    P1SEL |= BIT3;
    WDTCTL=WDTPW+WDTHOLD;
    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ;//上面两句将内部DCO校准至1MHz
    P1DIR |=BIT6;
    P1OUT |=BIT6;
    P2DIR |=BIT2;
    for(xh=1000;xh>0;xh--);
    P1OUT &=~BIT6;
    //for(xh=100000;xh>0;xh--);
    //P1OUT |=BIT6;
/*        while(1){
                    P2OUT ^= BIT2;
                    for(xh=1;xh>0;xh--);
    }*/
    ad9851_reset();
    //W0_wr(0x03);
    ddsfreq(2000);
    ctrlword(1);
    while(1);
    fq=10000;
    while(1){
    //if(P1IN & 0x08==0) {
      //ad9851_wr_Serial(0x01,0);
      ddsfreq(fq);
      ctrlword(1);
      for(xh=5000;xh>0;xh--);
      fq+=1000;
      if(fq>1000000) fq=30000;
    //}
    }
  }
离线bg9elj
发帖
20
只看该作者 1楼 发表于: 2013-09-06
我逐渐增大输出频率,结果频率一会增大、一会减小  我就频率每秒自增一定值,结果输出大大小小的变化  但是有时下一秒增大,有时下一秒减小
离线徐徐2009
发帖
6540
只看该作者 2楼 发表于: 2013-09-06
现在芯片假货盛行 9851什么来头?
QQ616710081  旺旺:电源学习网  
ATS20 ATS25 ATS100 收音机
高频假负载
7.023MHZ 晶振    7.050MHZ 晶振
 DIY 6波段电台
25欧功率合成馈线
手动 自动  50w 短波功放  FT-817功放
FM VHF 1.5W 100W  200W 功放套件 1-2KW短波功放变压器
离线yyh
发帖
1398
只看该作者 3楼 发表于: 2013-09-06
很久没玩了,可搜索我的帖子
BG8BAL
离线梭鱼
发帖
589
只看该作者 4楼 发表于: 2013-09-06
你的9851控制程序怎么这么长,真看不下去!!!按你说的现象看,肯定是程序写错了,网上搜个简单点的抄一下用吧。
假的9851、9850 片子市面上不少,主要表现在不能按最高时钟工作,假的9851 最高只能工作到150MHz,9850则只能到100MHz。高过这个频率则会在某些频点上输出不正常。
淘宝店址:https://shop70232146.taobao.com
NMRF微波工作室
雷击保护器,限幅器,检波器,天线放大器(LNA),滤波器
手机: 139-0451-3971
Email:stanana@sina.com
离线BI7LNQ
发帖
599
只看该作者 5楼 发表于: 2013-09-06
我的9850程序。lz调试的时候可以先关闭6倍频。把9851当50用。程序里两种计算方法,一种用了64bit数,一种用浮点,都是尽量为了获取更精确的频率配置字。我的小板子直接用了125M晶振,所以计算的时候你要根据自己需要修改,你如果要用6倍频改成180M常量就是了。
main.c

int main(void)
{
    RCC_Configuration();

    ad9850_init();

    delayus(1000);
    ad9850_wr_serial(0,15000000.0);
    while (1);
}


ad9850.c





/************************/
/* platform   dependent */
/************************/

#include "stm32f10x.h"
#include "platform_config.h"
#include "core_cm3.h"
#include "bitband.h"

void delayus(__IO uint32_t nTime);

#define FQUP GPIO_Pin_14
#define SCLK GPIO_Pin_13
#define SDAT GPIO_Pin_12
#define DATA_PORT GPIOB

#define ad9850_bit_data PB12
#define ad9850_w_clk PB13
#define ad9850_fq_up PB14



void ad9850_gpio_init()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = SCLK;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(DATA_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = SDAT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(DATA_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = FQUP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(DATA_PORT, &GPIO_InitStructure);
}




/************************/
/* platform independent */
/************************/
void ad9850_serial_init()
{
    ad9850_w_clk = 0;
    delayus(1);
    ad9850_w_clk = 1;
    delayus(1);
    ad9850_w_clk = 0;

    delayus(100);
    ad9850_fq_up=0;
    delayus(10);
    ad9850_fq_up=1;
    delayus(10);
    ad9850_fq_up=0;
}

void ad9850_init()
{
    ad9850_gpio_init();
    ad9850_serial_init();
}


#if 1 /* uint64 or double float */
const uint64_t deltaphase = 0xffffffff00000000 / 125000000;
void ad9850_wr_serial(unsigned char w, uint32_t frequence)
{
    uint32_t i;
    uint32_t M;
    uint64_t delta = deltaphase * frequence;
    M = delta >> 32;        //频率控制字
    ad9850_w_clk = 0;       //初始化
    ad9850_fq_up = 0;

    //写频率控制字
    for(i=0;i<32;i++)
    {
        ad9850_w_clk = 0;
        ad9850_bit_data = ((M>>i)&1);
        ad9850_w_clk = 1;         //上升沿写入数据
    }
    //写相位控制字
    for(i=0;i<8;i++)
    {
        ad9850_w_clk = 0;
        ad9850_bit_data = (w>>i)&1;
        ad9850_w_clk = 1;         //上升沿写入数据
    }
    //移入始能
    ad9850_fq_up = 0;
    ad9850_fq_up = 1;         //上升沿将40位数一次性打入数据寄存器
    ad9850_fq_up = 0;
}

#else
const double deltaphase = 4294967295.0 / 125000000.0;
void ad9850_wr_serial(unsigned char w, double frequence)
{
    unsigned char i;
    unsigned long int M;
    //计算频率值
    frequence = frequence * deltaphase;
    M = frequence;        //频率控制字
    ad9850_w_clk = 0;       //初始化
    ad9850_fq_up = 0;

    //写频率控制字
    for(i=0;i<32;i++)
    {
        ad9850_w_clk = 0;
        ad9850_bit_data = ((M>>i)&1);
        ad9850_w_clk = 1;         //上升沿写入数据
    }
    //写相位控制字
    for(i=0;i<8;i++)
    {
        ad9850_w_clk = 0;
        ad9850_bit_data = (w>>i)&1;
        ad9850_w_clk = 1;         //上升沿写入数据
    }
    //移入始能
    ad9850_fq_up = 0;
    ad9850_fq_up = 1;         //上升沿将40位数一次性打入数据寄存器
    ad9850_fq_up = 0;
}
#endif
离线bg3gtw
发帖
546
只看该作者 6楼 发表于: 2013-09-07
一直想用STC89C52RC单片机最小系统驱动9851DIY个信号源,就在程序上卡住了
地址:内蒙古正蓝旗邮政局1011信箱      027200
QQ:356292386
邮箱:lqsyg2004@126.com
设备:FT-991A   K4GP    9楼顶
离线bg3gtw
发帖
546
只看该作者 7楼 发表于: 2013-09-07
在这请各位帮忙,搞下程序多谢了
地址:内蒙古正蓝旗邮政局1011信箱      027200
QQ:356292386
邮箱:lqsyg2004@126.com
设备:FT-991A   K4GP    9楼顶
离线梭鱼
发帖
589
只看该作者 8楼 发表于: 2013-09-07
都已经有输出了、还愁啥!!用几个规则的控制字、看对应的输出频率、找出两者间的规律就知道程序错在哪了!!!先忽略相位和上电控制字、或者干脆先当成9850使。另外你用什么监测输出频率??输出的滤波器做得对不对?这些都是问题。有频普分析仪没??
淘宝店址:https://shop70232146.taobao.com
NMRF微波工作室
雷击保护器,限幅器,检波器,天线放大器(LNA),滤波器
手机: 139-0451-3971
Email:stanana@sina.com
离线BG4RFF
发帖
1581
只看该作者 9楼 发表于: 2013-09-07
除了频率的32位,还有其一个字节,看一下datasheet就知道了
BG4RFF
江苏如东、四川泸县
BG4RFF#163.com
QQ:4俩8拐拐勾4勾
手机:妖怪怪儿,五个妖狗动钩钩(防止恶意电话,先短信联系)
离线BG4RFF
发帖
1581
只看该作者 10楼 发表于: 2013-09-07
   //写相位控制字
    for(i=0;i<8;i++)
    {
        ad9850_w_clk = 0;
        ad9850_bit_data = (w>>i)&1;
        ad9850_w_clk = 1;         //上升沿写入数据
    }
就是这段你没有,我以前也是这样的
BG4RFF
江苏如东、四川泸县
BG4RFF#163.com
QQ:4俩8拐拐勾4勾
手机:妖怪怪儿,五个妖狗动钩钩(防止恶意电话,先短信联系)
离线BI7LNQ
发帖
599
只看该作者 11楼 发表于: 2013-09-07
回 BG4RFF 的帖子
BG4RFF:   //写相位控制字
    for(i=0;i<8;i++)
    {
        ad9850_w_clk = 0;
        ad9850_bit_data = (w>>i)&1;
... .. (2013-09-07 21:38) 

lz代码里其实有,就是那个ctrlword函数。关键是lz ddsfreq函数没有把频率换算为配置字。ad9851_wr_Serial换算了,但是main函数却又不是用这个来配置