说明DAC-DMA只能使用外部触发,即决定了DAC必须外部触发,其它软件触发或无触发是不行的,这也是本人亲测
代码设计:
1.IO口初始化
2.ADC初始化
3.DMA初始化
注意事项说明:
1.DAC触发源选择:
DAC_InitType.DAC_Trigger=DAC_Trigger_T8_TRGO;
大多触发模式是和定时器相关的,注意这里没有定时器1
TIM_SelectOutputTrigger(TIM8,TIM_TRGOSource_OC1Ref);//选择触发源
这一句是选择触发源,选项如下:
触发源: 复位、使能,更新,输出比较OC
关于_OC1和_OC1Ref区别,实际测试中未发现二者功能不同;而且_OC1就是参考_OC1Ref来输出的,当然还有更复杂的关系,请看数据手册
2.外设地址说明:
这里使用2种方式:
#define DAC1_DR (DAC_BASE+0x08)//宏定义
或者使用结构体定义的寄存器方式
DMA_InitStre.DMA_PeripheralBaseAddr=(uint32_t)&(DAC->DHR12R1);//外设 DAC1_DR
3.输出缓冲说明
这是什么意思呢,缓冲降低输出阻抗,这样就可以提供加大的驱动电流,但是实际设计时为了降低STM32功耗,增加系统稳定性,不会让其直接驱动负载,会在外部加入运放,比如恒流源电路中
另外请看数据手册中,如下
一旦开启缓冲,DAC输出不了0V,而是最低0.2V,类似于有输入失调电压的运放,有的设计中是不行的;另外这会影响DAC输出的线性度,一般外部负载电路是高输入阻抗,理论设计和实际输出不是线性的
所以实际应用中,一般不使用输出缓冲
代码如下:
/******************************************************************************
* 功能:
*
******************************************************************************/
void DAC_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//下拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
}
/******************************************************************************
* 功能:
*
******************************************************************************/
void DAC_Mode_Init(void)
{
DAC_InitTypeDef DAC_InitType;
DMA_InitTypeDef DMA_InitStre;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);//DMA时钟
/************************* 通道1 ***************************/
//使用DMA模式-寄存器到外设
DAC_InitType.DAC_Trigger=DAC_Trigger_T8_TRGO; //必须使用触发功能 TEN1=0
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); //使能DAC通道1
TIM_SelectOutputTrigger(TIM8,TIM_TRGOSource_OC1Ref);//选择触发源
//DMA初始化
DMA_DeInit(DMA1_Stream5);//复位
DMA_InitStre.DMA_PeripheralBaseAddr=(uint32_t)&(DAC->DHR12R1);//外设 DAC1_DR
DMA_InitStre.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
DMA_InitStre.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//半字
DMA_InitStre.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址增加失能
DMA_InitStre.DMA_Memory0BaseAddr=(uint32_t)DAC_Data_Table; //内存地址
DMA_InitStre.DMA_MemoryInc=DMA_MemoryInc_Enable;//寄存器(变量)地址增加
DMA_InitStre.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//半字
DMA_InitStre.DMA_MemoryBurst=DMA_MemoryBurst_Single;
DMA_InitStre.DMA_Channel=DMA_Channel_7;
DMA_InitStre.DMA_DIR=DMA_DIR_MemoryToPeripheral;//寄存器到外设输出
DMA_InitStre.DMA_BufferSize=16;//一个输出循环中数据长度
DMA_InitStre.DMA_Mode=DMA_Mode_Circular;//循环发送
DMA_InitStre.DMA_Priority=DMA_Priority_High;
DMA_InitStre.DMA_FIFOMode=DMA_FIFOMode_Disable;
DMA_InitStre.DMA_FIFOThreshold=DMA_FIFOThreshold_1QuarterFull;
DMA_Init(DMA1_Stream5,&DMA_InitStre);//初始化
DMA_Cmd(DMA1_Stream5,ENABLE);//DMA使能
DAC_DMACmd(DAC_Channel_1, ENABLE);//DAC-DMA使能