附加:
搞了一天都只有第一个转换的数据是正确,最后发现是红色部分有问题(原本2个数据位一样就会出错),修改就没事了。。。不过发现网上好多人都那样写也没事。我也是无语了。
DMA 方式 DAC(PA4)转换 :
代码如下:
#include <dac.h>
#include <stm32f4xx_dac.h>
u32 data_dac;
void Dac_DMA(void){
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Stream5); //复位
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); //开启外设时钟
DMA_InitStructure.DMA_Channel = DMA_Channel_7 ; //设置DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&(DAC->DHR12R1); //DHR12R1的地址
DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)&data_dac ; //数据内存的地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //读取数据的模式是从外设到内存
DMA_InitStructure.DMA_BufferSize = 1; //有 1个转换通道, 采集1次
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址不变
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //数据宽度为 32 位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //数据宽度为 32 位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; //循环转换
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA的优先级别
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable ;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; //内存地址不加
DMA_InitStructure.DMA_PeripheralBurst = 0 ; //外设内存不加
DMA_Init(DMA1_Stream5, &DMA_InitStructure); //配置
DMA_Cmd(DMA1_Stream5, ENABLE); //使能 DMA
}
void Dac_Init(void){
GPIO_InitTypeDef GPIO_InitTStruct;
DAC_InitTypeDef DAC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitTStruct.GPIO_Mode=GPIO_Mode_AN; // 模拟输入 会映射成到DA
GPIO_InitTStruct.GPIO_Pin=GPIO_Pin_4;
GPIO_InitTStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
GPIO_Init(GPIOA,&GPIO_InitTStruct);
DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;// 不用波形发生器
DAC_InitStruct.DAC_WaveGeneration=DAC_WaveGeneration_None;
DAC_InitStruct.DAC_OutputBuffer=DAC_OutputBuffer_Disable; //使用设置缓冲
DAC_InitStruct.DAC_Trigger=DAC_Trigger_T2_TRGO; // 定时器2 TRGO模式
DAC_Init(DAC_Channel_1,&DAC_InitStruct);
Dac_DMA(); // DMA 配置
DAC_Cmd(DAC_Channel_1,ENABLE); // 使能 DA1 方式
DAC_DMACmd(DAC_Channel_1,ENABLE); // 使能 DA1 DMA方式
}
void INIT_timer2(void)
{
TIM_TimeBaseInitTypeDef TIM_Typetim2;
NVIC_InitTypeDef NVIC_InitTIM2;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_Typetim2.TIM_CounterMode=TIM_CounterMode_Up;
TIM_Typetim2.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_Typetim2.TIM_Prescaler=8400;
TIM_Typetim2.TIM_Period=50;
TIM_TimeBaseInit(TIM2,&TIM_Typetim2);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
NVIC_InitTIM2.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitTIM2.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitTIM2.NVIC_IRQChannelPreemptionPriority=0x02;
NVIC_InitTIM2.NVIC_IRQChannelSubPriority=0x02;
NVIC_Init(&NVIC_InitTIM2);
TIM_Cmd(TIM2,ENABLE);
TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update); //选择更新事件作为触发输出 (TRGO)。
}
附加 : DAC的DMA 方式 好像不能那个用 DAC-CR2里TSEL1[2:0]的软件触发 (我弄了好久都搞不好,原子哥见到请帮忙指点下是不是上图已说明不能用软件触发) ,最后改成 定时器2TRGO
事件,所以要加红色那一段。!!! 在主程序给 data_dac赋值就OK了!~