当前位置: 首页 > news >正文

【STM32 CubeMX + Keil】DAC 输出0~3.3V间任意电压

本文示范使用 CubeMX 配置 DAC,并通过代码实现指定电压输出

目录

1、DAC 是什么?        

二、STM32 内置 DAC 概述        

三、CubeMX 配置 DAC        

四、代码实现        

五、编写电压输出函数


       

1、DAC 是什么?
        

DACDigital-to-Analog Converter,数模转换器)是一种将数字信号转换为模拟信号的关键外设。

干的事很简单:把数字代码变成模拟电压。

  • 输入:0–4095(12位数字值)
  • 输出:0V~3.3V(对应范围的模拟电压)

你就理解是个能用代码精确调压的数字电位器,写个值,改变输出电压,贼方便。

典型应用场景

  • 📈 生成各种波形:DAC最典型的应用,如正弦波、三角波等。
  • 🔊 音频输出:通过DAC将解码后的数字音频数据转换为模拟信号,经功率放大后驱动扬声器。
  • ⚙️ 控制模拟电路:比如调电机转速
  • 🔋  作为可编程电压基准源

       

二、STM32 内置 DAC 概述
        

大多数 STM32 芯片都内置了 DAC,不过不同系列的通道数有点区别。

1、分辨率

  • 清一色 12 位,范围 0–4095;
  • STM32所有型号,内置DAC都是12位。

2、输出能力

  • 电压:0V ~ 3.3V(与 VDDA 电压相关);
  • 电流:就几mA;别指望直接驱动大负载; 

3、通道数量

  • 多数型号 2 路输出。通道1是PA4、通道2是PA5,不管啥型号都焊死不变。
  • G系列是个卷王:4路甚至7路D。
  • ⚠️注意:F103C8没有DAC!要F103RC或以上型号才有。

4、触发方式

  • 软件触发:程序直接控制,写个值立马输出。前期调电路、验证功能时最常用。
  • 定时器触发:通常搭配DMA,自动从数组里搬波形数据给DAC,用来产生精确频率的正弦波、三角波等,自动刷波形,CPU 可躺平。
  • 外部引脚触发:用外部信号(如传感器、开关)直接触发DAC输出。信号来了立马响应,比中断还快。

       

三、CubeMX 配置 DAC
        

1、新建工程

若你已有现成的CubeMX工程,打开ioc文件即可在工程里进行DAC功能的添加、配置 。

如果打算新建工程进行测试,本文不啰嗦操作过程,可参考下面文章:

①  新建 STM32F407VE 工程

2、打勾使能DAC通道

DAC的配置,极度简单。

  • 两个通道,需要哪个通道输出,打勾即可。
  • 其它参数默认。

参数说明:

  • External Trigger (外部触发):不打勾。EXTI9触发,本篇示例无需使用。
  • Output Buffer (输出缓存):Enable。降低输出阻抗,可直接驱动外部负载(省外加运放)。高精度场合建议关闭以减少误差。
  • Tigger (触发方式): None,直接调用 DAC_SetChannelxData() 即可设置输出电压,最简单直接。注意,当选择 Software Trigger 软件触发时,设置电压值后必须额外调用 DAC_SoftwareTriggerCmd() 才能生效触发信号仅持续1个APB1时钟周期,每次修改电压都需重新触发。

3、生成工程配置

DAC的配置,只有上面一步,已全部完成。现在点击"Generate Code"生成工程代码即可。


       

四、代码实现
        

用CubeMX配置好后,Kiel里操作DAC主要就这3个函数。

  • 启动DAC:       HAL_DAC_Start(&hdac, DAC_CHANNEL_1); 
  • 停止DAC转换:HAL_DAC_Stop(&hdac, DAC_CHANNEL_1); 
  • 设置输出值:    HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2048);

输出示例:让PA4输出1.7V,PA5输出2.8V, 几行代码即可实现:

HAL_DAC_Start(&hdac, DAC_CHANNEL_1); // 开启通道1
HAL_DAC_Start(&hdac, DAC_CHANNEL_2); // 开启通道2HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2110); // 通道1输出1.7V
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 3475); // 通道2输出2.8V

为啥1.7V是2110,2.8V是3475?

  • DAC是12位,最大值是4095。即,0V对应0000,3.3V对应最大值4095。
  • 计算公式:数字值 = (目标电压÷3.3) x 4095
  • 1.7V的DAC值是:(1.7÷3.3)x4095 = 2110。 同理,2.8V的DAC值:(2.8÷3.3)x4095=3475。 

完成后,是这个样子的:

验证结果
用万用表测PA4引脚电压,确认输出准确:


五、编写电压输出函数

为了减少手工换算DAC值与电压值,编写一个电压输出函数,直接输入mV值即可转换输出。

还是上面那个:数字值 = (目标电压÷3.3) x 4095

编写函数:

// 设置通道1电压值; 单位:mV; 值范围: 0~3300;
void DAC_PA4SetVoltage(uint16_t mV)
{if (mV > 3300){mV = 3300;}uint16_t val = (uint16_t)(mV * 4095UL / 3300);                 // 毫伏转换为DAC值HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, val);  // 设置DAC通道1的值
}// 设置通道2电压值; 单位:mV; 值范围: 0~3300;
void DAC_PA5SetVoltage(uint16_t mV)
{if (mV > 3300){mV = 3300;}uint16_t val = (uint16_t)(mV * 4095UL / 3300);                 // 毫伏转换为DAC值HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, val);  // 设置DAC通道2的值
}

完成后,是这个样子:


文章转载自:

http://vHs27yJD.fhjnh.cn
http://eqwgfVPW.fhjnh.cn
http://G3VyxyeT.fhjnh.cn
http://zXpX10Aa.fhjnh.cn
http://EEfCmLvp.fhjnh.cn
http://yKYmsw2Q.fhjnh.cn
http://KizrQ8jn.fhjnh.cn
http://ujSRgaGS.fhjnh.cn
http://l2GZf3f0.fhjnh.cn
http://cXr4EkUt.fhjnh.cn
http://xVyOmCC0.fhjnh.cn
http://FAO1mRvA.fhjnh.cn
http://Xr4Qp5hZ.fhjnh.cn
http://zv5yofqf.fhjnh.cn
http://a7YtebEK.fhjnh.cn
http://E5JohNE1.fhjnh.cn
http://YOM5JjiX.fhjnh.cn
http://ppLJ3xDM.fhjnh.cn
http://dNWN6L0e.fhjnh.cn
http://UOMkGLYl.fhjnh.cn
http://1IWvi0fe.fhjnh.cn
http://onug9TFR.fhjnh.cn
http://Ic4t1Ghe.fhjnh.cn
http://pX8MsGeh.fhjnh.cn
http://B29XWjwi.fhjnh.cn
http://BGQvObLC.fhjnh.cn
http://XKYhQWhF.fhjnh.cn
http://OXvsRiXk.fhjnh.cn
http://kk4XQUSo.fhjnh.cn
http://WRhwA73y.fhjnh.cn
http://www.dtcms.com/a/387823.html

相关文章:

  • git submodule命令详解
  • HTTP/2.0是什么?
  • 深度学习基础:从线性回归到 Softmax 回归的完整梳理
  • 深度学习之线性回归与 Softmax 回归
  • 线性回归与 Softmax 回归
  • 源雀 Scrm开源:企微防截屏
  • [APItest-Karate] HttpRequestBuilder | HttpClient发送请求
  • 线性回归与 Softmax 回归:从基础模型到深度学习入门
  • 【Leetcode hot 100】105.从前序与中序遍历序列构造二叉树
  • 机器视觉在PCB制造中的检测应用
  • 服务器ssh端口放开,仍然无法登录
  • 【0基础3ds Max】命令面板详解
  • LeetCode 381 - O(1) 时间插入、删除和获取随机元素(允许重复)
  • [新启航]深孔加工尺寸精度检测方法 - 激光频率梳 3D 轮廓测量
  • MySQL 进阶:多表联合查询与数据备份恢复
  • 【LeetCode每日一题】:移除链表元素
  • 工业大数据时代时序数据库选型指南:为何Apache IoTDB成为首选?
  • Java 中 ArrayList 与 LinkedList 的深度对比:从原理到实战选择
  • 向量检索服务 DashVector产品功能
  • Spring-Cloud-Alibaba:2023.0.1.X引起的dashscope-sdk-java依赖冲突问题
  • vue 知识点
  • 深入理解 Linux 进程调度:从策略到实现的全方位解析
  • 【技术架构】从单机到微服务:Java 后端架构演进与技术选型核心方案
  • Java异常报错: java.io.IOException: Broken pipe
  • [Linux]学习笔记系列 -- lib/kobject.c 内核对象(Kernel Object) 设备模型的核心基石
  • 专题:Python实现贝叶斯线性回归与MCMC采样数据可视化分析2实例|附代码数据
  • IEEE 802.1X和**IEEE 802.11之间的关联和作用
  • 【Linux】【底层解析向】Linux Shell 核心功能拆解:环境变量不生效原因 + $?/echo/alias 底层逻辑
  • UV紫外卤素灯太阳光模拟器的原理
  • RAG简单构建(ollama+uv+deepseek)