打印

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

[复制链接]
338|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
王将|  楼主 | 2018-7-6 13:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
代码如下,小伙伴们也可以增加波形的类型,使其输出更多的波形

[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-&gtSC=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-&gtAR=(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]

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

419

主题

419

帖子

0

粉丝