实验十二 DAC—电压输出

一.实验目标

1.通过编程STM32实现使用内部DAC输出电压;

2.熟悉内部DAC使用。

二.知识储备及设计思路

DAC指数模转换器,即能将数字信号转为模拟信号的器件。DAC的实现有不同结构,如权电阻网络、R-2R型等结构。STM32F407的DAC模块(数字/模拟转换模块)是12位数字输入,电压输出型的DAC。DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压Vref+(通ADC共用)以获得更精确的转换结果。

STM32F407的DAC模块主要特点有:

① 2个DAC转换器:每个转换器对应1个输出通道

② 8位或者12位单调输出

③ 12位模式下数据左对齐或者右对齐

④ 同步更新功能

⑤ 噪声波形生成

⑥ 三角波形生成

⑦ 双DAC通道同时或者分别转换

⑧ 每个通道都有DMA功能

本开发板中DAC有如下特性:

数据手册中还给出了框图说明,可以在程序设计的过程中进行参考:

三.引脚说明与硬件连接

打开开发板的原理图,可以看到DAC的引脚是PA4和PA5,分别是通道1和通道2的输出,如图1所示,在使用过程中将这两个管脚接在万用表或者示波器上即可观察DAC两个通道的输出。

图1 单片机内部DAC的输出引脚

图2 开发板上DAC输出脚位置

如图2所示,在开发板上,这两个引脚接在了J2座子上,可以采用杜邦线进行连接。

在实际使用中,我们选择了输出1通道,在实际调试时可以将1通道接在示波器,共地之后就能在示波器上看到DAC的输出波形。

DAC常用的寄存器如下(以DAC1为例):

控制寄存器(CR):

控制寄存器具体介绍如下:

其他寄存器可以在数据手册中查阅,这里仅介绍比较重要的控制寄存器。该寄存器可以配置DAC的使能情况,并配置输出缓冲器,此外还包括DMA、中断等功能的配置,可以通过更改寄存器的值来改变模式。

在HAL库开发模式下,可以用库函数代替寄存器的配置过程。所使用的结构体为:

所使用的主要结构体为DAC_HandleTypeDef,其中主要成员的含义为:

Instance:寄存器基地址

State:DAC通讯状态

……

大部分的定义都是通过对instance成员赋值进行的,具体可参考工程代码。

四.程序整体框图和设计

整体程序采用模块化的设计思路,对关键模块的代码封装在一组.c和.h文件中,便于查阅和移植。本程序在例程键盘显示的基础上进行开发,可以通过调用LCD函数进行人机交互,并控制单片机实现不同的DAC输出。图3为本次程序设计的整体框图。

图3 程序设计框图

下面对DAC配置函数进行简单介绍。

1.DAC初始化配置

1
2
3
4
| void MX_DAC_Init(void) {  DAC_ChannelConfTypeDef sConfig = {0};  //GPIO_InitTypeDef GPIO_InitStruct = {0};  \__HAL_RCC_GPIOA_CLK\_ENABLE();   /\* USER CODE END DAC_Init 1 \*/  /\*\* DAC Initialization   \*/  hdac.Instance = DAC;  if (HAL_DAC_Init(&hdac) != HAL_OK)  {  Error\_Handler();  }  /\*\* DAC channel OUT1 config   \*/  sConfig.DAC_Trigger = DAC_TRIGGER_NONE;  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;  if (HAL_DAC\_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)  {  Error\_Handler();  }  /\* USER CODE BEGIN DAC_Init 2 \*/  HAL_DAC_Start(&hdac,DAC_CHANNEL_1);//开启DAC通道1  /\* USER CODE END DAC_Init 2 \*/  } |
| ------------------------------------------------------------ |


DAC的初始化是用cubeMX完成的,其中定义了DAC配置所需的结构体,对结构体赋值并打开相应GPIO的时钟(DAC时钟的开启要在文件stm32f4xx_hal_msp.c文件中进行配置,并在stm32f4xx_hal_conf.c文件中打开相应的标识符),按手册配置其触发类型和输出缓冲等。这一部分是cubeMX自动生成的,在移植过程中需要注意配置项目不能缺少。

2.电压的输出与显示

1
2
3
4
| void DAC\_Direct(double v){  /\*  计算公式:输出电压v = (VREF+) \* DOR / 4095  VREF+是电压参考基准,一般为3.3V  若输出0.7V直流电压,按公式计算为  v = 4095\*0.7/3.3 = 869  DOR = v \* 4095 / 3.3  实测VREF约为3.2566  \*/    hdac.Instance-\>DHR12R1=(uint32_t)(v \* 40950 / 32.566);   }  double Show_Current_V(void){  return HAL_DAC_GetValue(&hdac,DAC_CHANNEL_1)\*32.566/40950;//输出显示当前的输出电压 } |
| ------------------------------------------------------------ |


根据直流电压的输出公式,可以得到输出电压为V时寄存器的值。此处采用1通道的12位右对齐寄存器,对该寄存器进行赋值即可得到需要的输出电压。在此处为了便于书写,使用了转换函数,直接传入电压值即可自动转为寄存器所需的值。

电压显示部分采用了库函数,可以得到当前DOR寄存器的值(码数),再进行类似的转换即可得到当前电压值,用LCD打印即可实时获知。

其余部分代码见工程源文件。

五.实验结果

1.直流电压步进输出

如图4,显示了当按下key18时,输出电压的变化:

图4 直流电压步进输出

程序设计为按键一次输出电压增加0.5V,直到输出3V时清零,重新输出。用户也可以对程序重新定义,改变不同的步进值。

2.波形输出

如图5所示,按下按键KEY17通过设置输出的形式,可以实现锯齿波和正弦波的输出,波形的幅度、形状等可以由用户自由配置。

图5 锯齿波和正弦波波形

至此,本实验的内容基本上完成了。

六.STM32CubeMX配置关键硬件截图

本实验配置比较简单,选择好器件后,在Analog选项中选择DAC,选择需要的通道和中断即可,如图6所示。

图6 CubeMX配置页面