注意

本文章内容只适用于大容量的STM32F101xx和STM32F103xx产品。

DAC 简介(数模转换)

数字/模拟转换模块(DAC)是12位数字输入,电压输出的数字/模拟转换器。DAC可以配置为8位
或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐
或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道
可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输
入参考电压V REF+ 以获得更精确的转换结果

DAC主要特征

● 2个DAC转换器:每个转换器对应1个输出通道
● 8位或者12位单调输出
● 12位模式下数据左对齐或者右对齐
● 同步更新功能
● 噪声波形生成
● 三角波形生成
● 双DAC通道同时或者分别转换
● 每个通道都有DMA功能
● 外部触发转换
● 输入参考电压V REF+

DAC框图

在这里插入图片描述在这里插入图片描述

名称 型号类型 注释
VREF+ 输入,正模拟参考电压 2.4V ≤ V REF+ ≤ V DDA (3.3V)
VDDA 输入,模拟电源 模拟电源
VSSA 模拟输出信号 DAC通道x的模拟输出

一旦使能 DACx 通道,相应的 GPIO 引脚 (PA4 或者 PA5) 就会自动与 DAC 的模拟输出相连
(DAC_OUTx) 。为了避免寄生的干扰和额外的功耗,引脚 PA4 或者 PA5 在之前应当设置成模拟输
入 (AIN) 。

DAC功能

使能DAC通道

将DAC_CR寄存器的ENx位置’1’即可打开对DAC通道x的供电。经过一段启动时间t WAKEUP ,DAC通道x即被使能。

DAC数据格式

根据选择的配置模式,数据按照下文所述写入指定的寄存器:
● 单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 转换

1.不能直接对寄存器DAC_DORx写入数据,任何输出到DAC通道x的数据都必须写入DAC_DHRx寄存器(数据实际写入DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD、或者DAC_DHR12RD寄存器)。
2.如果没有选中硬件触发(寄存器DAC_CR1的TENx位置’0’),存入寄存器DAC_DHRx的数据会在一个APB1时钟周期后自动传至寄存器DAC_DORx。如果选中硬件触发(寄存器DAC_CR1的TENx位置’1’),数据传输在触发发生以后3个APB1时钟周期后完成。
3.一旦数据从DAC_DHRx寄存器装入DAC_DORx寄存器,在经过时间t SETTLING 之后,输出即有效,这段时间的长短依电源电压和模拟输出负载的不同会有所变化。在这里插入图片描述

DAC 输出电压

数字输入经过DAC被线性地转换为模拟电压输出,其范围为0到V REF+ 。
任一DAC通道引脚上的输出电压满足下面的关系:
DAC输出 = V REF x (DOR / 4095)

DAC相关寄存器

在这里插入图片描述

DAC的配置过程

使用 DAC模块的通道 1 来输出模拟电压,其详细设置步骤如下:

1 )开启 PA 口时钟,设置 PA4 为模拟输入

STM32F103RCT6 的 DAC 通道 1 是接在 PA4 上的,所以,我们先要使能 PORTA 的时钟,然后设置 PA4 为模拟输入(虽然是输入,但是 STM32 内部会连接在 DAC 模拟输出上)。

2 )使能 DAC1

同其他外设一样,要想使用,必须先开启相应的时钟。STM32 的 DAC 模块时钟是由APB1 提供的,所以我们先要在 APB1ENR 寄存器里面设置 DAC 模块的时钟使能。

3 )设置 DAC 的工作模式。

该部分设置全部通过 DAC_CR 设置实现,包括:DAC 通道 1 使能、DAC 通道 1 输出缓存关闭、不使用触发、不使用波形发生器等设置。

4)设置 DAC 的输出 值。

通过前面 3 个步骤的设置,DAC 就可以开始工作了,我们使用 12 位右对齐数据格式,所以我们通过设置 DHR12R1,就可以在 DAC 输出引脚(PA4)得到不同的电压值了。最后,再提醒一下大家,MiniSTM32 开发板的参考电压直接就是 VDDA,即 3.3V。

通过以上几个步骤的设置,我们就能正常的使用 STM32 的 DAC 通道 1 来输出不同的模拟电压了。

寄存器版本代码-软件延时

//DAC通道1输出初始化
void Dac1_Init(void)
{
	RCC->APB2ENR|=1<<2;    //使能PORTA时钟  	
	RCC->APB1ENR|=1<<29;   //使能DAC时钟 	
	   	 
	GPIOA->CRL&=0XFFF0FFFF; 
	GPIOA->CRL|=0X00000000;//PA4 模拟输入   

	DAC->CR|=1<<0;	//使能DAC1
	DAC->CR|=1<<1;	//DAC1输出缓存不使能 BOFF1=1
	DAC->CR|=0<<2;	//不使用出发功能TEN1=0
	DAC->CR|=0<<3;	//DAC TIM6 TRGO,不过要TEN1=1
	DAC->CR|=0<<6;	//不使用波形发生器
	DAC->CR|=0<<8;	//屏蔽幅值设置
	DAC->CR|=0<<12;	//DAC1 DMA不使能   

	DAC->DHR12R1=0;
}

这里DAC不采用定时器触发,不用DMA通道接收数据,采用正弦表和软件延时组合来产生正弦波,可以看到及其不稳定,有很多毛刺。

寄存器版本代码-定时器计时

//DAC通道1输出初始化
void Dac1_Init(void)
{
	RCC->APB2ENR|=1<<2;    //使能PORTA时钟
	RCC->APB1ENR|=1<<29;   //使能DAC时钟 	
	   	 
	GPIOA->CRL&=0XFFF0FFFF; 
	GPIOA->CRL|=0X00000000;//PA4 模拟输入   

	DAC->CR|=1<<0;	//使能DAC1
	DAC->CR|=1<<1;	//DAC1输出缓存不使能 BOFF1=1
	DAC->CR|=1<<2;	//使用出发功能TEN1=1
	DAC->CR|=1<<5;	//DAC TIM2 TRGO,不过要TEN1=1
	DAC->CR|=0<<6;	//不使用波形发生器
	DAC->CR|=0<<8;	//屏蔽幅值设置
	DAC->CR|=1<<12;	//DAC1 DMA使能   因为我用到DMA搬运数据

	DAC->DHR12R1=0;
}
//定时器初始化
void TIM2_DAC1_Init(u16 arr,u16 psc)
{
	
	RCC->APB1ENR|=1<<0;	//TIM2时钟使能
 	TIM2->ARR=arr;  	//自动重装载值
	TIM2->PSC=psc;  	//预分频系数	  
	TIM2->CR2|=2<<4;      //选择更新事件作为触发输出
	TIM2->CR1|=0x01;    //使能定时器2
	
}

//改变频率,重新计时
void TIM2_DAC_REINIT(u16 hz)//¸改变频率
{	
	u16 arr;
	arr = 72000000/(hz * 256); // 通过hz改变重装载值
	TIM2->CR1|=0x00;    //关闭定时器2
	TIM2->ARR=arr;  	//自动重装载值
	TIM2->CR1|=0x01;    //使能定时器2
}
定时器根据频率计算重装载值

在这里插入图片描述
在这里插入图片描述

在实际应用中,可以根据工程里的正弦波点数和定时器配置生成特定频率的正弦波。这里我用的是256点产生数据。

现象

在这里插入图片描述

end…

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐