经过一天不懈的努力,终于搞出来了,本人用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输出
谢谢,问题已经解决。之前是误解了“双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();
}
请问定时器溢出周期与正弦波形周期有什么关系啊?定时器溢出周期是DAC输出一个点的时间,还是DAC输出100个点的时间啊?
请问你输出正弦波的频率调整精度是多少,可以每次调整1HZ吗?
一周热门 更多>