原创 AD9851调试问题及程序

2009-8-19 20:15 5769 8 10 分类: MCU/ 嵌入式

对自己做总结,与大家做交流!


我在做AD9851的过程中,总的说来遇到的问题不多,一切相当顺利,我遇到的问题主要有以下几点。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


1.关于有源晶振,开始的时候,搭硬件电路的时候,晶振的问题是最困扰我的,众多网友对一个问题争执不休,就是有源晶振出来的到底是个什么样的波形,有的网友说是方波,有的说的三角波,有的说是正弦波,根据我实测的结果,3.3V供电时,出来的波形是不规则的正弦波,峰峰值大约是6.8V,我起初对这个峰峰值感到不可思议,后来的实际效果告诉我没什么影响,开始还有就是波形的问题,我曾想过用斯密特触发器把正弦波整成方波,但后来实际效果告诉我,也没必要,根据实际的效果,我在晶振和AD9851中间加了一个50欧姆的电阻,有网友建议最好是加33欧姆的!我觉得这点还是靠示波器说话的好!呵呵


2.这个就是关于程序的问题了,我信奉一句话,凡是程序能解决的问题都不是问题,呵呵,DDS程序中有个问题肯定对刚开始做的人是个很大的困扰,就是如何让需要输出的频率变成控制字呢,起初我翻阅了很多资料,其实最后还是返璞归真了,还是从官方AD9851PDF上看出来的,比如说你要输出1M波形的话,这样计算,系统时钟是120M的话,就用系统时钟120M除以2^32,然后乘以1M,得出的数就是控制字,AD9851接受的控制字的二进制的,计算机内部表示的数也是二进制的,所以你只要将你的得到的这个数进行4次移位就得到了频率控制字,相位控制字原理相同!


    3.整个过程中,我的问题主要是以上两点,最后要注意的就是多文件编译了,多文件编译时,一定要注意文件的隐蔽性以及衔接性,否则造成了错误找都找不到,特别整个系统的中断,定时器,何时进入低功耗模式等固定资源,要分配好,安排好!就像键盘是中断唤醒的,定时器延时的,唤醒后到了哪里再进中断,合着DDS,液晶等的一起就有些复杂了,要画个大致的图!


程序就直接上在这里了!


#include<msp430x24x.h>
#include"keyscan.h"
#include"12864.h"
#include"math.h"
#define uchar unsigned char
//硬件相关性
#define dds_dir_out P2DIR=0xff
#define dds_out P2OUT
#define dds_kz_dir_out P3DIR|=BIT1+BIT2+BIT3
#define bujin 100000
//时钟脉冲
#define dds_wc_high P3OUT|=BIT1
#define dds_wc_low P3OUT&=~BIT1
//频率更新控制字
#define dds_fq_high P3OUT|=BIT2
#define dds_fq_low P3OUT&=~BIT2
//复位
#define reset_high P3OUT|=BIT3
#define reset_low P3OUT&=~BIT3
//定义5个字节的频率控制字和相位控制字
uchar DDS_KZZ[5]={0X09,0X00,0X00,0X00,0X00};
//定义0-9数值
const uchar num[11]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20};//0x20是空格,就是数组中的第10个
unsigned long table[8]={0,0,0,0,0,0,0,0};
//
unsigned long int out_freq=10000,shuzi=1000000;
uchar temp;
//延时函数
void delay_ms(unsigned int a)
{
  unsigned int b;
  while(a--)
    for(b=800;b>0;b--);
}
void delay_us(unsigned int a)
{
  while(a--)
    _NOP();
}
//复位操作
void dds_reset()
{
  reset_low;
  reset_high;
  delay_ms(5);
  reset_low;
}


//并行方式写入5个字节的数据
void write_5_byte()
{
  uchar i;
  dds_fq_low;
  for(i=0;i<5;i++)
  {
    dds_wc_low;
    delay_us(5);//从POWER_DOWN模式唤醒需要5us的时间
    dds_out=DDS_KZZ;
    dds_wc_high;       
  }
  dds_fq_high;
  _NOP();
  _NOP();
  dds_fq_low;
}
 
//端口初始化函数
void init_dds_port()
{
  dds_dir_out;
  dds_kz_dir_out;
  dds_out=0x00;//全部拉低
  P3OUT=0X00;
}



//频率控制菜单
void dds_caidan()
{
  hanzi(2,1,"频率控制");
  hanzi(0,2,"频率 :        Hz");
  hanzi(0,3,"输入 :        Hz");
  hanzi(0,4,"步进 :  100  KHz");
}
//键盘功能UP增,DOWN减,步进100Khz
void dds_key()
{
  while(!KEYZHI);
    switch(KEYZHI)//比较KEYZHI,最后得到一个
    {
    case 0x11:
      {
        temp="1";
        break;
      }
    case 0x21:
      {
        temp="2";
        break;
      }
    case 0x41:
      {
        temp="3";
        break;
      }
      case 0x12:
      {
        temp="4";
        break;
      }
      case 0x22:
      {
        temp="5";
        break;
      }
      case 0x42:
      {
        temp="6";
        break;
      }
      case 0x14:
      {
        temp="7";
        break;
      }
      case 0x24:
      {
        temp="8";
        break;
      }
      case 0x44:
      {
        temp="9";
        break;
      }
      case 0x28:
      {
        temp="0";
        break;
      }
      case 0x88:
      {
        temp="88";
        break;
      }
    }   
    KEYZHI="0";  
}


//计数单元清零(显示)
void clr_shuzi(uchar y)
{
  uchar x;
  for(x=3;x<7;x++)
  {
    one_char(x,y,0x20,0x20);
  }
}
//液晶显示频率输入,在液晶上输入一个数字并且将这个数转成10进制,即shuzi
void keyin_process()
{
  shuzi="0";//只要是键盘处理输入数字就清楚原来的数字
  uchar pre,now,x,y=3;
  uchar i="0",b,a;
  for(x=3;x<7;x++)
  {
    one_char(x,y,0x5f,0x20);
    dds_key();
    if(temp==88)
      break;
    pre="num"[temp];//实际应该是键盘输入的值
   
    table=temp;
    i++;//将按键按下的数装进table中
   
    now="0x5f";//箭头当做光标
    one_char(x,y,pre,now);
    dds_key();
    if(temp==88)
      break;
    now="num"[temp]; 
   
    table=temp;
    i++;//将按键按下的数装进table中
   
    one_char(x,y,pre,now);
    if(x==6)
    {
       while(temp!=88)//写到最后一个字时检测确认键
       {
       dds_key();
       }   
    }
  }
//一下部分是把table中的数字合成一个频率数 
  a="i";
  for(b=0;b<a;b++)
  {
  shuzi+=table*(pow(10,(i-1)));
  i--;
  }
}
//频率计算,根据需要输出的频率,计算出控制字的值
void freq_solution()
{
  unsigned long temp;
  float n="0".02793968;
  uchar i="0",b=0;
  temp="out"_freq/n;


  for(i=4;i>0;i--)
  {
    DDS_KZZ=temp|b;
    temp>>=8;
  }
}


//集成化dds处理
void dds()
{
  out_freq=shuzi;
  freq_solution();
  dds_reset();
  delay_ms(3);
  write_5_byte(); 
}



//任意数字液晶显示,将8位数值显示在液晶上
void xianshi(unsigned long xs)
{
  con_disp(0xff,0xff,0x90,0x90,2,16);
  unsigned long tem;
  uchar a,b,c,d,e,f,g,h;
  uchar x="3",y=2;
  tem="xs";
  a="tem/10000000";//10M位
  b="tem"%10000000/1000000;//M位
  c="tem"%1000000/100000;//100K位
  d="tem"%100000/10000;//10K位
  e="tem"%10000/1000;//K位
  f="tem"%1000/100;//100位
  g="tem"%100/10;//10位
  h="tem"%10;//个位
  if(a==0)
  {
    a="10";
    if(b==0)
    {
      b="10";
      if(c==0)
      {
        c="10";
        if(d==0)
        {
          d="10";
          if(e==0)
          {
            e="10";
            if(f==0)
            {
              f="10";
              if(g==0)
              {
                g="10";
                if(h==0)
                {
                  h="0";
                }
              }
            }
          }
        }
      }
    }
  }
  one_char(x,y,num[a],num);
  x++;
  one_char(x,y,num[c],num[d]);
  x++;
  one_char(x,y,num[e],num[f]);
  x++;
  one_char(x,y,num[g],num[h]);
}
//步进算法
void bj_1()
{
  shuzi+=bujin;
  xianshi(shuzi);
  dds();
  LPM1;
}
void bj_2()
{
  shuzi-=bujin;
  xianshi(shuzi);
  dds();
  LPM1;
}
void bj_process()
{
  while(!KEYZHI);
  while(1)
  {


    if(KEYZHI==0x18)
      {       
        KEYZHI="0";
        delay_us(10);
        bj_2();
      }
    else if(KEYZHI==0x48)
      {              
        KEYZHI="0";
        delay_us(10);
        bj_1();
      }
    else
      break;
   }     
}


 


 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户377235 2014-7-13 21:29

系统时钟是120M的话,就用系统时钟120M除以2^32,然后乘以1M,得出的数就是控制字。这个方法直接确定不是会有一定误差吗?我生成60MHz频率,但示波器上只有58M。请问这个误差怎么解决啊?请问您里面设置的步进会减小这个误差吗?我是学生,正在学dds,所以在这边不太懂,所以向您求助一下

用户1373959 2010-5-18 21:19

我顶。

用户1609127 2010-5-18 19:53

源码补上: http://j.imagehost.org/download/0411/05-Number_Module

用户515414 2009-8-22 11:46

呵呵,谢谢你的评论,也难怪很多人测得的波形都不一样了,滤波器的我早就写了一篇设计的文章了,可能你没看到!
相关推荐阅读
用户515414 2010-04-28 22:18
第一天
capture CIS中的快捷键原理图页面编辑 CTRL+A 全选所有原理图页面编辑 B 放置总线BUS原理图页面编辑 E 放置总线BUS 的分支Entry原理图页面编辑 F 放置电源符号原理图页面编...
用户515414 2010-04-27 20:33
准备做个板
从咸宁过来武大有半年了,一直忙着毕业的事情以及导师的项目,很久没有更新空间了,现在项目闲下来了,也该做做自己的事情了,准备画一个2440的开发板。想每天上来更新下自己的进度,记录下,也能让自己坚持下去...
用户515414 2009-09-18 13:01
关于ARM7时钟的问题
在ARM7处理器中,在没有配置PLL和VPB分频器前,系统时钟Fcclk就是外部晶振的时钟Fosc,内部VPB总线的时钟是Fcclk/4也就是说是Fosc/4,开始关于时钟这章的疑惑就在这里。网上有学...
用户515414 2009-09-15 18:38
msp430开发板
对msp430的一个总结板,集成了学习430来做过的一些东西,彩色触摸液晶屏,24L01,DDS AD9851……正面反面https://static.assets-stash.eet-china.c...
用户515414 2009-09-09 11:10
开始学习ARM了
开始两天了,今天终于能在Proteus里仿真lpc2100了,对系统启动的过程也有了个大致的认识,再过两天我的板子就到了。...
用户515414 2009-08-30 15:04
AD603调试心得
在众多网友的经验下,AD603的调试也算是顺风顺水,半天解决了,开始直接照着PDF搭了个模式二的电路,直接将函数发生器的信号输入进来,波形严重失真,扭曲的不成样子,频率也不对,并且增益不可控,但是很稳...
EE直播间
更多
我要评论
2
8
关闭 站长推荐上一条 /3 下一条