基於STM32的DDS信號發生器

DDS信號發生器採用直接數字頻率合成(Direct Digital Synthesis,簡稱DDS)技術,把信號發生器的頻率穩定度、準確度提高到與基準頻率相同的水平,並且可以在很寬的頻率範圍內進行精細的頻率調節。採用這種方法設計的信號源可工作於調製狀態,可對輸出電平進行調節,也可輸出各種波形。

一個完整週期的函數波形被存儲在上面所示的存儲器查找表中。相位累加器跟蹤輸出函數的電流相位。爲了輸出一個非常低的頻率,採樣樣本之間的差相位(Δ)將非常小。例如,一個很慢的正弦波可能將有1度的Δ相位。則波形的0號採樣樣本採得0度時刻的正弦波的幅度,而波形的1號採樣將採得1度時刻的正弦波的幅度,依次類推。經過360次採樣後,將輸出正弦曲線的全部360度,或者確切地說是一個週期。一個較快的正弦波可能會有10度的Δ相位。於是,36次採樣就會輸出正弦波的一個週期。如果採樣率保持恆定,上述較慢的正弦波的頻率將比較快的正弦波慢10倍。 進一步說,一個恆定的Δ相位必將導致一個恆定正弦波頻率的輸出。但是,DDS技術允許通過一個頻率表迅速地改變信號的Δ相位。函數發生器能夠指定一個頻率表,該表包括由波形頻率和持續時間信息組成的各個段。函數發生器按順序產生每個定義的頻率段。通過生成一個頻率表,可以構建複雜的頻率掃描信號和頻率跳變信號。DDS允許函數發生器的相位從一級到另一級連續變化。 矢量信號發生器提供高靈活度和強大的解決方案,可用於科學研究,通信,消費電子,宇航/國防,半導體測試以及一些新興領域,如軟件無線電,無線電頻率識別( RFID),以及無線傳感網絡等。 有些公司還提供許多其他利用DAC來產生模擬信號的模擬輸出產品。模擬輸出板的基本架構是,將一個小型的FIFO存儲器連接到一個DAC上。絕大部分的模擬輸出板被用來產生靜態電壓,而且許多可以被用來產生低頻波形。

 

STM32內部帶有12位ADC,通過查表的方式輸出各個電壓

#include "sign.h"
u16 SineWave_Value[256]; 

/********正弦波輸出表***********/
//cycle	:波形表的位數	(0~256)
//Um		:輸出電壓的峯值(0~1.5)
/*******************************/
void SineWave_Data( u16 cycle ,u16 *D,float Um)
{
    u16 i;
    for( i=0;i<cycle;i++)
    {
        D[i]=(u16)((Um*sin(( 1.0*i/(cycle-1))*2*PI)+Um)*4095/3.3);
    }
}


/****************初始化引腳******************/
void SineWave_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);  //開時鐘
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推輓輸出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //輸出速率 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 ; //選擇引腳
    GPIO_SetBits(GPIOA,GPIO_Pin_4)  ;   //拉高輸出
    GPIO_Init(GPIOA, &GPIO_InitStructure);      //初始化
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;       //推輓輸出模式 
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //選擇引腳
    GPIO_Init(GPIOD, &GPIO_InitStructure);      //初始化
}

/******************DAC初始化ˉ*************************/
void SineWave_DAC_Config( void)
{
    DAC_InitTypeDef            DAC_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//開DAC時鐘
     
  /**************DAC結構初始化*******************/
    DAC_StructInit(&DAC_InitStructure);    
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;//不產生波形
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //不使能輸出緩存
    DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;//DAC觸發爲定時器2觸發
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);//初始化
    DAC_Cmd(DAC_Channel_1, ENABLE);    //使能DAC的通道1
    //DAC_DMACmd(DAC_Channel_1, ENABLE); //使能DAC通道1的DMA  
}

/*********定時器初始化************/
void SineWave_TIM_Config(u32 Wave1_Fre)
{
    TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//開時鐘
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0;     //不預分頻
    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //不分頻<br>  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數
    TIM_TimeBaseStructure.TIM_Period = Wave1_Fre;//設置輸出頻率
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);//設置TIME輸出觸發爲更新模式
}

/*********DMA配置***********/
void SineWave_DMA_Config(void)
{                  
    DMA_InitTypeDef            DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//開啓DMA2時鐘
     
    DMA_StructInit( &DMA_InitStructure);        //DMA結構體初始化
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//從寄存器讀數據
    DMA_InitStructure.DMA_BufferSize = 256;//寄存器大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不遞增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存地址遞增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//寬度爲半字
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//寬度爲半字
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//優先級非常高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//關閉內存到內存模式
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循環發送模式
	
	DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1;//外設地址爲DAC通道1的地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SineWave_Value;//波形數據表內存地址
	DMA_Init(DMA2_Channel3, &DMA_InitStructure);//初始化
	DMA_Cmd(DMA2_Channel3, ENABLE); //使能DMA通道3      
		
}

/**********正弦波初始化**********************/
//Wave1_Fre:	頻率值(0~60 000)Hz
//Um			 :	電壓峯值(0.0~1.5)V
/*******************************************/

void SineWave_Init(u16 Wave1_Fre,float Um)
{
	u32 f1;
	f1=(u32)(8000000/sizeof(SineWave_Value)*2/Wave1_Fre);//計算頻率
	SineWave_Data(256,SineWave_Value,Um);     //生成輸出正弦波的波形表
	SineWave_GPIO_Config();             //初始化io
	//SineWave_TIM_Config(f1);            //初始化定時器
	SineWave_DAC_Config();              //配置DAC
	//SineWave_DMA_Config();              //配置DMA
	//TIM_Cmd(TIM2, ENABLE);             //開啓定時器
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章