文档章节

DAC

青春无极限
 青春无极限
发布于 2016/03/25 11:39
字数 1068
阅读 50
收藏 1

 国电临近,总结一下之前写过的一些程序和电路。时间不多,只能抽空写了,等闲的时候再一并写好,以飨读者。

       STM32F103VCT6自带两个12DACDAC的转换速度一直没有查到,网上有人说是1MHZ的频率,那就是1us了。ADC的转换时间在56MHZ工作频率下为1us,在72MHZ工作频率下为1.17us。如果ADDA有对称关系的话,那么很可能跟ADC的时间相同。(仅作分析用!)

       DAC于我,有两个用途:输出波形输出固定电压。先来说说前者的配置。

       第一个参数:触发方式,DAC_InitStructure.DAC_Trigger。可选的外部触发源一共有八个。六个是定时器触发:TIM2TIM4TIM5TIM6TIM7TIM8。剩下两个分别是:EXTI线路9和软件触发。如果采用定时器触发的话,就还要再编写相应的定时器函数,这个倒不是很复杂,和定时器的编写方式类似。如:DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;//选择定时器6作外部触发源

 

void TIM_Configuration(void)

{

       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

       TIM_OCInitTypeDef            TIM_OCInitStructure;

 

      

       TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

      TIM_TimeBaseStructure.TIM_Period = 0x85;         

      TIM_TimeBaseStructure.TIM_Prescaler = 0x0;      

      TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   

      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

      TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);     

      

    TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);

}

输出信号频率计算:假设输出一个6个点的锯齿波波形,则其频率为:(72MHZ/(0x85+1))*6=89.552KHZ.注意:如果prescaler不为0,则时钟还要再除以(prescaler+1)

       第二个参数:DAC_InitStructure.DAC_WaveGeneration。顾名思义:波形发生器。STM32内部集成了两个幅度可调的波形发生器,可以产生三角波噪声波。如果我们使用自定义的缓冲区的话,就不需要配置这个参数或者使其为DAC_WaveGeneration_None,但为了避免别人误以为你忘了配置这个参数,所以还是多写一句吧,养成好的习惯。

       第三个参数:DAC_InitStructure.DAC_OutputBuffer,即是否使用输出缓存。输出缓存的功能主要用来减小输出阻抗,是STM32DAC无需外部运放就可以直接驱动负载。这里一般设置成DAC_OutputBuffer_Disable,即关闭外部缓存。这是为保险起见,万一驱动能力不够强(本人也没试过@_ @),那调试的时间就又多了一些。

       参数的配置就这么多了,算得上STM32中最简单的外设配置之一了!

       一般来说,用DAC输出波形,传输的数据比较多,所以采用DMA传输可以节省CPU的开支。所以在调用DAC_DMACmd(DAC_Channel_1, ENABLE);函数后别忘了配置DMA函数。详细的配置说明就不写了,这里把代码贴出来:

 

void DMA_Configuration(void)

{

       DMA_InitTypeDef            DMA_InitStructure;

      

       DMA_DeInit(DMA2_Channel3);

       DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_Address;

       DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&FIR_OutPutValueTab;

       DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

       DMA_InitStructure.DMA_BufferSize = 200;

       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_Mode = DMA_Mode_Circular;

       DMA_InitStructure.DMA_Priority = DMA_Priority_High;

       DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

       DMA_Init(DMA2_Channel3, &DMA_InitStructure);

 

      

       DMA_Cmd(DMA2_Channel3, ENABLE);

      

       DMA_ITConfig(DMA2_Channel3,DMA_IT_TC,ENABLE);

}

注意红色字体写的那行代码,当我们传输多个数据时,需要将其设置为连续转换!其余就不赘述了。

       接下来谈谈DAC固定电压的配置。

       STM32DAC固定电压配置和上面的波形输出配置相似,不同的地方在于它要多调用一个函数:DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);这样才会输出固定的电平。

具体配置如下:

 

void DAC_VOLTAGE_Configuration(void)

{

       DAC_InitTypeDef            DAC_InitStructure;

       DAC_DeInit();

      

      DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;

      DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;      

      DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

      DAC_Init(DAC_Channel_1, &DAC_InitStructure);

       //

      

       DAC_Cmd(DAC_Channel_1, ENABLE);

       DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);

}

配置完成后,调用DAC_SetChannel1Data(DAC_Align_12b_R,4000);函数就可以发送数据了!!极其方便。比起5615,0832之流不知简便了多少!有两点要注意:1、该函数的第一个参数DAC_Align_12b_R不可依据设置ADC外设地址的方式重写这个地址,因为这个参数是不带基址的,而我们重写地址后一半会把基址算进去,这样就不对了!(笔者就曾经卡在这里!看来凡事不可先入为主,否则问题迟早会发生。)2、每次改变发送数据时,要同时调用以下两个函数:

       DAC_SetChannel1Data(DAC_Align_12b_R,4000);

       DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);

至于为什么,我的理解是:因为DAC改变数据后并不会立即写入寄存器,需要一次更新,由于不是通过定时器触发来更新,因此就只能通过调用函数的方法来更新。


© 著作权归作者所有

青春无极限
粉丝 2
博文 129
码字总数 71498
作品 0
卢湾
程序员
私信 提问
加载中

评论(1)

Hu-San
Hu-San
非常感谢
DMA+DAC+TIMER输出正弦波 自己验证

define PI 3.1415 u16 DAC_Channel1WaveValue[256]; // 用函数封装/********************************************************** // 函数名称: void Sine_WaveData(u16 cycle ,u16 *D) // ......

zn2016
2018/03/09
0
0
EOS DAC:别只知道空投了,这才是真正的我!

关注 EOS DAC 寻找志同道合的伙伴 别看现在每天在EOS上发生的空投,就像是繁忙的国际航班线路一样不计其数。 但就在一年前,主网还未正式上线的时候,EOS空投还是一个非常时髦的概念。 在这样...

eosDAC
07/17
0
0
mongodb 数组内容匹配删除方法, $all 用法

文档如下 相册 需求 删除多张照片 假设删除 "573ac80afb5f892dac0063e6", "573ac80afb5f892dac0063e7" 这两个 同时 pictureSize -2为了保证删除内容必须匹配 且 要么此操作都成功 要么都失败......

筱龙缘
2016/07/14
133
0
DAC Factory好用吗?不试试怎么知道…

关注 EOS DAC 寻找志同道合的伙伴 实践是检验真理的唯一标准,这句话我们不仅在中学课本上学过,更在生活的方方面面体验过。 东西好不好,实践过才知道。 比如,中国改革开放初期选择深圳作为...

eosDAC
07/26
0
0
什么高速线缆DAC?有了有源光缆AOC为何还选择DAC?

有源光缆大家听多了,,不知道大家知不知道高速线缆DAC? 在数据中心和互联数据高速发展的时代,DAC凭借其出色的简便性与价格优势极大地扩张其市场,在IDC市场方面更是占领了极大份额。 什么...

专说光通讯
2017/12/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis Plus删除

/** @author beth @data 2019-10-17 00:30 */ @RunWith(SpringRunner.class) @SpringBootTest public class DeleteTest { @Autowired private UserInfoMapper userInfoMapper; /** 根据id删除......

一个yuanbeth
今天
4
0
总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
今天
4
0
java内存模型

前言 Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模...

ls_cherish
今天
4
0
友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部