【原创】kinetics DAC模块介绍
0赞Kinetis10包含两个独立的12位数模转换模块,DAC0和DAC1,用于将数字转换成对应的模拟电压。转换后的模拟电压可由外部引脚输出,也可以通过芯片内部连接输入到比较器模块、放大器模块、和模数转换模块。
DAC的参考电压可以二选一,一个来自外部或VREF模块的输出,默认连接到DACREF_1;另一个时VDDA,默认连接到DACREF_2。如果选择VDDA,则DAC的参考电压为3.3V。
12位二进制的表示范围为0~4095的无符号数。对应数据转换成模拟电压输出范围从VREF/4096~VREF。以VREF为3.3V计算,则是约0.8mV~3.3V,数据每变化1,输出电压变化约0.8mV。
将数据放入DAC的数据寄存器(DACx_DATL中的DACDATA[11:0]位),即可将数据转换为模拟电压。电压Vout= VREF * (1 + DACDAT0[11:0])/4096。在大量数据转换的应用中,也可以将数据放入DAC的缓冲区,由触发源输入触发信号,在触发信号的触发下,自动挨个将缓冲区中的数据转换为模拟电压。
缓冲区大小为1~16可设置大小的以word为单位的区域,转换的时候,由读指针指向正在转换的数据,可通过访问读指针获知当前正在转换的缓冲区单元。数据转换的次序为从顶部到底部依次转换,从顶部到底部之间,用户可设置位置标记(watermark)作为预警位置,当读指针指向缓冲区顶部、底部或位置标记处时,都有状态位可供查询,也可以发出中断请求。
触发信号可来自PDB模块的TRIG输出详细可查看PDB模块设置。
同时DAC模块也支持DMA操作,可通过DMA的方式向缓冲区中传递数据,大大提高了效率。
相关寄存器
1. DAC数据低位寄存器(DACx_DATnL)
在没有启用数据缓冲区的情况下,DATA[11:0]控制输出的电压,该寄存器存放的是DATA[7:0]位,此时Vout= Vin *(1 + DACDAT0[11:0])/4096。
2. DAC数据高位寄存器(DACx_DATnH)
该寄存器存放的是DATA[11:8]位。
注意,数据寄存器共16个word,每个word都由高8位DACx_DATnH和低8位DACx_DATnH组成。16个word组成DAC的缓冲区,如不使用缓冲区,则默认只使用DACx_DAT0H和DACx_DAT0L。
3. DAC状态寄存器(DACx_SR)
该寄存器中包含DMA缓冲区读指针位置的有关标志。缓冲区大小为1~16可设置大小的以word为单位的区域,转换的时候,由读指针指向正在转换的数据,数据转换的次序为从顶部到底部依次转换,从顶部到底部之间,用户可设置位置标记(watermark)作为预警位置,当读指针指向缓冲区顶部、底部或位置标记处时,都有状态位可供查询,该寄存器中存放的就是这些标志位。如果DMA功能使能的话,当DMA请求完成后,这些标志会被DMA自动清除。这些标志位都是写0清除,写1无效。
l DACBFWMF:DAC缓冲区水位标志。
DACBFWMF=0:DAC缓冲区读指针未达位置标记;
DACBFWMF=1:DAC缓冲区读指针达到位置标记。
l DACBFRPTF:DAC缓冲区读指针到顶标志,顶部为起始位置。
DACBFRPTF=0:DAC缓冲区读指针不为0;
DACBFRPTF=1:DAC缓冲区读指针为0。
l DACBFRPBF:DAC缓冲区读指针到底标志,底部为结束位置。
DACBFRPBF=0:DAC缓冲区读指针不等于DACBFUP;
DACBFRPBF=1:DAC缓冲区读指针等于DACBFUP。
4. DAC控制寄存器0(DACx_C0)
l DACEN:DAC使能。
DACEN=0:DAC被禁止;
DACEN=1:DAC使能。
l DACRFS:DAC参考选择。
DACRFS=0:选择DACREF_1为参考电压;
DACRFS=1:选择DACREF_2为参考电压。
DAC的参考电压由两个,一个是VREF_OUT,来自外部或VREF模块的输出,默认连接到DACREF_1;另一个时VDDA,默认连接到DACREF_2。
这里注意,如果ADC和DAC都使用VREF_OUT作为参考电压,则ACC精度的下降有可能和DAC切换有关。
l DACTRGSEL:DAC触发选择。触发事件的发生会使得缓冲区读指针自动指向下一个数据并进行转换。硬件触发信号默认来自PDB模块,软件触发则通过向DACSWTRG中写1实现。
DACTRGSEL =0:选择DAC硬件触发器;
DACTRGSEL =1:选择DAC软件触发器。
l DACSWTRG:DAC软件触发器。当DAC选择软件触发且缓冲区使能时,向该位写1即可实现软件触发,缓冲区读指针自动指向下一个数据。
DACSWTRG=0:DAC软件触发无效;
DACSWTRG=0:DAC软件触发有效。
l LPEN:DAC低功耗控制。
LPEN=0:大功率模式;
LPEN=1:低功率模式。
l DACBWIEN:DAC缓冲区位置标记中断使能。用于设定当读指针指向设定的位置标记处时,是否引发中断请求。
DACBWIEN=0:DAC缓冲区位置标记中断禁止;
DACBWIEN=1:DAC缓冲区位置标记中断使能。
l DACBTIEN:DAC缓冲区读指针顶部标志中断使能。
DACBTIEN=0:DAC缓冲区读指针到达顶部禁止中断;
DACBTIEN=1:DAC缓冲区读指针到达顶部触发中断。
l DACBBIEN:DAC缓冲区读指针底部标志中断使能。
DACBBIEN=0:DAC缓冲区读指针到达底部禁止中断;
DACBBIEN=1:DAC缓冲区读指针到达底部触发中断。
5. DAC控制寄存器1(DACx_C1)
l DMAEN:DMA使能。
DMAEN=0:DMA功能禁止;
DMAEN=1:DMA功能使能。
l DACBFWM:缓冲区水位标志选择。该位允许用户设置,水位标志相当于预警标志,表示还差多少,缓冲区中数据就即将转换完毕。水位标志应位于顶部和底部之间,意义是表示当缓冲区读指针已经距离最高限还差多少的时候,水位标志置1。
DACBFWM=00:1word;
DACBFWM=01:2word;
DACBFWM=10:3word;
DACBFWM=11:4word。
l DACBFMD:DAC工作模式选择。
DACBFMD=00:普通模式,在触发信号驱动下,从缓冲区顶部逐个转换数据到最底部,然后读指针回到缓冲区顶部,循环往复;
DACBFMD=01:摇摆模式,在触发信号驱动下,从缓冲区顶部逐个转换数据到最底部,再从底部逐个转换回到顶部,循环往复;
DACBFMD=10:单次扫描模式,在触发信号驱动下,从缓冲区顶部逐个转换数据到最底部,然后读指针回到缓冲区顶部并停止转换。
DACBFMD=11:保留。
l DACBFEN:DAC缓冲区使能。只有在缓冲区使能的情况下,才可使用触发信号触发逐个转换缓冲区中数据。
DACBFEN=0:DAC缓冲区读指针禁止,转换数据永远来自缓冲区的第一个字,即DAC数据寄存器中的数;
DACBFEN=1:DAC缓冲区读指针使能,转换数据来自读指针指向的字。
6. DAC控制寄存器2(DACx_C2)
l DACBFRP:DAC缓冲区读指针。
l DACBFUP:DAC缓冲区最高限,相当于指定缓冲区大小,如不指定,缓冲区大小默认为16个,即最大值。该最高限不允许DAC读指针超越。
DAC功能详解
1. DAC缓冲区操作
缓冲区大小为1~16可设置大小的以word为单位的区域,转换的时候,由读指针指向正在转换的数据,可通过访问读指针获知当前正在转换的缓冲区单元。数据转换的次序为从顶部到底部依次转换,从顶部到底部之间,用户可设置位置标记(watermark)作为预警位置,当读指针指向缓冲区顶部、底部或位置标记处时,都有状态位可供查询,也可以发出中断请求。如果DAC使能,但DAC缓冲区未使能,则DAC的数据一直来自DAT0寄存器,该数据被转换成模拟电压输出。改变该寄存器中的数据,当前输出的模拟电压也会立刻改变。
如果DAC和DAC缓冲区都使能,则缓冲区中被读指针指向的字数据会被转换成模拟电压,之后读指针会在硬件触发器或软件触发器的触发下,指向缓冲区中下一个字。
数据缓冲区的工作模式有三个,模式的切换不会改变指针指向的位置。指针的值可以被置为0到DACBFUP之间的任何一个值。
缓冲区普通模式为默认模式,在这个模式下,读指针在触发信号下每次加1,直到到达最高限,然后下一个触发信号到来时,指针回0。
摇摆模式和普通模式不同的是,当读指针到达底部时,并不直接回0,而是开始递减,一步步退回缓冲区顶部。
单次扫描模式是,读指针在触发信号下每次加1,直到到达最高限,然后停止。
DAC数据缓冲区中的读指针指向位置可以触发3个中断。一个是,当读指针到达缓冲区底部时,也就是最高限时。第二个是,读指针到达缓冲区顶部时,也就是起始位置时。第三个是,读指针到达用户设置的位置标记时。
2. DAC触发信号
当缓冲区使能时,DAC会在触发信号的驱动下轮流转换缓冲区中的数据。如没有触发信号,则当前DAC输出模拟电压的数据永远来自当前读指针指向的位置。如不使用缓冲区,则DAC转化无需设置触发器。
触发信号有两个选择,一个是软件触发,一个是硬件触发,通过DACx_C0寄存器中的DACTRGSEL位设置。默认情况下,选择硬件触发,硬件触发信号来自PDB模块,软件触发通过程序指令实现。
软件触发的方法是,只要向DACx_C0寄存器中的DACSWTRG位写1,即可实现软件触发。硬件触发则需要设置PDB模块,由PDB模块提供周期性的DAC间隔触发信号,详细可参见PDB模块设置。
3. 例程
将如下数组置于DAC缓冲区内,在触发信号触发下是实现连续转换,实现三角波输出。
- uint16 DAC_DATA[]={255,511,767,1023,1279,1535,1791,2047,2303,
- 2559,2815,3071,3327,3583,3839,4095};
- uint16 DAC_DATA[]={255,511,767,1023,1279,1535,1791,2047,2303,
- 2559,2815,3071,3327,3583,3839,4095};
初始化代码如下:
- void DAC0_Init(void)
- {
- uint8i;
- SIM_SCGC2|=SIM_SCGC2_DAC0_MASK;//打开DAC0时钟
- DAC0_C0|=DAC_C0_DACEN_MASK;//DAC使能
- DAC0_C0|=DAC_C0_DACRFS_MASK;//参考电压2,选择VDDA
- DAC0_C0&=~DAC_C0_DACTRGSEL_MASK;//使用硬件触发器
- DAC0_C1|=DAC_C1_DACBFEN_MASK;//缓冲区使能
- DAC0_C1|=DAC_C1_DACBFMD(1);//摇摆模式
- for(i=0;i<=15;i++)//缓冲区初始化
- {
- DAC0_DATL(i)=DAC_DATA[i]%256;
- DAC0_DATH(i)=DAC_DATA[i]/256;
- }
- }
- void DAC0_Init(void)
- {
- uint8i;
- SIM_SCGC2|=SIM_SCGC2_DAC0_MASK;//打开DAC0时钟
- DAC0_C0|=DAC_C0_DACEN_MASK;//DAC使能
- DAC0_C0|=DAC_C0_DACRFS_MASK;//参考电压2,选择VDDA
- DAC0_C0&=~DAC_C0_DACTRGSEL_MASK;//使用硬件触发器
- DAC0_C1|=DAC_C1_DACBFEN_MASK;//缓冲区使能
- DAC0_C1|=DAC_C1_DACBFMD(1);//摇摆模式
- for(i=0;i<=15;i++)//缓冲区初始化
- {
- DAC0_DATL(i)=DAC_DATA[i]%256;
- DAC0_DATH(i)=DAC_DATA[i]/256;
- }
- }