经过一天不懈的努力,终于搞出来了,本人用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输出
一周热门 更多>