AD9833程序汇总 下载本文

Main.C

/***********************************************

**** AVR SPI接口控制AD9833 ***

功能:M8 SPI 接口控制 AD9833 AD9833为DDS(Direct Digital Frequency Synthesis)直接数字频率合成器 可产生0-12.5MHz的正弦波、三角波、方波 作者:hb8421 编译器:WINAVR20050214

开始时间:2007年7月3日10:33:26 结束时间:

***********************************************/ #include #include #include #include

//时钟定为内部晶振 8MHz,F_CPU=8000000 #include \#include \#include \int main(void) { //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻 //不用的管脚使能内部上拉电阻。 PORTB=0xFF; PORTC=0xFF; PORTD=0xFF; //设定SPI接口 PORTB=(1<

1

}

} }

Main.h

#ifndef _main_H_ #define _main_H_ 1

//控制位

#define ctr8 0 //PD0 #define ctr4 1 //PD1 #define ctr2 2 //PD2 #define ctr1 3 //PD3 #define pn 7 //PD7

#define T1_OUT 0//PC0 脉冲输出 //全局变量声明

volatile unsigned char ctr_v;//拨码开关8421的输出 volatile unsigned char ctr_pn;//正负脉冲按钮开关的输出

volatile unsigned int T1_TOP;//设置T1的时间值

#endif /* _main_H_ */

Control.c

/*

控制文件

对控制端口拨码开关8421判断和对正负脉冲按钮开关的判断*/ #include #include #include #include

#include \#include \

//---------------------------------------------

//ctr8421:对控制端口拨码开关8421判断 //

//输入:无

//输出:ctr_v unsigned char

//---------------------------------------------

2

unsigned char ctr8421(void) { //ctr=0 if(((PIND&(1<

if(((PIND&(1<

if(((PIND&(1<

if(((PIND&(1<

if(((PIND&(1<

if(((PIND&(1<

if(((PIND&(1<

if(((PIND&(1<

if((!(PIND&(1<

3

if((!(PIND&(1<

//--------------------------------------------- //ctrpn:对正负脉冲按钮开关的判断 //

//输入:无

//输出:ctr_p unsigned char

//--------------------------------------------- unsigned char ctrpn(void) { if(!(PIND&(1<

#ifndef _control_H_ #define _control_H_ 1

unsigned char ctr8421(void); unsigned char ctrpn(void);

#endif /* _control_H_ */

AD9833.C

/*

AD9833

功能:可编程波形发生器,能够产生正弦波、三角波、方波输出。 特点:主频时钟为25MHz时,精度为0.1Hz,主频时钟为1MHz时,精度可以达到0.004Hz。 输出正弦波频率 fOUT=M(fMCLK/2^28) M为频率控制字,由外部编程给定,其范围为0≤M≤2^28-1。 fMCLK为外部输入晶振。

FSYNC引脚是使能引脚,电平触发方式,低电平有效。进行串行数据传输时,FSYNC引脚必须置低,

要注意FSYNC有效到SCLK下降沿的建立时间t7的最小值。FSYNC置低后,在16个SCLK的下降沿数据

被送到AD9833的输入移位寄存器,在第16个SCLK的下降沿FSYNC可以被置高,但要注意在SCLK下降

沿到FSYNC上升沿的数据保持时间ts的最小和最大值。当然,也可以在FSYNC为低电平

4

的时候,连

续加载多个16位数据,仅在最后一个数据的第16个SCLK的下降沿的时将FSYNC置高,最后需要注意

的是,写数据时SCLK时钟为高低电平脉冲信号,但是,在FSYNC刚开始变为低时(即将开始写数 据时),SCLK必须为高电平(注意t11这个参数)。

当AD9833初始化时,为了避免DAC产生虚假输出,RESET必须置为1(RESET不会复位频率、相位和 控制寄存器),直到配置完毕,需要输出时才将RESET置为0;RESET为0后的8-9个MCLK时钟周期

可在DAC的输出端观察到波形。 AD9833数据传输格式: 对于单个16位数据来说,高位在前,低位在后。 对于频率寄存器和相位寄存器来说,先是控制字,再是数据低字节,最后是数据高字节。 */

#include #include #include #include #include \#include \

/*----------------------------------------------------------------------- delay_nus :长延时函数(GCC内部延时函数的延时过短)

输入参数: t :延时时间 us

-----------------------------------------------------------------------*/ void delay_nus(unsigned int t) {

while (t--)

_delay_us(1); }

/*----------------------------------------------------------------------- delay_nms :长延时函数(GCC内部延时函数的延时过短)

输入参数: t :延时时间 ms

-----------------------------------------------------------------------*/ void delay_nms(unsigned int t) {

while (t--)

_delay_ms(1); }

//----------------------------------------------------------------------- //Write_word : 写16位数据到SPI接口,软件SPI方式

5

//输入参数: data: 数据(16位)

//----------------------------------------------------------------------- void Write_word(unsigned int data) { unsigned char i; SCL_H; SDA_H; FSYNC_H; delay_nus(200); FSYNC_L; for(i=0;i<16;i++) { if(data&0x8000) SDA_H; else SDA_L; SCL_L; delay_nus(5); SCL_H; data=data<<1; } delay_nus(2); FSYNC_H; SCL_L; delay_nus(200); }

void init_ad9833(void) { Write_word(0x2100); //28位连续,选择频率0,相位0,RESET=1 Write_word(0x4000); //写频率0寄存器的低字节LSB Write_word(0x4000); //写频率0寄存器的高字节MSB Write_word(0x2900); //28位连续,选择频率0,相位0,RESET=1 Write_word(0x8000); //写频率0寄存器的低字节LSB Write_word(0x8000); //写频率0寄存器的高字节MSB Write_word(0xC000); //写频率0寄存器的低字节LSB Write_word(0xF000); //写频率0寄存器的高字节MSB Write_word(0x2000); //28位连续,选择频率0,相位0,RESET=0 }

//------------------------------------------------------------------ //output :AD9833输出指定频率的正弦波 //

//输入参数:freq_value 类型:unsigned long //输出参数:无

6

//------------------------------------------------------------------ void output(unsigned long freq_value) { unsigned long dds; unsigned int dds_l,dds_h; dds= freq_value *268.435456; //268435456/ FMCLK dds=dds<<2; dds_l=dds; //低字节 dds_h=dds>>16; //高字节 dds_l=dds_l>>2; dds_l=dds_l & 0x7FFF; dds_l=dds_l | 0x4000; dds_h=dds_h & 0x7FFF; dds_h=dds_h | 0x4000; Write_word(0x2000); //28位连续,选择频率0,相位0,RESET=0 Write_word(dds_l); Write_word(dds_h); }

AD9833.H

//AD9833头文件 #ifndef _AD9833_H_ #define _AD9833_H_ 1 //定义AD9833的时钟

#define FMCLK 1000000 //AD9833的主晶振为1MHz //M8管脚定义

#define AD9833_CE 2 //PB2 SS #define AD9833_SDATA 3 //PB3 MOSI #define AD9833_SCLK 5 //PB5 SCK //宏定义

#define FSYNC_L PORTB&=~(1<

#define FSYNC_H PORTB|= (1<

#define SCL_L PORTB&=~(1<

#define SDA_L PORTB&=~(1<

void Write_word(unsigned int data);//写16位数据到SPI接口 void init_ad9833(void);

void output(unsigned long freq_value);//AD9833输出指定频率的正弦波 void delay_nus(unsigned int t);//延时函数——微妙

7

void delay_nms(unsigned int t);//延时函数——毫秒 #endif /* _AD9833_H_ */

8