我们一般配合定时器和DMA一起使用
数字/模拟转换模块(DAC)是12位数字输入,电压输出的数字/模拟转换器。DAC可以配置为8位
或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐
或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道
可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输
入参考电压VREF+以获得更精确的转换结果。
●2个DAC转换器:每个转换器对应1个输出通道
● 8位或者12位单调输出
● 12位模式下数据左对齐或者右对齐
● 同步更新功能
● 噪声波形生成
● 三角波形生成
● 双DAC通道同时或者分别转换
● 每个通道都有DMA功能
● 外部触发转换
● 输入参考电压VREF+
注意: 一旦使能DACx通道,相应的GPIO引脚(PA4或者PA5)就会自动与DAC的模拟输出相连
(DAC_OUTx)。为了避免寄生的干扰和额外的功耗,引脚PA4或者PA5在之前应当设置成模拟输
入(AIN)。
DAC功能描述:
1使能DAC通道:将DAC_CR寄存器的ENx位置’1’即可打开对DAC通道x的供电。经过一段启动时间tWAKEUP,DAC通道x即被使能。
注意: ENx位只会使能DAC通道x的模拟部分,即便该位被置’0’,DAC通道x的数字部分仍然工作
2使能DAC输出缓存:DAC集成了2个输出缓存,可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载。每个DAC通道输出缓存可以通过设置DAC_CR寄存器的BOFFx位来使能或者关闭。
3DAC数据格式:
根据选择的配置模式,数据按照下文所述写入指定的寄存器:
● 单DAC通道x,有3种情况:
─ 8位数据右对齐:用户须将数据写入寄存器DAC_DHR8Rx[7:0]位(实际是存入寄存器
DHRx[11:4]位)
─ 12位数据左对齐:用户须将数据写入寄存器DAC_DHR12Lx[15:4]位(实际是存入寄存器
DHRx[11:0]位)
─ 12位数据右对齐:用户须将数据写入寄存器DAC_DHR12Rx[11:0]位(实际是存入寄存器
DHRx[11:0]位)
根据对DAC_DHRyyyx寄存器的操作,经过相应的移位后,写入的数据被转存到DHRx寄存器中
(DHRx是内部的数据保存寄存器x)。随后,DHRx寄存器的内容或被自动地传送到DORx寄存
器,或通过软件触发或外部事件触发被传送到DORx寄存器。
● 双DAC通道,有3种情况:
─ 8位数据右对齐:用户须将DAC通道1数据写入寄存器DAC_DHR8RD[7:0]位(实际是存入
寄存器DHR1[11:4]位),将DAC通道2数据写入寄存器DAC_DHR8RD[15:8]位(实际是存入
寄存器DHR2[11:4]位)
─ 12位数据左对齐:用户须将DAC通道1数据写入寄存器DAC_DHR12LD[15:4]位(实际是存
入寄存器DHR1[11:0]位),将DAC通道2数据写入寄存器DAC_DHR12LD[31:20]位(实际是
存入寄存器DHR2[11:0]位)
─ 12位数据右对齐:用户须将DAC通道1数据写入寄存器DAC_DHR12RD[11:0]位(实际是存
入寄存器DHR1[11:0]位),将DAC通道2数据写入寄存器DAC_DHR12RD[27:16]位(实际是
存入寄存器DHR2[11:0]位)
根据对DAC_DHRyyyD寄存器的操作,经过相应的移位后,写入的数据被转存到DHR1和DHR2
寄存器中(DHR1和DHR2是内部的数据保存寄存器x)。随后,DHR1和DHR2的内容或被自动地
传送到DORx寄存器,或通过软件触发或外部事件触发被传送到DORx寄存器。
4 DAC转换:
不能直接对寄存器DAC_DORx写入数据,任何输出到DAC通道x的数据都必须写入DAC_DHRx寄存器(数据实际写入DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD、或者DAC_DHR12RD寄存器)。如果没有选中硬件触发(寄存器DAC_CR1的TENx位置’0’),存入寄存器DAC_DHRx的数据会在一个APB1时钟周期后自动传至寄存器DAC_DORx。如果选中硬件触发(寄存器DAC_CR1的TENx位置’1’),数据传输在触发发生以后3个APB1时钟周期后完成。一旦数据从DAC_DHRx寄存器装入DAC_DORx寄存器,在经过时间tSETTLING之后,输出即有效,这段时间的长短依电源电压和模拟输出负载的不同会有所变化。
5 DAC输出电压:
数字输入经过DAC被线性地转换为模拟电压输出,其范围为0到VREF+。
任一DAC通道引脚上的输出电压满足下面的关系:
DAC输出 = VREF x (DOR / 4095)。
6 选择DAC触发:
如果TENx位被置1,DAC转换可以由某外部事件触发(定时器计数器、外部中断线)。配置控制位
TSELx[2:0]可以选择8个触发事件之一触发DAC转换。
每次DAC接口侦测到来自选中的定时器TRGO输出,或者外部中断线9的上升沿,最近存放在寄
存器DAC_DHRx中的数据会被传送到寄存器DAC_DORx中。在3个APB1时钟周期后,寄存器
DAC_DORx更新为新值。
如果选择软件触发,一旦SWTRIG位置’1’,转换即开始。在数据从DAC_DHRx寄存器传送到
DAC_DORx寄存器后,SWTRIG位由硬件自动清’0’。
注意: 1. 不能在ENx为’1’时改变TSELx[2:0]位。EN是DAC通道使能,TEN是DAC触发时能
2. 如果选择软件触发,数据从寄存器DAC_DHRx传送到寄存器DAC_DORx只需要一个APB1时
钟周期
TSEL2[2:0]:DAC通道2触发选择 (DAC channel2 trigger selection) 位于DAC_CR寄存器
该3位用于选择DAC通道2的外部触发事件。
000:TIM6 TRGO事件;
001:对于互联型产品是TIM3 TRGO事件,对于大容量产品是TIM8 TRGO事件;
010:TIM7 TRGO事件;
011:TIM5 TRGO事件;
100:TIM2 TRGO事件;
101:TIM4 TRGO事件;
110:外部中断线9;
111:软件触发。
注意:该3位只能在TEN2 = 1(DAC通道2触发使能)时设置。
7 DMA请求:
任一DAC通道都具有DMA功能。2个DMA通道可分别用于2个DAC通道的DMA请求。
如果DMAENx位置’1’,一旦有外部触发(而不是软件触发)发生,则产生一个DMA请求,然后
DAC_DHRx寄存器的数据被传送到DAC_DORx寄存器。
在双DAC模式下,如果2个通道的DMAENx位都为’1’,则会产生2个DMA请求。如果实际只需要
一个DMA传输,则应只选择其中一个DMAENx位置’1’。这样,程序可以在只使用一个DMA请
求,一个DMA通道的情况下,处理工作在双DAC模式的2个DAC通道。
DAC的DMA请求不会累计,因此如果第2个外部触发发生在响应第1个外部触发之前,则不能处
理第2个DMA请求,也不会报告错误。
8 噪声生成:
可以利用线性反馈移位寄存器(Linear Feedback Shift Register LFSR)产生幅度变化的伪噪声。
设置WAVE[1:0]位为’01’选择DAC噪声生成功能。寄存器LFSR的预装入值为0xAAA。按照特定
算法,在每次触发事件后3个APB1时钟周期之后更新该寄存器的值。
设置DAC_CR寄存器的MAMPx[3:0]位可以屏蔽部分或者全部LFSR的数据,这样的得到的LSFR
值与DAC_DHRx的数值相加,去掉溢出位之后即被写入DAC_DORx寄存器。
如果寄存器LFSR值为0x000,则会注入’1’(防锁定机制)。
将WAVEx[1:0]位置’0’可以复位LFSR波形的生成算法。
注意: 为了产生噪声,必须使能DAC触发,即设DAC_CR寄存器的TENx位为’1’。
9 三角波生成
可以在DC或者缓慢变化的信号上加上一个小幅度的三角波。设置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’可以复位三角波的生成。
注意: 1. 为了产生三角波,必须使能DAC触发,即设DAC_CR寄存器的TENx位为’1’。
2. MAMP[3:0]位必须在使能DAC之前设置,否则其值不能修改。
DAC初始化代码
void DA_Config()
{
DAC_InitTypeDef dacinit;
RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
//DAC_LFSRUnmask_Bit相当于在选有几位数据在波动以DA寄存器数据为最小值(0bit是一位),DAC_TriangleAmplitude三角波的幅度以DA数据为最小值,每次触发加一
dacinit.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
dacinit.DAC_OutputBuffer=DAC_OutputBuffer_Disable; //输出缓冲,减小输出阻抗
dacinit.DAC_Trigger=DAC_Trigger_T4_TRGO; //外部触发使能后不能修改触发方式,另外软件触发更快
dacinit.DAC_WaveGeneration=DAC_WaveGeneration_None; //无 噪声 三角波//
DAC_Init(DAC_Channel_1,&dacinit);
DAC_Cmd(DAC_Channel_1,ENABLE);
}