一、DAC简介

DAC(Digital-to-Analog Converter),即数字/模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与 ADC 相反。在常见的数字信号系统中,大部分传感器信号被化成电压信号,而 ADC 把电压模拟信号转换成易于计算机存储、处理的数字编码,由计算机处理完成后,再由 DAC 输出电压模拟信号,该电压模拟信号常用来驱动某些执行器件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。

STM32 具有片上 DAC 外设,它的分辨率可配置为 8 位或 12 位的数字输入信号,具有两个 DAC 输出通道,这两个通道互不影响,每个通道都可以使用 DMA 功能,都具有出错检测能力,可外部触发。

二、DAC通道选择

在 STM32 中具有 2 个这样的 DAC 部件,每个 DAC 有 1 个对应的输出通道连接到特定的引脚,即:PA4-通道 1PA5-通道 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 定时器触发,利用这种方式可以输出特定的波形。在这里我们选择定时器2。
    Software trigger 软件触发,在本模式下,向 DAC_SWTRIGR 寄存器写入配置即可触发信号进行转换。
  • Wave generation mode:Disable(不使用波形发生器)。

4.2 配置DMA

点击 DMA Settings 添加 DAC_CH1 对应 DMA2 的通道3。DMA模式选择循环模式,方向选为内存到外设。

  • Priority
    当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在 DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通 道编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。
  • Mode
    Normal 表示单次传输,传输一次后终止传输。
    Circular 表示循环传输,传输完成后又重新开始继续传输,不断循环永不停止。
  • Increment Address
    Peripheral 表示外设地址自增。
    Memory 表示内存地址自增。
  • Data Width
    Byte 一个字节。
    Half Word 半个字,等于两字节。
    Word 一个字,等于四字节。

五、TIM2通用定时器

5.1 参数配置

Timers 中选择 TIM2 设置,时钟源 Clock Source 选择内部时钟 Internal Clock

Parameter Settings 进行具体参数配置。

  • Prescaler(时钟预分频数):0 则驱动计数器的时钟 CK_CNT = CK_INT(即72MHz)/(0+1) = 72MHz 即不分频
  • Counter Mode(计数模式):Up(向上计数模式)
  • Counter Period(自动重装载值):20-1
  • auto-reload-preload(自动重装载):Disable(不使能)
  • TRGO Parameters(触发输出):Update Event(更新事件) 在定时器的定时时间到达的时候输出一个信号(如:定时器更新产生TRGO信号来触发ADC的同步转换)

5.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输出值
/*** @brief  Starts the TIM Base generation.* @param  htim TIM Base handle* @retval HAL status*/
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);

七、生成正弦波数据表

要输出正弦波,实质是要控制 DAC 以 v=sin(t)的正弦函数关系输出电压,其中 v 为电压输出,t 为时间。 而由于模拟信号连续而数字信号是离散的,所以使用 DAC 产生正弦波时,只能按一定时间间隔输出正弦曲线上的点,在该时间段内输出相同的电压值,若缩短时间间隔,提高单个周期内的输出点数,可以得到逼近连续正弦波的图形,见下图 37-3,若在外部电路加上适当的电容滤波,可得到更完美的图形。

由于正弦曲线是周期函数,所以只需要得到单个周期内的数据后按周期重复即可,而单个周期内取样输出的点数又是有限的,所以为了得到呈 v=sin(t)函数关系电压值的数据通常不会实时计算获取,而是预先计算好函数单个周期内的电压数据表,并且转化成以 DAC 寄存器表示的值。 如 sin 函数值的范围为[-1: +1],而 STM32 的 DAC 输出电压范围为[0~3.3]V,按 12 位 DAC 分辨率表示的方法,可写入寄存器的最大值为 212 = 4096,即范围为[0:4096]。所以,实际输出时,会进行如下处理:

  1. 抬升 sin 函数的输出为正值:v = sin(t)+1 ,此时,v 的输出范围为[0:2];
  2. 扩展输出至 DAC 的全电压范围: v = 3.3*(sin(t)+1)/2 ,此时,v 的输出范围为[0:3.3], 正是 DAC 的电压输出范围,扩展至全电压范围可以充分利用 DAC 的分辨率;
  3. 把电压值以 DAC 寄存器的形式表示:Reg_val = 212/3.3 * v = 211*(sin(t)+1),此时,存储到 DAC 寄存器的值范围为[0:4096];
  4. 实践证明,在 sin(t)的单个周期内,取 32 个点进行电压输出已经能较好地还原正弦波形,所以在 t∈[0:2π]区间内等间距根据上述 Reg_val 公式运算得到 32 个寄存器值,即可得到正弦波表;
  5. 控制 DAC 输出时,每隔一段相同的时间从上述正弦波表中取出一个新数据进行输出,即可输出正弦波。改变间隔时间的单位长度,可以改变正弦波曲线的周期。

生成的正弦波数据表:

[2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668, 3382, 3042, 2661,
2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127, 310, 564, 878, 1240, 1636, 2048]

八、修改main函数

添加正弦波数据表

uint16_t Sine12bit[32] = {2048  , 2460  , 2856  , 3218  , 3532  , 3786  , 3969  , 4072  ,4093   , 4031  , 3887  , 3668  , 3382  , 3042  ,2661   , 2255  , 1841  , 1435  , 1054  , 714   , 428   , 209   , 65    , 3     ,24     , 127   , 310   , 564   , 878   , 1240  , 1636  , 2048
};

添加 HAL_TIM_Base_Start() 函数,启动定时器。
添加 HAL_DAC_Start_DMA()函数,启动 DAC 的 DMA 输出。

uint16_t Sine12bit[32] = {2048  , 2460  , 2856  , 3218  , 3532  , 3786  , 3969  , 4072  ,4093   , 4031  , 3887  , 3668  , 3382  , 3042  ,2661   , 2255  , 1841  , 1435  , 1054  , 714   , 428   , 209   , 65    , 3     ,24     , 127   , 310   , 564   , 878   , 1240  , 1636  , 2048
};/*** @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();MX_TIM2_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start(&htim2);HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)Sine12bit, 32, DAC_ALIGN_12B_R);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

九、实验现象


112500 Hz 即 112.5KHz

十、注意事项

用户代码要加在 USER CODE BEGIN NUSER CODE END N 之间,否则下次使用 STM32CubeMX 重新生成代码后,会被删除。


• 由 Leung 写于 2021 年 3 月 17 日

• 参考:STM32CubeMX系列教程8:数模转换(DAC)
    《嵌入式-STM32开发指南》第二部分 基础篇 - 第8章 模拟输入输出-DAC(HAL库)
    STM32 CubeMX生成DAC+DMA+TIM生成正弦波

STM32CubeMX学习笔记(20)——DAC接口使用(输出正弦波)相关推荐

  1. STM32CubeMX学习笔记(38)——FSMC接口使用(TFT-LCD屏显示)

    一.TFT-LCD简介 TFT-LCD(Thin Film Transistor-Liquid Crystal Display) 即薄膜晶体管液晶显示器.TFT-LCD 与无源 TN-LCD. STN ...

  2. STM32CubeMX学习笔记(24)——通用定时器接口使用(电容按键检测)

    一.电容按键简介 电容器(简称为电容)就是可以容纳电荷的器件,两个金属块中间隔一层绝缘体就可以构成一个最简单的电容.如图 32-1(俯视图),有两个金属片,之间有一个绝缘介质,这样就构成了一个电容.这 ...

  3. STM32CubeMX学习笔记(9)——I2C接口使用(读写EEPROM AT24C02)

    一.I2C简介 I2C(Inter-Integrated Circuit ,内部集成电路) 总线是一种由飞利浦 Philip 公司开发的串行总线.是两条串行的总线,它由一根数据线(SDA)和一根 时钟 ...

  4. STM32CubeMX学习笔记(22)——CRC接口使用

    一.CRC简介 CRC(Cyclic Redundancy Check),即循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者 ...

  5. STM32CubeMX学习笔记(28)——FreeRTOS实时操作系统使用(任务管理)

    一.FreeRTOS简介 FreeRTOS 是一个可裁剪.可剥夺型的多任务内核,而且没有任务数限制.FreeRTOS 提供了实时操作系统所需的所有功能,包括资源管理.同步.任务通信等. FreeRTO ...

  6. STM32CubeMX学习笔记(25)——FatFs文件系统使用(操作SPI Flash)

    一.FatFs简介 FatFs 是面向小型嵌入式系统的一种通用的 FAT 文件系统.它完全是由 ANSI C 语言编写并且完全独立于底层的 I/O 介质.因此它可以很容易地不加修改地移植到其他的处理器 ...

  7. STM32CubeMX学习笔记(27)——FatFs文件系统使用(操作SD卡)

    一.FatFs简介 FatFs 是面向小型嵌入式系统的一种通用的 FAT 文件系统.它完全是由 ANSI C 语言编写并且完全独立于底层的 I/O 介质.因此它可以很容易地不加修改地移植到其他的处理器 ...

  8. STM32CubeMX学习笔记(15)——电源管理(PWR)低功耗睡眠模式

    一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗.由用户根据应用选择具体的低功耗模式,以在低功耗.短启动时间和可用唤醒源之间寻求最佳平衡. 睡眠模 ...

  9. 2020-4-22 深度学习笔记20 - 深度生成模型 5 (有向生成网络--sigmoid信念网络/可微生成器网络/变分自编码器VAE/生产对抗网络GAN/生成矩匹配网络)

    第二十章 深度生成模型 Deep Generative Models 中文 英文 2020-4-17 深度学习笔记20 - 深度生成模型 1 (玻尔兹曼机,受限玻尔兹曼机RBM) 2020-4-18 ...

  10. STM32CubeMX学习笔记(16)——电源管理(PWR)低功耗停止模式

    一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗.由用户根据应用选择具体的低功耗模式,以在低功耗.短启动时间和可用唤醒源之间寻求最佳平衡. 睡眠模 ...

最新文章

  1. [学习笔记]最小圆覆盖
  2. python getopt
  3. macos下载的安装包在哪里_macbook任意降级,为您带来mac os完美降级教程
  4. 软件工程网络15个人阅读作业1 (201521123030 周汉麟)
  5. 特征选择算法-Relief
  6. 渗透测试-信息收集篇
  7. SpringBoot使用快递鸟进行电子面单的获取以及打印
  8. C语言实现EPSG:4326和EPSG:3857的互转
  9. (使用python+adb)能实现王者荣耀自动刷金币?
  10. xcode7的那些坑-“Your binary is not optimized for iPhone 5” (ITMS-90096) when submitting
  11. 关于 python ImportError: No module named 的问题及解决办法
  12. WebViewJavascriptBridge
  13. 微x怎么设置主题_微信主题怎么设置 微信主题设置方法
  14. 新宝综述拉升大阳包阴沪指收复3600点
  15. iOS —— SQLite3 功能使用详解 (三)
  16. 清除页面缓存快捷键-避免重新登陆方式
  17. 为何概述(翻译)CS229这个系列
  18. 超文本传输协议版本 2 [http/2 spec]
  19. 做wish用多大的虚拟服务器,虚拟海外仓适应于wish,ebay,速卖通,自营平台
  20. wingdings字体符号在哪_wingding、Wingdings2、wingdings3字体特殊符号和键盘字母相对应位置.doc...

热门文章

  1. GetDataBack Pro V5.57 功能强大且专业的数据恢复
  2. python猫眼电影分析_抓取猫眼电影
  3. wordpress搜索不了中文linux,WordPress上传带中文汉字名称的图片不显示的解决办法...
  4. 《Java》Java教程
  5. Excel 一些操作记录,方便自己查
  6. python时间序列分析2-平稳时间序列分析
  7. CDH安装指南(Centos6)
  8. QIIME2进阶一_用QIIME2解析序列,诠释生命
  9. m6000查看端口状态_M6000日常查看维护命令 -
  10. 【毕业设计】2-基于单片机控制的直流电机调速系统设计(原理图+仿真+答辩论文+答辩PPT)