完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
DAC简介 主要特点: + 2个DAC转换器,支持两路输出 + 8位或者12位数字输入,12位需要设置数据对齐方向(左对齐或右对齐) + 允许同步更新 + 生成噪声或者三角波 + 双DAC同时或者分别转换 + 每个通道有DMA功能 + 外部触发转换 + 输入参考电压 简单介绍: DAC整体框图 [tr]名称符号注释[/tr]
DAC数据格式 Stm32 支持8位和12位转换 DAC输出电压=VREF*(DOR/2m) m为8,12 触发方式 触发方式有定时器触发、外部事件触发和软件触发 其中软件触发和无触发时,数据从DHR->DOR仅需1个APB时钟,其他方式均需3个APB时钟 软件触发会自动清零,只需关心何时置‘1’ 噪声 三角波 设置WAVEx[1:0]位为’10’选择DAC的三角波生成功能。设置DAC_CR寄存器的MAMPx[3:0]位来选择三角波的幅度。内部的三角波计数器每次触发事件之后3个APB1时钟周期后累加1。计数器的值与DAC_DHRx寄存器的数值相加并丢弃溢出位后写入DAC_DORx寄存器。在传入DAC_DORx寄存器的数值小于MAMP[3:0]位定义的最大幅度时,三角波计数器逐步累加。一旦达到设置的最大幅度,则计数器开始递减,达到0后再开始累加,周而复始。 将WAVEx[1:0]位置’0’可以复位三角波的生成。 可知:频率需要MAMP、TIM共同改变。 直接输出 直接输出需要配置I/O口,参考手册要求配置成模拟输入 GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//旦使能DACx通道,相应的GPIO引脚就会自动与DAC的模拟输出相连,为了避免寄生的干扰和额外的功耗,引脚PA4/PA5在之前应当设置成“模拟输入” GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); 配置DAC_CRX寄存器,详细函数内容 DAC_InitTypeDef DAC_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE); DAC_InitStruct.DAC_WaveGeneration=DAC_WaveGeneration_None; DAC_InitStruct.DAC_Trigger = DAC_Trigger_None; DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//输出缓存可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载,不稳定不使用 DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0; DAC_Init(DAC_Channel_1,&DAC_InitStruct); DAC_Cmd(DAC_Channek_1,&DAC_InitType); 此时已经配置完毕,调用如下命令设置电压 DAC_SetChannel1DAta(DAC_Align_12b_R,0); 定时器触发 修改DAC_CRX寄存器配置中 DAC_Trigger DAC_InitStruct.DAC_Trigger=DAC_Trigger_T6_TRGO; 配置定时器TIM6的寄存器,具体内容见[TIM介绍] TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_Period = 10 -1; TIM_TimeBaseInitStruct.TIM_Prescaler = 72; TIM_TimeBaseInitStruct.TIM_ClockDivision = 0; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct); TIM_SelectOutputTrigger(TIM6,TIM_TRGOSource_Update); 定时器触发的含义是,当[定时器]更新事件的时候,会将DHR寄存器的内容传递到DOR,然后转换输出,主要配合控制其他功能,如下面的波形输出 外部事件触发 修改DAC_CRX寄存器配置中 DAC_Trigger DAC_InitStruct.DAC_Trigger=DAC_Trigger_T6_TRGO; 配置GPIO GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE,&GPIO_InitStruct); 配置EXTI寄存器,具体内容见[EXTI] EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line9; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStructure); 软件触发 修改DAC_CRX寄存器配置中 DAC_Trigger DAC_InitStruct.DAC_Trigger=DAC_Trigger_Software; 配置完成后,调用如下函数 DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE); 该情况下
三角波 配置DAC_CRX寄存器 DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Triangle; DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO; DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_4095; 配置TIM6即可,也可以通过外部中断或者软件触发 可知:
噪声 配置DAC_CRX寄存器 DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Noise; DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO; DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; 通过设置LFSRUnmask可以屏蔽部分数据 DMA产生正弦波 #include "sign.h" u16 SineWave_Value[256]; /********正弦波输出表***********/ //cycle :波形表的位数 (0~256) //Um :输出电压的峰值(0~1.5) /*******************************/ void SineWave_Data( u16 cycle ,u16 *D,float Um) { u16 i; for( i=0;i { D=(u16)((Um*sin(( 1.0*i/(cycle-1))*2*PI)+Um)*4095/3.3); } } /****************初始化引脚******************/ void SineWave_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开时钟 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出速率 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ; //选择引脚 GPIO_SetBits(GPIOA,GPIO_Pin_4) ; //拉高输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 } /******************DAC初始化ˉ*************************/ void SineWave_DAC_Config( void) { DAC_InitTypeDef DAC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//开DAC时钟 /**************DAC结构初始化*******************/ DAC_StructInit(&DAC_InitStructure); DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;//不产生波形 DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //不使能输出缓存 DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;//DAC触发为定时器2触发 DAC_Init(DAC_Channel_1, &DAC_InitStructure);//初始化 DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC的通道1 DAC_DMACmd(DAC_Channel_1, ENABLE); //使能DAC通道1的DMA } /*********定时器初始化************/ void SineWave_TIM_Config(u32 Wave1_Fre) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开时钟 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0x0; //不预分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数 TIM_TimeBaseStructure.TIM_Period = Wave1_Fre;//设置输出频率 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);//设置TIME输出触发为更新模式 } /*********DMA配置***********/ void SineWave_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//开启DMA2时钟 DMA_StructInit( &DMA_InitStructure); //DMA结构体初始化 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//从寄存器读数据 DMA_InitStructure.DMA_BufferSize = 256;//寄存器大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//宽度为半字 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//宽度为半字 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//优先级非常高 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//关闭内存到内存模式 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循环发送模式 DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1;//外设地址为DAC通道1的地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SineWave_Value;//波形数据表内存地址 DMA_Init(DMA2_Channel3, &DMA_InitStructure);//初始化 DMA_Cmd(DMA2_Channel3, ENABLE); //使能DMA通道3 } /**********正弦波初始化**********************/ //Wave1_Fre: 频率值(0~60 000)Hz //Um : 电压峰值(0.0~1.5)V /*******************************************/ void SineWave_Init(u16 Wave1_Fre,float Um) { u32 f1; f1=(u32)(72000000/sizeof(SineWave_Value)*2/Wave1_Fre); SineWave_Data(256,SineWave_Value,Um); SineWave_GPIO_Config(); SineWave_TIM_Config(f1); SineWave_DAC_Config(); SineWave_DMA_Config(); TIM_Cmd(TIM2, ENABLE); } 双通道函数配置 以上内容随意组合,只需注意初始化各个寄存器 库函数及寄存器 在这里主要列出寄存器和库函数的对应关系,方便经常使用库函数的人查阅手册。 控制寄存器DAC_CR [tr]寄存器位(x=1,2)库函数[/tr]
软件触发寄存器DAC_SWTRIGR [tr]寄存器位(x=1,2)库函数[/tr]
数据保持寄存器DAC_DHR [tr]寄存器位(x=1,2)库函数[/tr]
软件触发寄存器DAC_SWTRIGR [tr]寄存器位(x=1,2)库函数[/tr]
数据保持寄存器DAC_DHR [tr]寄存器位(x=1,2)库函数[/tr]
|
||
|
||
只有小组成员才能发言,加入小组>>
3280 浏览 9 评论
2958 浏览 16 评论
3460 浏览 1 评论
9004 浏览 16 评论
4052 浏览 18 评论
1115浏览 3评论
573浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
571浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2303浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1859浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 12:04 , Processed in 1.221073 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号