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