一、DAC简介
DAC(Digital-to-Analog Converter),即数字/模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与 ADC 相反。在常见的数字信号系统中,大部分传感器信号被化成电压信号,而 ADC 把电压模拟信号转换成易于计算机存储、处理的数字编码,由计算机处理完成后,再由 DAC 输出电压模拟信号,该电压模拟信号常用来驱动某些执行器件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。
STM32 具有片上 DAC 外设,它的分辨率可配置为 8 位或 12 位的数字输入信号,具有两个 DAC 输出通道,这两个通道互不影响,每个通道都可以使用 DMA 功能,都具有出错检测能力,可外部触发。
二、DAC通道选择
在 STM32 中具有 2 个这样的 DAC 部件,每个 DAC 有 1 个对应的输出通道连接到特定的引脚,即:PA4-通道 1
,PA5-通道 2
,为避免干扰,使用 DAC 功能时,DAC 通道引脚需要被配置成模拟输入功能(AIN)。
三、新建工程
1. 打开 STM32CubeMX 软件,点击“新建工程”
2. 选择 MCU 和封装
3. 配置时钟
RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)
选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz
修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置
4. 配置调试模式
非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器
SYS 设置,选择 Debug 为 Serial Wire
四、DAC1
4.1 参数配置
在 Analog
中选择 DAC
设置,并选择 OUT1 Configuration
通道1
或者在右边图找到 PA4
引脚,选择 DAC_OUT1
具体配置参数如下。
- OUT1/2 Configuration:
对应两个输出通道。 - External Trigger:
外部中断EXTI9 触发
就是使用外部中断来触发DAC。 - Output Buffer:
使能DAC输出缓存。
DAC 集成了 2 个输出缓存,可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载。每个 DAC 通道输出缓存可以通过设置 DAC_CR 寄存器的 BOFFx 位来使能或者关闭。
如果带载能力还不行,后面就接一个电压跟随器,选择运放一定要选择电流大的型号。
使能输出缓冲后,DAC 输出的最小电压为 0.2V,最大电压为 VREF±0.2,而未使能输出缓冲则输出可达到0V。
- Trigger:
选择DAC的触发方式
Timer 2/4/5/6/7/8 Trigger Out event
定时器触发,利用这种方式可以输出特定的波形。
Software trigger
软件触发,在本模式下,向 DAC_SWTRIGR 寄存器写入配置即可触发信号进行转换。
4.2 生成代码
输入项目名和项目路径
选择应用的 IDE 开发环境 MDK-ARM V5
每个外设生成独立的 ’.c/.h’
文件
不勾:所有初始化代码都生成在 main.c
勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。
点击 GENERATE CODE 生成代码
五、库函数
/* IO operation functions *****************************************************/
HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel); //开启DAC输出
HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel); //关闭DAC输出
HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment); //需要函数中不断开启 //开启DAC的DMA输出
HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel); //关闭DAC的DMA输出
HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data); //设置DAC输出值
uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel); //获取DAC输出值
六、修改main函数
与 ADC 外设类似,DAC 也使用 VREF+ 引脚作为参考电压,在设计原理图的时候一般把 VSSA 接地,把 VREF+ 和 VDDA 接 3.3V,可得到 DAC 的输出电压范围为:0~3.3V。
如果想让输出的电压范围变宽,可以在外部加一个电压调理电路,把 0~3.3V 的 DAC 输出抬升到特定的范围即可。
12位模式下DAC输出电压计算公式如下:
DAC 输出电压 = VREF+ * ( DOR / 4095 )
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_DAC_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2048);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
当 DOR 我们赋值 2048 时,实际输出的电压为 2048 / 4096 x 3.3V = 1.65V
七、注意事项
用户代码要加在 USER CODE BEGIN N
和 USER CODE END N
之间,否则下次使用 STM32CubeMX 重新生成代码后,会被删除。
• 由 Leung 写于 2021 年 3 月 12 日
• 参考:STM32CubeMX系列教程8:数模转换(DAC)
【STM32】HAL库 STM32CubeMX教程十—DAC