ad9833.c

来自「89c2051控制的DDS信号发生芯片AD98」· C语言 代码 · 共 283 行

C
283
字号
#include <AT89x051.H>
#include <INTRINS.H>
#include "SIGNAL.h"

#define AD9833_CLK	DDS_CLK
#define AD9833_CS	DDS_CS
#define AD9833_DATA	DDS_DATA

//#define DDS_PORT	P3

#define cs_9833 		AD9833_CS=0;		//(DDS_PORT &= 0x7f)
#define not_cs_9833 	AD9833_CS=1;		//(DDS_PORT |= 0x80)

#define set_9833_sdata 	AD9833_DATA = 1;		//(DDS_PORT |= 0x20)
#define clr_9833_sdata 	AD9833_DATA = 0;		//(DDS_PORT &= 0xdf)
#define set_9833_clk 	AD9833_CLK = 1;		//(DDS_PORT |= 0x40)
#define clr_9833_clk 	AD9833_CLK = 0;		//(DDS_PORT &= 0xbf)

//unsigned long int ad9833_turn_word;
//const ulong  culAd9833Clock=16384000;
//const float cfAd9833Coeff=16.384;
const unsigned int cuiAd9833Coeff=16384;

const unsigned long mulSweepMaxFreq=80000;
const unsigned int mulSweepMinFreq=1000;
const unsigned int muiSweepStepFreq=328;

unsigned long mulSweepMaxFreqWord;
unsigned long mulSweepMaxFreqWord;
unsigned long gulSweepCurrentFreqWord;
//unsigned long gulCurrentFrequecy;

/*
union turn_word
  {
   unsigned long int ad9833_long_word;
   unsigned int ad9833_word[2];
  }ad98_turnword;

*/
//高位regi1,低位regi0
void write_ad9833(unsigned char regi0,unsigned char regi1)
{
  	unsigned char i;
	set_9833_clk;
	cs_9833;

  	for(i=0;i<8;i++)
	{
		//_nop_();_nop_();_nop_();_nop_();_nop_();
		set_9833_clk;
		regi1 = regi1 << 1;
		DDS_DATA = CY;
		//_nop_();_nop_();_nop_();_nop_();_nop_();

		clr_9833_clk;
   	}
	for(i=0;i<8;i++)
	{
		//_nop_();_nop_();_nop_();_nop_();_nop_();
		set_9833_clk;

		regi0 = regi0 << 1;
		DDS_DATA = CY;
		//_nop_();_nop_();_nop_();_nop_();_nop_();

		clr_9833_clk;
  	}

  	not_cs_9833;

  	set_9833_clk;
}
//
//   --------------------------------------------------------
//             计算出的频率值送入AD9833
//ulFreq单位为1Hz
void freq_ad9833_out(ulong ulFreq)
{
	unsigned char Ad9833RegLow,Ad9833RegHigh;
	ulong  ulFreqWord;

     //if(ulFreq<200000)        ad98_turnword.ad9833_long_word=ulFreq*cuiAd9833Coeff/1000;
	//else if(ulFreq<2000000)
	/*
	ad98_turnword.ad9833_long_word=ulFreq/10*cuiAd9833Coeff/100;

	{
	        Ad9833RegLow = 0x00;
             Ad9833RegHigh = 0x20;
             write_ad9833(Ad9833RegLow,Ad9833RegHigh);

		   //先写低14位
	        ad98_turnword.ad9833_long_word =  ad98_turnword.ad9833_long_word<<2;
	        ad98_turnword.ad9833_word[1] = ad98_turnword.ad9833_word[1]>>2;

	        Ad9833RegLow = ad98_turnword.ad9833_word[1]&0xff;
	        Ad9833RegHigh = (ad98_turnword.ad9833_word[1]>>8)&0xff;

	        Ad9833RegHigh &= ~0x80;
	        Ad9833RegHigh |= 0x40;
	        write_ad9833(Ad9833RegLow,Ad9833RegHigh);

		   //再写高14位
	        Ad9833RegLow = ad98_turnword.ad9833_word[0]&0xff;
	        Ad9833RegHigh = (ad98_turnword.ad9833_word[0]>>8)&0xff;

	        Ad9833RegHigh &= ~0x80;
	        Ad9833RegHigh |= 0x40;
	        write_ad9833(Ad9833RegLow,Ad9833RegHigh);
	}
	*/
	     Ad9833RegLow = 0x00;
          Ad9833RegHigh = 0x20;
          write_ad9833(Ad9833RegLow,Ad9833RegHigh);

		ulFreqWord=ulFreq/10*cuiAd9833Coeff/100;
		//先写低14位
          Ad9833RegLow = ulFreqWord&0xff;
	     Ad9833RegHigh =(ulFreqWord>>8)&0xff;
	     Ad9833RegHigh &= ~0x80;
	     Ad9833RegHigh |= 0x40;
	     write_ad9833(Ad9833RegLow,Ad9833RegHigh);
		//再写高14位
          Ad9833RegLow = (ulFreqWord>>14)&0xff;
	     Ad9833RegHigh =(ulFreqWord>>22)&0xff;
	     Ad9833RegHigh &= ~0x80;
	     Ad9833RegHigh |= 0x40;
	     write_ad9833(Ad9833RegLow,Ad9833RegHigh);
}

void select_waveform(uchar ucWave)
{
	unsigned char Ad9833RegLow,Ad9833RegHigh;
     Ad9833RegHigh = 0x20;
     if(ucWave==SINE)	Ad9833RegLow = CMD_SIN;
	else if(ucWave==SQURE)	Ad9833RegLow = CMD_SQURE;
	else if(ucWave==RAMP)	Ad9833RegLow = CMD_RAMP;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);
}
//    --------------------------------------------------------
//            AD9833 Control Subroutines
//    --------------------------------------------------------
//
//             Subroutine: Reset AD9833
//
//    write to control register R15,R14 == 00
//    write to freq0 register R15,R14 == 01
//    write to freq1 register R15,R14 == 10
//    write to phase0 register R15,R14,R13 == 110
//    write to phase1 register R15,R14,R13 == 111
//
//    BIT     SLEEP1 SLEEP12
//            0      0        no power down
//            0      1        DAC power down
//            1      0        internal clock disable
//            1      1        DAC power down internal clock disable
//
//   15 14  13  12   11      10    9   8     7       6       5     4    3   2   1    0
//    0  0 B28 HLB FSELECT PSELECT 0 RESET SLEEP1 SLEEP12 OPBITEN  0  DIV2  0  MODE  0
//
//    BIT    OPBITEN  MODE  DIV2    VOUT
//             0       0     *     sinusoid
//             0       1     *     triangle
//             1       0     0     MSB/2
//             1       0     1     MSB
//             1       1     *     RESERVED
//

//初始化结束后输出正弦波,频率为1/128*Fmclk/2
void reset_ad9833(void)
{
	unsigned char Ad9833RegLow,Ad9833RegHigh;
	//cs_9833;
	Ad9833RegLow = 0;
	Ad9833RegHigh = 0x21;                 //set ad9833 control register reset bit
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);
//////////////////////////////////////////////////////////////////////////////////////
	Ad9833RegLow = 0;
	Ad9833RegHigh = 0x40;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);   // F0 == 1/128*Fmclk/2
	Ad9833RegLow = 0x80;
	Ad9833RegHigh = 0x40;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);   //
	Ad9833RegLow = 0;
	Ad9833RegHigh = 0x80;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);   // F1 == 1/64*Fmclk/2
	Ad9833RegLow = 0;
	Ad9833RegHigh = 0x81;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);   //
	Ad9833RegLow = 0;
	Ad9833RegHigh = 0xc0;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);   // P0 == 0
	Ad9833RegLow = 0;
	Ad9833RegHigh = 0xe8;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);   // P1 == pi
/////////////////////////////////////////////////////////////////////////////////////
	Ad9833RegLow = 0x00;
	Ad9833RegHigh = 0x20;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);
/////////////////////////////////////////////////////////////////////////////////////
	//not_cs_9833;
}
//
//  ------------------------------------------------------------
//
/*
void clr_9833(void)
{
 	write_ad9833(0x00,0x01);
}
void open_9833(void)
{
     write_ad9833(0x00,0x20);
}
*/
void sweep_process_and_freq_ad9833_out(void)
{
	unsigned char Ad9833RegLow,Ad9833RegHigh;
	ulong  ulFreqWord;

	gulSweepCurrentFreqWord+=muiSweepStepFreq;
     if(gulSweepCurrentFreqWord>mulSweepMaxFreqWord)
     	gulSweepCurrentFreqWord=mulSweepMaxFreqWord;

	//控制字:只写频率字0的高14位
	Ad9833RegLow = 0x00;
	Ad9833RegHigh = 0x10;
	write_ad9833(Ad9833RegLow,Ad9833RegHigh);

		//ulFreqWord=gulSweepCurrentFreqWord/10*cuiAd9833Coeff/100;
		ulFreqWord=gulSweepCurrentFreqWord;
		//先写低14位
          Ad9833RegLow = ulFreqWord&0xff;
	     Ad9833RegHigh =(ulFreqWord>>8)&0xff;
	     Ad9833RegHigh &= ~0x80;
	     Ad9833RegHigh |= 0x40;
	     write_ad9833(Ad9833RegLow,Ad9833RegHigh);
		//再写高14位
          Ad9833RegLow = (ulFreqWord>>14)&0xff;
	     Ad9833RegHigh =(ulFreqWord>>22)&0xff;
	     Ad9833RegHigh &= ~0x80;
	     Ad9833RegHigh |= 0x40;
	     write_ad9833(Ad9833RegLow,Ad9833RegHigh);

}

void sweep_init(void)
{
	//晶体为24MHZ
	//定时器1工作在方式1,作为16位定时器
	TMOD|=0x10;
    	TL1=-(8000%256);//1ms中断一次
    	TH1=-(8000/256);
    	TR1=0;		//停止定时器1
    	PT1=1;		//定时器1为高优先级
    	ET1=1;     	//允许定时器1中断
	/*
     Ad9833RegLow = 0x00;
     Ad9833RegHigh = 0x10;//只写高14位频率字
     write_ad9833(Ad9833RegLow,Ad9833RegHigh);
	*/
	//得到扫描频率的最大值和最小值的高14位
	mulSweepMaxFreqWord=mulSweepMaxFreq/10*cuiAd9833Coeff/100;
	mulSweepMaxFreqWord=mulSweepMinFreq/10*cuiAd9833Coeff/100;
	gulSweepCurrentFreqWord=mulSweepMaxFreqWord;
}


void sweep_start_process(void)
{
	//得到扫描频率的最大值和最小值的高14位

	freq_ad9833_out(mulSweepMaxFreqWord);
    	TL1=-(2000%256);//1ms中断一次
    	TH1=-(2000/256);
    	TR1=1;		//启动定时器1
}
void sweep_stop_process(void)
{
    	TR1=0;		//停止定时器1
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?