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 
//时钟定为内部晶振 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 \  //---------------------------------------------  //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  /*----------------------------------------------------------------------- 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