智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 2791|回复: 3
打印 上一主题 下一主题

【跟我学OSKinetis】第6课-DAC编程实践

[复制链接]

59

主题

1029

帖子

0

精华

版主

有什么需帮助的?

Rank: 9Rank: 9Rank: 9

积分
15163

热心会员奖章论坛元老奖章优秀会员奖章在线王奖章

威望
11088
贡献
1415
兑换币
1728
注册时间
2011-12-18
在线时间
1330 小时
跳转到指定楼层
1#
发表于 2013-11-4 20:42:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 洋葱圈 于 2013-11-4 20:44 编辑

上节讲了ADC模拟转数字模块,这节趁热打铁,说说DAC数字转模拟模块。ADC和DAC就像一对欢喜冤家,大家可以把这两个模块理解为互逆过程,就像录音机与播音机两个东西,前者负责把模拟量采集进来,后者负责把模拟量输出出去。其实当你会用了这两个模块之后,完全可以自己做一个简单的录音和播音机了。
与ADC的复杂程度不同,DAC模块可以说是非常简单了,不但它本身的寄存器很少,而且你在直接使用固件库编程的时候就更简单了。因此我们就先讲一下的工作模式,了解了工作模式之后再使用固件库编程便是极好的了。


DAC转换原理

K60中的DAC是12位精度的,这个概念与ADC的精度概念一样,就是把参考电压分成2的12次方份,每一份的电压就是它的最小输出精度,因此DAC的输出电压精度就是3.3V/4096=0.00081V。至于内部的转换原理如何,我们可以从官方技术文档中的模块框图看出:

上图是截取的模块框图的上半部分,其中红框内就是实现电压转换的部分,大家可以理解为K60内部通过4096个等值的电阻将参考电压分成了4096分,而MUX则根据蓝框中的值来判断到底选择哪个分压值进行输出。这个蓝框中的值就是大家在编程中设置的输出值,它其实是一个缓冲区,可以配置为不同的模式来输出缓冲区中的值。绿框中的部分是一个缓冲放大器,途中的DACEN是一个寄存器控制位,用来使能DAC工作,DACRFS用来选择参考电压,LPEN用来使能低功耗模式。
至于本框图的下半部分,则是DAC的比较重要也是难点所在,本文中没有示出,大家可以自己到技术文档中感受下,这部分用于控制DAC的硬件触发、缓冲区工作模式选择、中断等等。


DAC工作模式

非缓冲区工作模式

这个“非缓冲区工作模式”一看就是和“缓冲区工作模式”相对应的,如果大家在用固件库初始化DAC时不做任何配置,默认就是非缓冲区工作模式。该模式是DAC最简单的工作模式,因为几乎不用做任何配置,使能DAC后,只要向DAC数据寄存器(DAC[x]_DAT)的第一个缓冲区(DAC[0]_DAT)写入0~4095之间的数值,就可以在DAC输出引脚输出电压。

缓冲区工作模式

既然该模式叫做“缓冲区工作模式”,那么它必然会用到了DAC数据寄存器(DAC[x]_DAT)的所有缓冲区,而不仅仅是第一个缓冲区。那么DAC是如何选择缓冲区中的数据进行输出的呢,原来在缓冲区工作模式下,DAC还分为了3个不同的工作模式。
在学习3中工作模式前,你要了解什么是DAC数据寄存器的缓冲区。DAC输出的模拟电压值是由DAC数据寄存器(DAC[x]_DAT)决定的,它不是一个寄存器,而是一系列缓冲区,x为0~15,即长度为16。DAC可根据触发模式(硬件触发或软件触发)的不同,依次将缓冲区中的值输出出去。至于按照什么顺序输出,就是要看你设置的工作模式了。
在固件库的使用中,如果你要使用缓冲区工作模式,需要配置初始化结构体的变量DAC_BufferEnableTRUE
普通模式
在该模式下,DAC的读指针会从最底部的缓冲区依次读出数据并输出,每触发一次,地址+1,到达最高上限后(比如设置缓冲区最高为4),那么读指针会在下一次触发时会到底部缓冲区(DAC[0]_DAT)。
如果使用普通模式,需要配置DAC_BufferWorkModeBUFFER_MODE_NORMAL
摆动模式
顾名思义,在该模式下,读指针像单摆一向,不会在到达顶端后立即返回底部,而是会在下次触发后由地址+1改为地址-1,也就是说读指针会一直在缓冲区底部和最高上限之间游走。
如果使用普通模式,需要配置DAC_BufferWorkModeBUFFER_MODE_SWING
单次扫描模式
在该模式下,读指针从底部逐渐增加到最高上限后,就会停止在那里不动,只有在再次复位指针后,它才会再一次开始增加。
如果使用普通模式,需要配置DAC_BufferWorkModeBUFFER_MODE_ONETIMESCAN
以上所说的缓冲区最高上限是由DAC_BufferUpperLimit配置的,取值为1~16。


关于DAC的触发

如果你使用“非缓冲区工作模式”,那么不必理会这节,因为只有只用“缓冲区工作模式”时才需要配置DAC的触发模式。每触发一下DAC,它的数据读指针就会改变一次地址,从而改变数据的输出。最简单的方式是配置DAC为软件触发(.DAC_SoftTrgEnable=TRUE),你就可以使用库函数LPLD_DAC_SoftwareTrigger()触发指针变更。当然DAC也可配置为硬件触发,也需要用到PDB模块来配合使用。


关于DAC的中断

同样,如果你使用DAC的缓冲区工作模式,那么也可以配置是否触发不同的中断。
当使能读指针底部中断后(.DAC_ReadPointerBottomIntEnable=TRUE),DAC会在读指针到达缓冲区最高上限后产生中断请求。
当使能读指针顶部中断后(.DAC_ReadPointerTopIntEnable=TRUE),DAC会在读指针等于0后产生中断请求。
当使能缓冲区水印中断后(.DAC_BufferWatermarkIntEnable=TRUE),DAC会在读指针到达水印位置后产生中断请求,这个水印位置由DAC_BufferWatermarkSel结构体变量决定。
当然,在初始化参数中使能相关中断后还不够,还要配置相关中断的回调函数才可以,最终还要调用使能DACx中断函数来使能中断控制器。


DAC例程讲解

打开例程“08-(DAC)LPLD_AnalogSignalOutput”(请使用该例程的0.2版本,0.1版本存在BUG),编译下载后运行,用示波器观察DAC0_OUT引脚的波形,会看到三角波的产生,如下图所示:


这是一个极其简单的例程,我们只需要几行的程序就可以实现三角波的生成,首先看初始化代码:

1
  dac_init_struct.DAC_Dacx = DAC0;
2
  LPLD_DAC_Init(dac_init_struct);


Line 1:使用DAC0模块。
Line 2:调用初始化函数初始化DAC0。没错,只需要这简单的2行就完成了DAC的最简单功能的初始化任务!

接下来看while循环内的代码:

1
    if(i==0)
2
      delta = DELTA;
3
    else if(i==4095)
4
      delta = -DELTA;
5

6
    i += delta;
7

8
    LPLD_DAC_SetBufferDataN(DAC0, i, 1);
9
    delay(DELAY);


Line 1~4:这几行决定每次循环的输出值是增还是减,因为我们要输出三角波,因此不管波形的增加还是减小,它都是线性变化的,当到达底部后,让每次变化为递增DELTA,当达到顶部后 ,让每次变化为递减DELTA,这个DELTA值默认设置为1。
Line 6:将递增或递减的值累加到输出值i中。
Line 8:调用设置输出缓冲区数据函数,配置输出数据的第1个缓冲区为输出值i。因为我们没有使能“缓冲区工作模式”,因此只要调用了此函数后,DAC就会立即输出数值i。
Line 9:延时一小会以保持波形,如果你想更改波形的频率,更改这里的延时值就可以了。当然,如果想精确的设置输出间隔时间,最好还是使用“缓冲区工作模式”并配合“硬件触发”为好!


DAC能干什么

开篇我们说了,ADC和DAC是就像一对欢喜冤家,互相是对着干的。那么DAC到底都能实际干些什么呢?最常用的就是我们说的输出音频数据,当然它本质还是输出模拟波形,只不过这个波形的频率范围是我们可以用耳朵识别出来的。
DAC也可以做为波形发生器,就像本例程中生成的三角波一样,你可以利用不同的算法,加上点有计划的输出间隔、触发配置,就可以做得更像样一点。
如果你想做一个可编程电流源,同样可以例程DAC来控制,这里我们就抛砖引玉了,大家可以慢慢挖掘!
本片仅仅是针对OSKinetis固件库来阐述DAC到底怎么用,更详细的原理、使用方法,大家可以百度、谷歌、看技术文档等等。


  • 有什么需求和疑问欢迎联系 support[AT]lpld.cn
  • OSKinetis固件库专业讨论群,有机会和固件库开发者一对一交流。QQ群:184156168(入群请输入“LPLD固件库”)
  • OSKinetis V3固件库及例程获取:http://www.znczz.com/thread-207411-1-1.html







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

2

主题

109

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2611

优秀会员奖章

威望
1371
贡献
794
兑换币
724
注册时间
2013-3-19
在线时间
223 小时
2#
发表于 2013-11-4 21:07:50 | 只看该作者
回复 支持 反对

使用道具 举报

20

主题

259

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
5644
威望
2695
贡献
1597
兑换币
1729
注册时间
2013-1-5
在线时间
677 小时
3#
发表于 2013-11-8 17:11:29 | 只看该作者
请问老师今年光电的CCD需要用到比较器模块么?
回复 支持 反对

使用道具 举报

7

主题

177

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2881
威望
1376
贡献
841
兑换币
925
注册时间
2014-10-12
在线时间
332 小时
4#
发表于 2015-10-11 14:43:47 | 只看该作者
always xuexi
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-12-26 14:28 , Processed in 0.090238 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表