stm32+AD9910 并口驱动

搞了好几天DAC芯片AD9910 ,找到多数资料时SPI控制内部RAM或者DDS输出波形,这里总结一下STM32 FMSC 总线输出到AD9910 ,由于AD9910 的PDCLK 为输出,这里采用PWM输入捕获模式获取 AD9910 PDCLK 的下降沿,采用捕获信号触发DMA2  ,DMA 在将数据搬移到总线上,具体代码如下:


#include "ad9910.h"
#include <math.h>
#include "delay.h"
#include "string.h"
#include "dma.h"

volatile uint16_t ParallelTbl[25000]={0};// 最大点数
#define		NOR_PSRAM_ADDRBASE				(0x60000000)		// BANK1 NOR_PSRAM 基地址
#define		NOR_PSRAM_NE1_ADDRBASE		(NOR_PSRAM_ADDRBASE+((uint32_t)0x0<<26)) //SRAM  NE1 片选基地址
#define		NOR_PSRAM_NE2_ADDRBASE		(NOR_PSRAM_ADDRBASE+((uint32_t)0x1<<26)) //SRAM  NE2 片选基地址
#define		NOR_PSRAM_NE3_ADDRBASE		(NOR_PSRAM_ADDRBASE+((uint32_t)0x2<<26)) //SRAM  NE3 片选基地址
#define		NOR_PSRAM_NE4_ADDRBASE		(NOR_PSRAM_ADDRBASE+((uint32_t)0x3<<26)) //SRAM  NE4 片选基地址
#define		HDL_SET16BIT				1 //16bit FSMC

uint8_t  cfr1[4] = {0x00, 0x40, 0x00, 0x02};//cfr1控制字
uint8_t  cfr2[4] = {0x01, 0x40, 0x08, 0x00};//cfr2控制字
uint8_t  cfr3[4] = {0x05, 0x0F, 0x41, 0x32};//cfr3控制字  40M输入  25倍频  VC0=101   ICP=001;

uint8_t  profile[8][8] = {0x00}; //ramprofile0控制字
uint8_t  drgparameter[20]={0x00};
uint32_t RAM_WAVE[1024]={0}; //RAM 波形文件

void F4xFsmcInit(void)
{
	RCC->AHB1ENR|=0xF<<3;    	//使能PD,PE,PF,PG时钟  
	RCC->AHB3ENR|=1<<0;     	//使能FSMC时钟  
	GPIO_Set(GPIOD,(3<<0)|(7<<8)|(3<<14),\
		GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PD0,1,8,9,10,14,15 AF OUT
	GPIO_Set(GPIOE,(0x1ff<<7),\
		GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PE7-15 AF OUT
	GPIO_Set(GPIOF,(0X3F<<0)|(0XF<<12),\
		GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PF0~5,12~15
//COM DEF
	GPIO_Set(GPIOD,(3<<4),\
		GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PD4~5 RD,WR
//PD7,//FSMC_NE1,/CS1 
//PG9,//FSMC_NE2,/CS2 
//PG10,//FSMC_NE3,/CS3 
//PG12,//FSMC_NE4,/CS4 
	// GPIO_Set(GPIOG,PIN9,\
	// 	GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);// 
	GPIO_Set(GPIOD,PIN7,\
		GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);// 
	// DATA AF
 	GPIO_AF_Set(GPIOD,14,12);	//PD14,AF12
 	GPIO_AF_Set(GPIOD,15,12);	//PD15,AF12
	GPIO_AF_Set(GPIOD,0,12);	//PD0,AF12
 	GPIO_AF_Set(GPIOD,1,12);	//PD1,AF12
 	GPIO_AF_Set(GPIOE,7,12);	//PE7,AF12
 	GPIO_AF_Set(GPIOE,8,12);	//PE8,AF12
 	GPIO_AF_Set(GPIOE,9,12);	//PE9,AF12
 	GPIO_AF_Set(GPIOE,10,12);	//PE10,AF12
 	GPIO_AF_Set(GPIOE,11,12);	//PE11,AF12
 	GPIO_AF_Set(GPIOE,12,12);	//PE12,AF12
 	GPIO_AF_Set(GPIOE,13,12);	//PE13,AF12
 	GPIO_AF_Set(GPIOE,14,12);	//PE14,AF12
 	GPIO_AF_Set(GPIOE,15,12);	//PE15,AF12
 	GPIO_AF_Set(GPIOD,8,12);	//PD8,AF12
 	GPIO_AF_Set(GPIOD,9,12);	//PD9,AF12
 	GPIO_AF_Set(GPIOD,10,12);	//PD10,AF12
	
 	GPIO_AF_Set(GPIOF,0,12);	//PF0,AF12
 	GPIO_AF_Set(GPIOF,1,12);	//PF1,AF12
 	GPIO_AF_Set(GPIOF,2,12);	//PF2,AF12
 	GPIO_AF_Set(GPIOF,3,12);	//PF3,AF12
 	GPIO_AF_Set(GPIOF,4,12);	//PF4,AF12
 	GPIO_AF_Set(GPIOF,5,12);	//PF5,AF12
 	GPIO_AF_Set(GPIOF,12,12);	//PF12,AF12
 	GPIO_AF_Set(GPIOF,13,12);	//PF13,AF12
 	GPIO_AF_Set(GPIOF,14,12);	//PF14,AF12
 	GPIO_AF_Set(GPIOF,15,12);	//PF15,AF12
	
 	GPIO_AF_Set(GPIOD,4,12);	//PD4,AF12 //RD
 	GPIO_AF_Set(GPIOD,5,12);	//PD5,AF12 //WR

	GPIO_AF_Set(GPIOD,7,12);	//PD7,AF12 // 
	
	//寄存器清零
	//BANK 1 支持nor SRM控制
	//bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
	//这里我们使用NE1 ,也就对应BTCR[0],[1]。				    
	FMC_Bank1->BTCR[0]=0X00000000;//NE 1 
	FMC_Bank1->BTCR[1]=0X00000000;
	FMC_Bank1E->BWTR[0]=0X00000000;
	//操作BCR寄存器	使用异步模式,模式A(读写共用一个时序寄存器)
	//BTCR[偶数]:BCR寄存器;BTCR[奇数]:BTR寄存器
	FMC_Bank1->BTCR[0]|=1<<12;//存储器写使能
#if HDL_SET16BIT>0
	FMC_Bank1->BTCR[0]|=1<<4; //存储器数据宽度为16bit 	
#else
	FMC_Bank1->BTCR[0]&=~((uint32_t)1<<4);  // 存储为8 bit
#endif
	//操作BTR片选时序寄存器		(HCLK=168M, 1个HCLK=6ns			    
	FMC_Bank1->BTCR[1]|=0xf<<8; //0000 0010: DATAST 阶段的持续时间 = 255 × HCLK 时钟周期	 
	FMC_Bank1->BTCR[1]|=0<<4; //地址保持时间(ADDHLD)未用到	  	 
	FMC_Bank1->BTCR[1]|=0<<0; //地址建立时间(ADDSET)为0个HCLK 0ns	 	 
	//闪存写时序寄存器  
//	FMC_Bank1E->BWTR[0]=0x0FFFFFFF;//默认值
	FMC_Bank1E->BWTR[0]|=(0xf<<8);//DATAST: 数据阶段的持续时间 (Data-phase duration)。
	FMC_Bank1E->BWTR[0]|=0<<4;//地址保持阶段的持续时间
	FMC_Bank1E->BWTR[0]|=0<<0;//地址设置阶段的持续时间
	
	FMC_Bank1->BTCR[0]|=1<<0; //使能BANK1区域1
}


/******************************************************************************
 * Init GPIO for DDS
******************************************************************************/
void DDS_GPIO_Init(void)
{
	RCC->AHB1ENR|=1<<1;//使能PORTB时钟 
	//PB7-3
	GPIO_Set(GPIOB,PIN3|PIN4|PIN5|PIN6|PIN7|PIN8|PIN9,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //
	RCC->AHB1ENR|=1<<2;//使能PORTC时钟
	GPIO_Set(GPIOC,PIN12|PIN13,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //
	RCC->AHB1ENR|=(1<<6);//使能PORTG时钟 
	GPIO_Set(GPIOG,PIN10,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);
	//其余引脚配置:
	// 并口F[1:0] =00 ;控制幅度
	// FSMC D15-D0 =>  AD9910 D[15:0];
	// TXENABLE =1;// 接3.3v
	// PDCLK => PA8 输入PWM 捕获

  /*Configure GPIO pin Output Level */
	DDS_OSK=0;
	AD9910_PWR=0;
	PROFILE2=0;
	PROFILE1=0;
	PROFILE0=0;
	DRCTL	=0;
	DRHOLD=0;
	UP_DAT=0;
	MAS_REST=0;
	CS=0; 

	F4xFsmcInit();
	// 使用TIM1_ETR 作为并口数据输入,FSMC DATA 16bit 用作数据线
	// 配置F[1:0]="00" ;用于14bit 振幅参数设置
	RCC->AHB1ENR|=1<<0;//使能PORTA时钟 
	RCC->APB2ENR|=(1<<0);// enable TIM1
	GPIO_Set(GPIOA,PIN8,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);
	GPIO_AF_Set(GPIOA,8,1);// TIM1_CH1

	TIM1->PSC =0;// =fosc /2 =84Mhz
	TIM1->ARR=100;// 这里不使用,

	TIM1->CR2 =(1<<3);// CCDS =1;
	//DMA2-CH1 : TIM1_CH1

	TIM1->DIER=(1<<9);// CC1DE CC1_DMA enable
	TIM1->EGR =(1<<1);// CC1G enable
	TIM1->CCMR1 =(1<<0);// IC1 <-> TI1
	TIM1->CCER =(1<<1)| //下降沿触发
				(1<<0);// enable capture CC1

	//configure DMA
	DmaConfigt dmacf; 		
	dmacf.chx =6;
	dmacf.par =(uint32_t)NOR_PSRAM_NE1_ADDRBASE;//FSMC ->NE1 
	dmacf.mar=(uint32_t)ParallelTbl;// MEM
	dmacf.ndtr=25000;
	dmacf.dir=SRAMtoPeripheral; // RAM ->  FSMC
	dmacf.width=width_16bit;
	dmacf.burst=burst_single;//突发单次传输
	dmacf.loopen=1;//循环DMA模式
	MYDMA_Config(DMA2_Stream1,&dmacf);
	
	DMA2_Stream1->FCR=0x21;//不使用FIFO

	//初始化 正弦波
	double Rad =0;
	uint16_t temp =0;
	for(int i=0;i<25000;i++){
		Rad =sin((i%360) * 3.1415926/180.0)+1; 
		Rad*=8192;
		temp =(uint16_t)Rad;
     	ParallelTbl[i] =temp<<2; // Get Sinus
	}

}			

/******************************************************************************
 * Init SPI, 8bit, Master
 * MODE 3, MSB, 
******************************************************************************/
void DDS_SPI_Init(void)
{
	SPI2_Init();
	SPI2_SetSpeed(SPI_SPEED_256);
}


/*****************************************************************************************
   Update - data updates from memory
*****************************************************************************************/ 
void DDS_UPDATE(void)
{
	 delay_ms(1);
	 UP_DAT = 0;
	 delay_ms(1);
	 UP_DAT = 1;
	 delay_ms(1);
	 UP_DAT = 0;
}
 

//高14位幅度控制
const unsigned char ramdata_Square[4096] = {	
//方波
0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 
0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 
0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 
0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00, 0xff,0xfc,0x00,0x00,

0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
};

//高14位幅度控制
const unsigned char ramdata_Sawtooth[4096] = {
//锯齿波
0x00,0x00,0x00,0x00, 0x03,0xfc,0x00,0x00, 0x07,0xf8,0x00,0x00, 0x0b,0xf4,0x00,0x00, 0x0f,0xf0,0x00,0x00, 0x13,0xec,0x00,0x00, 0x17,0xe8,0x00,0x00, 0x1b,0xe4,0x00,0x00, 
0x1f,0xe0,0x00,0x00, 0x23,0xdc,0x00,0x00, 0x27,0xd8,0x00,0x00, 0x2b,0xd4,0x00,0x00, 0x2f,0xd0,0x00,0x00, 0x33,0xcc,0x00,0x00, 0x37,0xc8,0x00,0x00, 0x3b,0xc4,0x00,0x00, 
0x3f,0xc0,0x00,0x00, 0x43,0xbc,0x00,0x00, 0x47,0xb8,0x00,0x00, 0x4b,0xb4,0x00,0x00, 0x4f,0xb0,0x00,0x00, 0x53,0xac,0x00,0x00, 0x57,0xa8,0x00,0x00, 0x5b,0xa4,0x00,0x00, 
0x5f,0xa0,0x00,0x00, 0x63,0x9c,0x00,0x00, 0x67,0x98,0x00,0x00, 0x6b,0x94,0x00,0x00, 0x6f,0x90,0x00,0x00, 0x73,0x8c,0x00,0x00, 0x77,0x88,0x00,0x00, 0x7b,0x84,0x00,0x00, 	

0x7f,0x80,0x00,0x00, 0x83,0x7c,0x00,0x00, 0x87,0x78,0x00,0x00, 0x8b,0x74,0x00,0x00, 0x8f,0x70,0x00,0x00, 0x93,0x6c,0x00,0x00, 0x97,0x68,0x00,0x00, 0x9b,0x64,0x00,0x00, 
0x9f,0x60,0x00,0x00, 0xa3,0x5c,0x00,0x00, 0xa7,0x58,0x00,0x00, 0xab,0x54,0x00,0x00, 0xaf,0x50,0x00,0x00, 0xb3,0x4c,0x00,0x00, 0xb7,0x48,0x00,0x00, 0xbb,0x44,0x00,0x00, 
0xbf,0x40,0x00,0x00, 0xc3,0x3c,0x00,0x00, 0xc7,0x38,0x00,0x00, 0xcb,0x34,0x00,0x00, 0xcf,0x30,0x00,0x00, 0xd3,0x2c,0x00,0x00, 0xd7,0x28,0x00,0x00, 0xdb,0x24,0x00,0x00, 
0xdf,0x20,0x00,0x00, 0xe3,0x1c,0x00,0x00, 0xe7,0x18,0x00,0x00, 0xeb,0x14,0x00,0x00, 0xef,0x10,0x00,0x00, 0xf3,0x0c,0x00,0x00, 0xf7,0x08,0x00,0x00, 0xfb,0x04,0x00,0x00,

};

void AD9110_IOInit(void)
{
	DDS_SPI_Init();
	DDS_GPIO_Init();
}

#define	 txd_8bit	SPI2_ReadWriteByte

//======================ad9910初始化程序================================
void Init_ad9910(void)
{
	AD9110_IOInit(); //IO初始化
	AD9910_PWR = 0;  //软件拉低
	PROFILE2 = PROFILE1 = PROFILE0 = 0;
	DRCTL = 0;
	DRHOLD = 0;
	MAS_REST = 1;
	delay_ms(5);
	MAS_REST = 0;
	delay_ms(5);
	Txcfr(0xf);
}
//======================发送cfr控制字====================================
void Txcfr(int8_t m)
{
	uint8_t i;
	if(m&1){
		CS = 0;
		txd_8bit(0x00); //发送CFR1控制字地址
		for (i = 0; i < 4; i++)
			txd_8bit(cfr1[i]);
		CS = 1;
		DDS_UPDATE();
	}
	if(m&2){
		CS = 0;
		txd_8bit(0x01); //发送CFR2控制字地址
		for (i = 0; i < 4; i++)
			txd_8bit(cfr2[i]);
		CS = 1;
		DDS_UPDATE();
	}
	if(m&4){
		CS = 0;
		txd_8bit(0x02); //发送CFR3控制字地址
		for (i = 0; i < 4; i++)
			txd_8bit(cfr3[i]);
		CS = 1;
		DDS_UPDATE();
	}
}
//=====================================================================
void IoProfileUpdate(int8_t x)
{
	PROFILE2=x&0x4?1:0;
	PROFILE1=x&0x2?1:0;
	PROFILE0=x&0x1?1:0;		
	DDS_UPDATE();	
}
//ad9910发送profile0控制字程序
//int8_t profilex :8个profile
void Txprofile_cfg(int8_t profilex )
{
	uint8_t  m;
	profilex&=0x7;// 
	CS=0;
	txd_8bit(0x0e+profilex);                
	for (m=0;m<8;m++){
		txd_8bit(profile[profilex][m]); 
	}
	CS=1;
	DDS_UPDATE();
	IoProfileUpdate(profilex);
}

//计算频偏字、频率字和发送程序
//uint32_t  Freq: 0-400000000 Hz
//uint16_t amplitude : 0-16383
//uint16_t phase :0-65535
void Freq_convert(uint32_t  Freq,uint16_t amplitude,uint16_t phase)
{
	int8_t	si_profile   =0;
	uint32_t  Temp = (uint32_t )Freq * 4.294967296; 
	//将输入频率因子分为四个字节  4.294967296=(2^32)/1000000000
	profile[si_profile][7] = (uint8_t )Temp;
	profile[si_profile][6] = (uint8_t )(Temp >> 8);
	profile[si_profile][5] = (uint8_t )(Temp >> 16);
	profile[si_profile][4] = (uint8_t )(Temp >> 24);
	profile[si_profile][3] = phase&0xff;
	profile[si_profile][2] = (phase>>8)&0xff;
	profile[si_profile][1] = amplitude&0xff;
	profile[si_profile][0] = (amplitude>>8)&0x3f;
	Txprofile_cfg(si_profile);

	cfr1[0] = 0x00;// disable RAM
	cfr1[1] = 0x40;//反sin 滤波器on
	cfr1[3] =0x02;//

	cfr2[0] =0x01;// enable profile x
	cfr2[1] =(1<<6);// enable SYNC_CLK out
	cfr2[2] =(1<<3);// enable PDCLK  out
	cfr2[3] =0;// disable parallel I mode

	cfr3[0] =0x05;//PLL =1Ghz
	cfr3[2] =0x41;// PLL enable
	Txcfr(0x7);//发送cfrx控制字	
}

//计算正弦波幅值(Vpp)和发送程序
void Amp_convert(uint32_t Amp)
{
	uint32_t Temp = (uint32_t )Amp * 28.4829; 
	//将输入幅度因子分为两个字节  25.20615385=(2^14)/650
	if (Temp > 0x3fff)
		Temp = 0x3fff;
	Temp &= 0x3fff;
	profile[1][1] = (uint8_t )Temp;
	profile[1][0] = (uint8_t )(Temp >> 8);
	Txprofile_cfg(1);
}

//======================ad9910发送DRG参数程序==================================
void Txdrg(void)
{
	uint8_t  i,m;
	for(i=0;i<3;i++){
		CS=0;
		txd_8bit(0x0b+i);//发送数字斜坡限制地址0x0b,0x0c,0x0d
		for (m=0;m<8;m++)
			txd_8bit(drgparameter[m+(8*i)]); 
		CS=1;
		DDS_UPDATE();
	}
}         

//=====================扫频波参数设置和发送程序===================================
void SweepFre(uint32_t  SweepMinFre, uint32_t  SweepMaxFre, uint32_t  SweepStepFre, uint32_t  SweepTime)
{
	uint32_t  Temp1, Temp2, ITemp3, DTemp3, ITemp4, DTemp4;
	Temp1 = (uint32_t )SweepMinFre*4.294967296;
	if(SweepMaxFre > 400000000)
		SweepMaxFre = 400000000;
	Temp2 = (uint32_t )SweepMaxFre*4.294967296;
	if(SweepStepFre > 400000000)
		SweepStepFre = 400000000;
	ITemp3 = (uint32_t )SweepStepFre*4.294967296;
	DTemp3 = ITemp3;
	ITemp4 = (uint32_t )SweepTime/4;                                    //1GHz/4, 单位:ns
	if(ITemp4 > 0xffff)
		ITemp4 = 0xffff;
	DTemp4 = ITemp4;
	
	//扫频上下限
	drgparameter[7]=(uint8_t )Temp1;
	drgparameter[6]=(uint8_t )(Temp1>>8);
	drgparameter[5]=(uint8_t )(Temp1>>16);
	drgparameter[4]=(uint8_t )(Temp1>>24);
	drgparameter[3]=(uint8_t )Temp2;
	drgparameter[2]=(uint8_t )(Temp2>>8);
	drgparameter[1]=(uint8_t )(Temp2>>16);
	drgparameter[0]=(uint8_t )(Temp2>>24);
	//频率步进(单位:Hz)
	drgparameter[15]=(uint8_t )ITemp3;
	drgparameter[14]=(uint8_t )(ITemp3>>8);
	drgparameter[13]=(uint8_t )(ITemp3>>16);
	drgparameter[12]=(uint8_t )(ITemp3>>24);
	drgparameter[11]=(uint8_t )DTemp3;
	drgparameter[10]=(uint8_t )(DTemp3>>8);
	drgparameter[9]=(uint8_t )(DTemp3>>16);
	drgparameter[8]=(uint8_t )(DTemp3>>24);
	//步进时间间隔(单位:us)
	drgparameter[19]=(uint8_t )ITemp4;
	drgparameter[18]=(uint8_t )(ITemp4>>8);
	drgparameter[17]=(uint8_t )DTemp4;
	drgparameter[16]=(uint8_t )(DTemp4>>8);
	//发送DRG参数
	Txdrg();
	cfr1[0] = 0x00; //RAM 失能
	cfr2[1] = 0x0e; //DRG 使能
	Txcfr(0x3); //发送cfrx控制字
}

	
//发送方波、锯齿波波形程序
void Txramdata(uint8_t *data ,uint16_t len)
{
	CS=0;
	txd_8bit(0x16); //发送ram控制字地址
	for (uint16_t m=0; m<len; m++){
		txd_8bit(*data++); 
	}
	CS=1;
	DDS_UPDATE();
}   
void Txramdata32(uint32_t *data ,uint16_t len)
{
	union TagDat{
		uint32_t data32;
		uint8_t data8[4];
	}TagDatSt;

	CS=0;
	txd_8bit(0x16); //发送ram控制字地址
	for (uint16_t m=0; m<len; m++){
		TagDatSt.data32 =*data++;
		txd_8bit(TagDatSt.data8[3]); 
		txd_8bit(TagDatSt.data8[2]); 
		txd_8bit(TagDatSt.data8[1]); 
		txd_8bit(TagDatSt.data8[0]); 
	}
	CS=1;
	DDS_UPDATE();
} 
//========================产生方波的程序======================================
void Square_wave(uint32_t Sample_interval)
{
	int8_t	sq_profile   =2;
	cfr1[0] = 0x00;
	Txcfr(0x1); 

	uint32_t Temp = ((1000000000/(unsigned long int)(Sample_interval)/64/4));        //1GHz/4, 采样间隔范围:4*(1~65536)ns
	if(Temp > 0xffff)
			Temp = 0xffff;
	profile[sq_profile][7] = 0x24;
	profile[sq_profile][6] = 0x00;//DAC 播放开始地址
	profile[sq_profile][5] = 0x00;

	uint16_t RamAddrEnd =63; //ram 播放点数
	profile[sq_profile][4] = (RamAddrEnd<<6)&0xff;// dac 播放RAM 结束地址
	profile[sq_profile][3] = (RamAddrEnd>>2)&0xff;
	profile[sq_profile][2] = (uint8_t )Temp;// dac 播放速度
	profile[sq_profile][1] = (uint8_t )(Temp>>8);
	profile[sq_profile][0] = 0x00;
	Txprofile_cfg(sq_profile);

	Txramdata((uint8_t*)ramdata_Square,RamAddrEnd*4); // 发送波形文件

	cfr1[0] = 0xc0;                                    //RAM 使能,幅度控制
	Txcfr(0x1);                                               //发送cfrx控制字	
}

//产生锯齿波的程序=====================================
void Sawtooth_wave(uint32_t  Sample_interval)
{
	int8_t	sa_profile   =3;
	cfr1[0] = 0x00;//根据pdf描述先,disable RAM mode
	Txcfr(0x1);
	
	uint32_t  Temp = ((1000000000/(unsigned long int)(Sample_interval)/64/4));      
	//1GHz/4, 采样间隔范围:4*(1~65536)ns
	if(Temp > 0xffff)
			Temp = 0xffff;
	profile[sa_profile][7] = (1<<5)|(4<<0);// 连续循环模式
	profile[sa_profile][6] = 0x00;
	profile[sa_profile][5] = 0x00;

	uint16_t RamAddrEnd =63; //ram 播放点数
	profile[sa_profile][4] = (RamAddrEnd<<6)&0xff;
	profile[sa_profile][3] = (RamAddrEnd>>2)&0xff;
	profile[sa_profile][2] = (uint8_t )Temp;
	profile[sa_profile][1] = (uint8_t )(Temp>>8);
	profile[sa_profile][0] = 0x00;
	Txprofile_cfg(sa_profile);	

	Txramdata((uint8_t*)ramdata_Sawtooth,RamAddrEnd*4);//发送波形文件

	cfr1[0] = 0xc0;                                    //RAM 使能,幅度控制
	Txcfr(0x1);                                               //发送cfrx控制字	
}
//方波输出
// 输出频率 =1Ghz/4/点数{1-1024}/播放速度{1-65535}
// => 250Mhz /点数{1-1024}/播放速度{1-65535}
// 生成原则: {保证点数,最快播放速度}
//uint32_t  Freq : 0-20000000
//uint16_t amplitude: 0-16383
//uint16_t phase:  = 度数*65535 /360 
//int16_t DutyCycle : %1-1000% : {1-1000}
void Square_waveCalc(uint32_t  Freq,uint16_t amplitude,uint16_t phase,int16_t DutyCycle){

	int8_t	sa_profile   =2;
	uint32_t wavebuf[1024]={0};
	cfr1[0] = 0x00;//根据pdf描述先,disable RAM mode
	Txcfr(0x1);

	uint16_t StepRate =1;//range:1-65535 
	uint32_t  DacPoint = 250000000L/Freq;      
	if(DacPoint > 1024){// DAC 采样点数
		StepRate =DacPoint/1024;// 播放速度
		DacPoint =1024;
	}
	//计算占空比
	uint16_t HalfDacPoint =DacPoint*DutyCycle/1000;
	//计算相位
	uint32_t phaseIndex =phase*360/65535;
	phaseIndex =DacPoint*phaseIndex/360;
	if(phaseIndex)phaseIndex--;
	uint16_t i;
	for(i=0;i<DacPoint;i++){// 根据点数计算波形周期
		RAM_WAVE[i]=(i<HalfDacPoint)? (uint32_t)amplitude<<18:0; //高低电平模式,幅度可变
	}

	if(phaseIndex>0){ //根据相位移动缓存数据
		memcpy(wavebuf,RAM_WAVE,phaseIndex*4);
		memcpy(RAM_WAVE,&RAM_WAVE[phaseIndex],(DacPoint-phaseIndex)*4);
		memcpy(&RAM_WAVE[DacPoint-phaseIndex],wavebuf,phaseIndex*4);
	}

	profile[sa_profile][7] = (1<<5)|(4<<0);// 连续循环模式
	profile[sa_profile][6] = 0x00;
	profile[sa_profile][5] = 0x00;
	profile[sa_profile][4] = (DacPoint<<6)&0xff;
	profile[sa_profile][3] = (DacPoint>>2)&0xff;
	profile[sa_profile][2] = (uint8_t )StepRate; //播放速度
	profile[sa_profile][1] = (uint8_t )(StepRate>>8);
	profile[sa_profile][0] = 0x00;
	Txprofile_cfg(sa_profile);	

	Txramdata32(RAM_WAVE,DacPoint);//发送波形文件

	cfr1[0] = 0xc0;//RAM 使能,幅度控制
	cfr1[1] = 0x00;//反sin 滤波器关闭
	cfr1[3] =0x02;//

	cfr2[0] =0x01;// enable profile x
	cfr2[1] =(1<<6);// enable SYNC_CLK out
	cfr2[2] =(1<<3);// enable PDCLK  out
	cfr2[3] =0;// disable parallel I mode

	cfr3[0] =0x05;//PLL =1Ghz
	cfr3[2] =0x41;// PLL enable
	Txcfr(0x7);//发送cfrx控制字		
}
// 锯齿波
// 输出频率 =1Ghz/4/点数{1-1024}/播放速度{1-65535}
// => 250Mhz /点数{1-1024}/播放速度{1-65535}
// 生成原则: {保证点数,最快播放速度}
//uint32_t  Freq : 0-20000000
//uint16_t amplitude: 0-16383
//uint16_t phase:  = 度数*65535 /360 
void Sawtooth_waveCalc(uint32_t  Freq,uint16_t amplitude,uint16_t phase){
	int8_t	sa_profile   =3;
	uint32_t wavebuf[1024]={0};
	cfr1[0] = 0x00;//根据pdf描述先,disable RAM mode
	Txcfr(0x1);

	uint16_t StepRate =1;//range:1-65535 
	uint32_t  DacPoint = 250000000L/Freq;      
	if(DacPoint > 1024){// DAC 采样点数
		StepRate =DacPoint/1024;// 播放速度
		DacPoint =1024;
	}
	uint16_t HalfDacPoint =DacPoint>>1;
	//计算相位
	uint32_t phaseIndex =phase*360/65535;
	phaseIndex =DacPoint*phaseIndex/360;
	if(phaseIndex)phaseIndex--;
	uint16_t i,j=0;
	uint32_t tempval =0;
	if(DacPoint&1){//奇数点数时正常对称显示
		j = amplitude /HalfDacPoint; //得到单斜率点数间隔
		for(i=0;i<HalfDacPoint+1;i++){//up
			tempval =i*j;
			RAM_WAVE[i] =tempval<<18;
		}
		for(j=0;j<HalfDacPoint;j++,i++){//down
			tempval=RAM_WAVE[HalfDacPoint-j-1];
			RAM_WAVE[i] =tempval<<18;
		}
	}else{//偶数点,上升比下降多一个点
		j = amplitude /(HalfDacPoint+1); //得到单斜率点数间隔
		for(i=0;i<HalfDacPoint+1;i++){//UP
			tempval =i*j;
			RAM_WAVE[i] =tempval<<18;
		}
		j = amplitude /(HalfDacPoint-1); //得到单斜率点数间隔
		for(i=0;i<HalfDacPoint-1;i++){//DOWN
			tempval =(HalfDacPoint-i-1)*j;
			RAM_WAVE[i+HalfDacPoint+1] =tempval<<18;
		}
	}
	if(phaseIndex>0){ //根据相位移动缓存数据
		memcpy(wavebuf,RAM_WAVE,phaseIndex*4);
		memcpy(RAM_WAVE,&RAM_WAVE[phaseIndex],(DacPoint-phaseIndex)*4);
		memcpy(&RAM_WAVE[DacPoint-phaseIndex],wavebuf,phaseIndex*4);
	}

	profile[sa_profile][7] = (1<<5)|(4<<0);// 连续循环模式
	profile[sa_profile][6] = 0x00;
	profile[sa_profile][5] = 0x00;
	profile[sa_profile][4] = (DacPoint<<6)&0xff;
	profile[sa_profile][3] = (DacPoint>>2)&0xff;
	profile[sa_profile][2] = (uint8_t )StepRate; //播放速度
	profile[sa_profile][1] = (uint8_t )(StepRate>>8);
	profile[sa_profile][0] = 0x00;
	Txprofile_cfg(sa_profile);	

	Txramdata32(RAM_WAVE,DacPoint);//发送波形文件

	cfr1[0] = 0xc0;//RAM 使能,幅度控制
	cfr1[1] = 0x40;//反sin 滤波器on
	cfr1[3] =0x02;//

	cfr2[0] =0x01;// enable profile x
	cfr2[1] =(1<<6);// enable SYNC_CLK out
	cfr2[2] =(1<<3);// enable PDCLK  out
	cfr2[3] =0;// disable parallel I mode

	cfr3[0] =0x05;//PLL =1Ghz
	cfr3[2] =0x41;// PLL enable
	Txcfr(0x7);//发送cfrx控制字	

}

// 使能16bit 外部总线发送数据
void Parallel_wave(uint16_t length){
	if(length){

		cfr1[0] =0;// disable RAM mode
		cfr1[1] = 0x00;//反sin 滤波器off
		cfr1[3] =0x02;//
		cfr2[0] =0;// disable profile x
		cfr2[1] =(1<<6);// enable SYNC_CLK out
		cfr2[2] =(1<<3);// enable PDCLK  out
		cfr2[3] =(1<<4);// enable parallel I mode

		cfr3[0] = 0x07;//PLL 被旁路
		cfr3[2] =0x40;// PLL disable
		Txcfr(0x7);
		delay_ms(10);

	int8_t sa_profile =0;
		// 清空 配置
		profile[sa_profile][7] = 0x00;
		profile[sa_profile][6] = 0x00;
		profile[sa_profile][5] = 0x00;
		profile[sa_profile][4] = 0x00;
		profile[sa_profile][3] = 0x00;
		profile[sa_profile][2] = 0x00;
		profile[sa_profile][1] = 0x00;
		profile[sa_profile][0] = 0x00;
		Txprofile_cfg(sa_profile);	

		MYDMA_Enable(DMA2_Stream1,length);//start dma
		TIM1->CR1=0x1;// enable TIM1	
	}else{
		TIM1->CR1=0;
		Disable_DMA(DMA2_Stream1);
	}
}

#ifndef __AD9910_H
#define __AD9910_H

#include <stdint.h>
#include <stdlib.h>
#include <stdint.h>
#include "sys.h"
#include <spi.h>


#define  	DDS_OSK				PBout(9)
#define		AD9910_PWR		PCout(12) //
#define		PROFILE2			PBout(7)
#define		PROFILE1			PBout(6)
#define		PROFILE0			PBout(5)

#define		DRCTL					PBout(4)
#define		DRHOLD				PBout(3)
#define		UP_DAT				PCout(13)

#define		MAS_REST			PBout(8)
#define		CS						PGout(10)

void AD9110_IOInit(void);
void Init_ad9910(void);
void Freq_convert(uint32_t  Freq,uint16_t amplitude,uint16_t phase);           //写频率
void Amp_convert(unsigned int Amplitude); //写幅度
void Txcfr(int8_t);
extern void IoProfileUpdate(int8_t x);
void Square_wave(uint32_t Sample_interval);                                                   //方波;
void Sawtooth_wave(uint32_t Sample_interval);                                                 //三角波
void SweepFre(uint32_t SweepMinFre, uint32_t SweepMaxFre, uint32_t SweepStepFre, uint32_t SweepTime); //扫频

extern void Square_waveCalc(uint32_t  Freq,uint16_t amplitude,uint16_t phase,int16_t DutyCycle);
extern void Sawtooth_waveCalc(uint32_t  Freq,uint16_t amplitude,uint16_t phase);

extern volatile uint16_t ParallelTbl[25000];
extern void Parallel_wave(uint16_t length);
#endif

使用方法:

uint32_t freqSet =1000000;//1Mhz
uint16_t amplitude =0x3fff;//14bit
uint16_t phase =0xffff;//
uint16_t SampleRate =20000;
int16_t DutyCycle = 500;//50.0%

int8_t ModeSetType =0;
uint16_t parallelLength =360;

void makeOut(void){
	switch(ModeSetType){
		case 0://sine
			Parallel_wave(0);
			Freq_convert(freqSet,amplitude,phase);
		break;
		case 1://square
			// Square_wave(SampleRate);
			Parallel_wave(0);
			Square_waveCalc(freqSet,amplitude,phase,DutyCycle);
		break;
		case 2://Triangular
			// Sawtooth_wave(SampleRate);
			Parallel_wave(0);
			Sawtooth_waveCalc(freqSet,amplitude,phase);
		break;
		case 3:// parallel data port
			Parallel_wave(parallelLength);//
		break;
		default:break;
	}
}

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值