用TIMER+DMA+DAC写的一个简单DDS,能输出幅值频率可变的正弦波、三角波和锯齿波

2019-07-20 06:36发布

代码如下,小伙伴们也可以增加波形的类型,使其输出更多的波形
[mw_shl_code=c,true]#include "dac.h" #include <math.h> #define MAXWAVECNT 200 #define WAVECNT 100 //波形的阶数,阶数越大波形拟真度越高,频率会越低 u16 wavedatatab[MAXWAVECNT] = {0}; //存储任意的波形数据 /*自定义波形数据生成 Amp为幅值 0~3.3V offset为偏置 值0~3.3V wavetype为波形类型: 0为正弦波 1为三角波 2为锯齿波 */ void GEN_WAVE(float Amp,float offset,u8 wavetype) { u16 tempAmp = Amp*4096/3.3; u16 tempoffset = offset*4096/3.3; u8 i; u16 step; switch(wavetype) { case 0: for(i=0 ;i<WAVECNT;i++) { wavedatatab = (u16)( tempAmp*sin(2*3.14*i/WAVECNT)+tempoffset); } break; case 1: step = tempAmp/(WAVECNT/2); for(i=0 ;i<WAVECNT;i++) { if(i<(WAVECNT/2)) wavedatatab= i*step+tempoffset; else wavedatatab = (WAVECNT-i)*step+tempoffset; } break; case 2: step = tempAmp/WAVECNT; for(i=0 ;i<WAVECNT;i++) { wavedatatab= i*step+tempoffset; } break; default:break; } } void TIM2_Int_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<0; //TIM2时钟使能 TIM2->ARR=arr; //设定计数器自动重装值 TIM2->SC=psc; //预分频器 TIM2->CR1|=1<<7; //ARPE使能 TIM2->CR2 |=0x2<<4; //TIMER更新做为TRGO源 TIM2->CR1 |=TIM_CR1_CEN; //使能定时器2 } void DAC_DMA_init(void) { RCC->AHB1ENR|=1<<21;//DMA1时钟使能 DMA1_Stream5->AR=(u32)&(DAC->DHR12R1); //DMA外设地址 DMA1_Stream5->M0AR=(u32)wavedatatab; //DMA 存储器0地址 DMA1_Stream5->NDTR=WAVECNT; //DMA 传输数量 DMA1_Stream5->CR=0; //先全部复位CR寄存器值 DMA1_Stream5->CR|=1<<6; //存储器到外设模式 DMA1_Stream5->CR|=1<<8; //循环模式 DMA1_Stream5->CR|=0<<9; //外设非增量模式 DMA1_Stream5->CR|=1<<10; //存储器增量模式 DMA1_Stream5->CR|=1<<11; //外设数据长度:16位 DMA1_Stream5->CR|=1<<13; //存储器数据长度:16位 DMA1_Stream5->CR|=1<<16; //中等优先级 DMA1_Stream5->CR|=0<<21; //外设突发单次传输 DMA1_Stream5->CR|=0<<23; //存储器突发单次传输 DMA1_Stream5->CR|= 0x7<<25;//通道选择 DMA1_Stream5->CR|= 1<< 0;//开DMA } //DDS初始化 void Dac1_Init(void) { RCC->APB1ENR|=1<<29; //使能DAC时钟 RCC->AHB1ENR|=1<<0; //使能PORTA时钟 GPIO_Set(GPIOA,PIN4,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA4,模拟输入,下拉 DAC->CR|=1<<0; //使能DAC1 DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=1 DAC->CR|=1<<2; //使用触发功能 TEN1=1 DAC->CR|=4<<3; //DAC TIM2 TRGO,不过要TEN1=1才行 DAC->CR|=0<<6; //不使用波形发生 DAC->CR|=0<<8; //屏蔽、幅值设置 DAC->CR|=1<<12; //DAC1 DMA使能 DAC->DHR12R1=0; DAC_DMA_init(); TIM2_Int_Init(100,0); } void SET_DAC_FRQ(u16 frq) { TIM2->CR1 &=~TIM_CR1_CEN; TIM2->ARR = frq; TIM2->CR1 |=TIM_CR1_CEN; } void DDS_Output_Wave(float Amp,float offset,u8 wavetype,u16 frq) { DMA1_Stream5->CR&= ~(1<< 0);//关DMA GEN_WAVE(Amp,offset,wavetype); SET_DAC_FRQ(frq); DMA1_Stream5->CR|= (1<< 0);//关DMA } [/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。