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); //開啓定時器
}