原创 DDS AD9833 的单片机控制

2008-10-11 08:55 6980 6 10 分类: MCU/ 嵌入式
DDS,即数字直接合成,产生各种波形。DDS芯片有很多,比较常用的是AD公司的AD9833。
电路如下:
点击看大图
其中:
    FCS  片选信号
    SCLK 数据传输时钟
    SDA  数据线
    MCLK 芯片主频,接一个25M的晶振模块

控制程序如下:
环境:
    Keil C 8.02
    C8051F020 @ 20M


//代码
sbit FCS1 = P3^1;
sbit SCL  = P3^4;
sbit SDA  = P3^5;


#define B28  0x2000      //complete word or two seperate byte
#define HLB  0x1000      //H/L Byte sequience input
#define FSEL 0x0800      //Freq0 or Freq1
#define PSEL 0x0400      //Phase0 or Phase1
#define REST 0x0100      //1: Reset
#define SLP1 0x0080      //1: Internal MCLK Disable
#define SLP2 0x0040      //1: PowerDown Onchip DAC
#define OPBITEN 0x0020   //VOUT connect to MSB/2
#define DIV2 0x0004      //when opbiten,
#define MODE 0x0002      //

#define ASTR  0x0000
#define AFREQ0 0x4000
#define AFREQ1 0x8000
#define APHS0  0xD000
#define APHS1  0xF000

void spi_delay(unsigned int n)
{
    unsigned int i,j = n*10;
    for(i=0; i<j; i++){_nop_();};
}

void spi_initialize()
{
    unsigned char i,j;

    WDTCN     = 0xDE;
    WDTCN     = 0xAD;

    XBR0 = 0x05;
    XBR2      = 0x40;

    P3MDOUT   = 0xFF;
    P3 = 0xFF;

    return;
}

void spi_sendword(unsigned int wData)
{
    unsigned int bitTest=wData;
    unsigned char i;

    SCL = 1;
    SDA = 1;
    FCS1 = 1;
    spi_delay(10);

    FCS1 = 0;
    spi_delay(5);

    for(i=0; i<16; i++)
    {
        if((bitTest & 0x8000))
            {
                SDA = 1;
            }
        else
            {
                SDA = 0;
            }
       
        SCL = 0;
        spi_delay(5);
        SCL = 1;
        spi_delay(4);
        bitTest <<= 1;
    }
    spi_delay(2);
    FCS1 = 1;
    spi_delay(2);
    SCL = 1;

    return;
}


void main()
{
    unsigned int a,b;

    spi_initialize();
   
    //初始化,所有寄存器清零
    spi_sendword(ASTR | B28 | REST);
    spi_sendword(AFREQ0 | 0);
    spi_sendword(AFREQ0 | 0);
    spi_sendword(ASTR   | B28 |REST | FSEL);
    spi_sendword(AFREQ1 | 0);
    spi_sendword(AFREQ1 | 0);
    spi_sendword(APHS0  | 0);
    spi_sendword(APHS1  | 0);


    //产生正弦波;先写指令寄存器,后写频率寄存器;高14位在前,低14位在后
    spi_sendword(ASTR   | B28);
    spi_sendword(AFREQ0 | 0x49B);     //200k sine wave
    spi_sendword(AFREQ0 | 0x83);

    while(1)
    {
        _nop_();
    }
}

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户85560 2009-7-14 13:10

郁闷!发的程序怎么成这样子了! 没查到博主的联系方式, 我的联系方式:wangyuanlu@rigol.com 可否向你咨询?

用户85560 2009-7-14 13:07

程序如下: Config.H文件: **************************************** #include ".\include\at89X52.H" sbit DDSCLK = 0x84; // P0_4 sbit DDSEN = 0x85; // P0_5 sbit DDSData = 0xB7; // P3_7 extern void DDSIni(); extern void LDelay(unsigned char DelayNum); extern void SDelay(unsigned char DelayNum); extern void AD9833_reset(); extern void AD9833_writedata(unsigned int DDSdata); extern void Load_wave(unsigned int Contr_Reg_data,unsigned int Fre_MSBdata,unsigned int Fre_LSBdata,unsigned int Phs_data); AD9833.c文件: ****************************** //C Files #include "config.h" void DDSIni() { /* P1_2=0; DDSCS=0; // DDSCS able _595CS=1; //595CS disable */ DDSEN=1; //DDSEN disable DDSCLK=1; //Clock high DDSData=0; AD9833_reset(); } void LDelay(unsigned char DelayNum) { unsigned char Delay1p6mS=0XFF; while(DelayNum--) { while(Delay1p6mS--); } } void SDelay(unsigned char DelayNum) { while(DelayNum--); } ///////////////////////////////////// /*函数描述: /*写入参数: /*返回参数: /*作者: /*日期: *//////////////////////////////////// void AD9833_reset() { //add code here AD9833_writedata(0x2100); //准备清空频率寄存器0 AD9833_writedata(0x4000); //Filled with 0 AD9833_writedata(0x4000); //Filled with 0 AD9833_writedata(0x2900); //Prepare for clear Fre1 AD9833_writedata(0x8000); //Filled with 0 AD9833_writedata(0x8000); //Filled with 0 AD9833_writedata(0xD000); //clear PHS 0 AD9833_writedata(0xF000); //clear PHS 1 } void AD9833_writedata(unsigned int DDSdata) { unsigned char data_num=0; unsigned int DDSdata_temp; DDSdata_temp=DDSdata; DDSCLK=1; SDelay(80); DDSEN=0; //DDS able SDelay(80); for(data_num=0;data_num<16;data_num++) { if(DDSdata_temp & 0X8000 ) { DDSData=1; } else { DDSData=0; } SDelay(50); DDSCLK=0; SDelay(100); /* DDSData=0; SDelay(100); */ DDSCLK=1; DDSdata_temp=DDSdata_temp<<1; if(data_num < 15) { SDelay(1000); } } DDSEN=1; } void Load_wave(unsigned int Contr_Reg_data,unsigned int Fre_MSBdata,unsigned int Fre_LSBdata,unsigned int Phs_data) { //add unsigned int Fre_MSBdata_temp=Fre_MSBdata; unsigned int Fre_LSBdata_temp=Fre_LSBdata; unsigned int Contr_Reg_data_temp=Contr_Reg_data; unsigned int Phs_data_temp=Phs_data; AD9833_writedata(Contr_Reg_data_temp); AD9833_writedata(Fre_LSBdata_temp); AD9833_writedata(Fre_MSBdata_temp); AD9833_writedata(Phs_data); } main.c 文件 ******************************************** //main files #include "config.h" main() { //add code here //hardware_test(); LDelay(0XFF); LDelay(0XFF); DDSIni(); Load_wave(0x2100,0x400F,0x4FFF,0xD000); while(1) { ; } }

用户150704 2009-6-23 22:42

不可以的

用户1406757 2009-6-11 18:34

AD9833可以直接输出占空比可调的方波吗?
相关推荐阅读
用户150704 2010-08-08 09:49
关于 error 122 AGDI: memory read failed 问题
 在和STM32F103战斗了1个多星期之后,终于搞定error122 AGDI: memory read failed问题。其中过程曲折,而结果却出人意料的简单。特别整理出来,希望对各位同仁有所帮助...
用户150704 2010-03-14 14:36
三相无刷电机控制与TMS320F2812 -- F2812简介(5)
系统控制与时钟    系统控制与时钟模块包括复位控制、时钟、功耗控制,如图1所示。复位控制:    外部复位脚XRS输入低电平信号后,系统控制模块产生内核复位信号(Reset),使CPU复位。再由CP...
用户150704 2010-03-13 16:00
三相无刷电机控制与TMS320F2812 -- F2812简介(4)
中断系统        F2812芯片的CPU支持一个不可屏蔽中断(NMI)和14个可屏蔽中断(INT1~INT14),这些中断称为CPU级中断。芯片内部集成了许多外部设备,如SPI、SCI、CAN等...
用户150704 2010-03-11 22:59
三相无刷电机控制与TMS320F2812 -- F2812简介(3)
存储器映射        F2812采用哈佛结构,数据与程序分开编址,即数据空间与程序空间。如图1,为数据空间、程序空间存储器的映射关系。     数据与程序空间地址的0x000000~0x00 04...
用户150704 2010-03-07 15:19
三相无刷电机控制与TMS320F2812 -- F2812简介(2)
F2812总体结构       F2812总体结构见图1。芯片内总结构基本上可以分为三大部分:内核、外设及总线。    内核即图中的C28x CPU部分,为芯片的中央处理器。主要接受外部四种信号:- ...
用户150704 2010-03-06 22:11
三相无刷电机控制与TMS320F2812 -- F2812简介(1)
TMS320F2812简介(1)     作为新手,当你第一次拿到电机控制的设计任务时,最先要解决的问题就是选什么样的控制芯片。通常你会去师兄师姐或都是老前辈那请教该用什么。估计70%的回答是TI的C...
EE直播间
更多
我要评论
4
6
关闭 站长推荐上一条 /3 下一条