DAC+DMA(1k-25k)任意正弦波输出

2019-07-21 00:41发布

  经过一天不懈的努力,终于搞出来了,本人用TIME4触发DAC实现DMA传输产生正弦波(100点),经测试误差1HZ,主要代码如下:
void DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
 u32 DR_Base;  //做缓冲用,不知道为什么.非要不可
 RCC->AHBENR|=1<<1;//开启DMA2时钟
 __nop();                    //等待 DMA1 时钟稳定
    __nop();                    //经测试最少 2 个 nop
    __nop(); 
 DR_Base=cpar;
 DMA_CHx->CPAR=DR_Base;   //DMA1 外设地址
 DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址
 DMA1_MEM_LEN=cndtr;      //保存DMA传输数据量
 DMA_CHx->CNDTR=cndtr;    //DMA1,传输数据量
 DMA_CHx->CCR=0X00000000;//复位
 DMA_CHx->CCR|=1<<4;  //从存储器读
 DMA_CHx->CCR|=1<<5;  //循环模式
 DMA_CHx->CCR|=0<<6;  //外设地址非增量模式
 DMA_CHx->CCR|=1<<7;  //存储器增量模式
 DMA_CHx->CCR|=1<<8;  //外设数据宽度为16位
 DMA_CHx->CCR|=1<<10; //存储器数据宽度16位
 DMA_CHx->CCR|=1<<12; //中等优先级
 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式 
 
 DMA_CHx->CCR|=1<<1;  //允许完成中断
// DMA_CHx->CCR|=1<<2;  //允许半完成中断
 DMA_CHx->CCR|=1<<0;  //开启DMA传输
 
 MY_NVIC_Init(1,3,DMA2_Channel3_IRQChannel,2);
// MYDMA2_Enable(DMA2_Channel3);    
}
//开启一次DMA传输
void DMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
 DMA_CHx->CCR&=~(1<<0);       //关闭DMA传输
 DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量
 DMA_CHx->CCR|=1<<0;          //开启DMA传输


void Dac1_Init(void)
{
 RCC->APB2ENR|=1<<2;    //使能PORTA时钟    
 RCC->APB1ENR|=1<<29;   //使能DAC时钟    
     
 GPIOA->CRL&=0XFF00FFFF;
 GPIOA->CRL|=0X00000000;//PA4 PA5模拟输入      DAC->CR|=1<<0; //使能DAC1
 DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=1
 DAC->CR|=1<<2; //使用触发功能 TEN1=0
 DAC->CR|=5<<3; //(0101)DAC TIM6 TRGO,不过要TEN1=1才行
 DAC->CR|=0<<6; //不使用波形发生
 DAC->CR|=0<<8; //屏蔽、幅值设置
 DAC->CR|=1<<12; //DAC1 DMA使能  DAC->DHR12R1=0;
 DAC->DHR12R2=0;
}
void Timerx_Init(u16 arr,u16 psc)
{
 RCC->APB1ENR|=1<<2;//TIM4时钟使能  
 __nop();
 __nop();
  TIM4->ARR=arr;  //设定计数器自动重装值//刚好1ms   
 TIM4->SC=psc;  //预分频器7200,得到10Khz的计数时钟
 //TIM2->CR1=0x8000; //ARPE使能 
 TIM4->CR2|=3<<4;    //比较脉冲 (必须要)
 //TIM2->CR1|=1<<2;         
 TIM4->CR1|=0x01;    //使能定时器2    
}
while(1)
{         DMA_Config(DMA2_Channel3,(u32)&DAC->DHR12R1,(u32)Sine12bit,100); 
       DMA_Enable(DMA2_Channel3);
     Dac1_Init();
     f = 800; 
     Timerx_Init(720000/f,0);

}
f表示频率,PA4输出  
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
34条回答
sweetstandard
1楼-- · 2019-07-25 04:26
本帖最后由 sweetstandard 于 2017-3-22 09:32 编辑

谢谢,问题已经解决。之前是误解了“双DAC"的含义,以为”双DAC“是使用两个独立的DAC呢,其实”双DAC“是同时触发两个DAC。之后,我用了单独两个DAC,问题就解决了。
具体程序如下,希望有朋友能借鉴到。

#include "dac.h"
#include "dma.h"
//-------------------DAC 通道 1 输出初始化-------------------------------------
void Dac1_Init(void)
{
  
        GPIO_InitTypeDef GPIO_InitStructure;
        DAC_InitTypeDef DAC_InitType;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );//使能PORTA通道时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );        //使能DAC通道时钟

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                                      // 端口配置 PA-4
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                     //模拟输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA,GPIO_Pin_4)        ;                     //PA.4 输出高

        DAC_InitType.DAC_Trigger=DAC_Trigger_T6_TRGO;        //使用触发功能 TEN1=1
        DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
        DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
        DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;//DAC1输出缓存关闭 BOFF1=1

        DAC_Init(DAC_Channel_1,&DAC_InitType);  //初始化DAC通道1
        DAC_Cmd(DAC_Channel_1, ENABLE);         //使能DAC1
        DAC_SetChannel1Data(DAC_Align_12b_R, 0);//12位右对齐数据格式设置DAC值
        
       MY_DAC1_DMA_Config();        
        
}
//-------------------DAC 通道 2 输出初始化-------------------------------------
void Dac2_Init(void)
{
  
        GPIO_InitTypeDef GPIO_InitStructure;
        DAC_InitTypeDef DAC_InitType;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );//使能PORTA通道时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );  //使能DAC通道时钟

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                      // 端口配置 PA-5
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                     //模拟输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA,GPIO_Pin_5)        ;                     //PA.5 输出高
        
        DAC_InitType.DAC_Trigger=DAC_Trigger_T7_TRGO;        //使用触发功能 TEN1=1
        DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
        DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
        DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;        //Dac2输出缓存关闭 BOFF1=1

        DAC_Init(DAC_Channel_2,&DAC_InitType);  //初始化DAC通道2
        DAC_Cmd(DAC_Channel_2, ENABLE);         //使能Dac2
        DAC_SetChannel2Data(DAC_Align_12b_R, 0);//12位右对齐数据格式设置DAC值
        
        MY_DAC2_DMA_Config();               
}
llsjing
2楼-- · 2019-07-25 09:23
void Timerx_Init(u16 arr,u16 psc)
请问定时器溢出周期与正弦波形周期有什么关系啊?定时器溢出周期是DAC输出一个点的时间,还是DAC输出100个点的时间啊?
zlfeng007
3楼-- · 2019-07-25 10:26

请问你输出正弦波的频率调整精度是多少,可以每次调整1HZ吗?
FQJ
4楼-- · 2019-07-25 14:58
好东西

一周热门 更多>