stm32的DAC输出

一、DAC原理

DAC 为数字/模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对 应的模拟电压输出,它的功能与 ADC相反。在常见的数字信号系统中,大部分传感器信号 被化成电压信号,而 ADC把电压模拟信号转换成易于计算机存储、处理的数字编码,由计 算机处理完成后,再由 DAC输出电压模拟信号,该电压模拟信号常常用来驱动某些执行器 件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。 STM32具有片上 DAC外设,它的分辨率可配置为 8位或 12位的数字输入信号,具有 两个 DAC 输出通道,这两个通道互不影响,每个通道都可以使用 DMA 功能,都具有出错 检测能力,可外部触发。

在这里插入图片描述
整个 DAC模块围绕框图下方的“数字至模拟转换器 x”展开,它的左边分别是参考电 源的引脚:𝑉𝐷𝐷𝐴、𝑉𝑆𝑆𝐴及𝑉𝑟𝑒𝑓+,其中 STM32 的 DAC 规定了它的参考电压𝑉𝑟𝑒𝑓+输入范围为 2.4——3.3V。“数字至模拟转换器 x”的输入为 DAC 的数据寄存器“DORx”的数字编码, 经过它转换得的模拟信号由图中右侧的“DAC_OUTx”输出。而数据寄存器“DORx”又 受“控制逻辑”支配,它可以控制数据寄存器加入一些伪噪声信号或配置产生三角波信号。 图中的左上角为 DAC的触发源,DAC根据触发源的信号来进行 DAC转换,其作用就相当 于 DAC转换器的开关,它可以配置的触发源为外部中断源触发、定时器触发或软件控制触 发。如本章实验中需要控制正弦波的频率,就需要定时器定时触发 DAC进行数据转换。

二、DAC初始化

1、定时器初始化
在这里插入图片描述
TIM2的定时周期被配置为 20,向上计数,不分频。即 TIM2 每隔 20*(1/72M)秒就会触发一次 DAC 事件,作 DAC触发源使用的定时器并不需要设置中断,当定时器计数器向上计数至指定的 值时,产生Update事件,同时触发DAC把DHRx寄存器的数据转移到DORx,从而开始进 行转换。

2、DAC初始化
在这里插入图片描述
在 DAC_Config 函数中,完成了 DAC 通道的 GPIO 的初始化和 DAC 模式配置。其中 GPIO 按照要求被配置为模拟输入模式(没有模拟输出模式),在该模式下才能正常输出模 拟信号。 配置 DAC 工作模式时,则使用了 DAC_InitTypeDef 类型的初始化结构体,把 DAC 通 道 1 和 2 都配置成了使用定时器 TIM2 触发、不使用波形发生器以及不使用 DAC 输出缓冲 的模式。 初始化完 GPIO 和 DAC 模式后,还使用了 DAC_Cmd、DAC_DMACmd 函数使能了通 道以及 DMA 的请求。由于本实验中对 DAC1 和 2 的操作是同步的,所以只要把 DMA 与 DAC通道 2关联起来即可,当使用DMA设置通道2的数据值时,同时更新通道1的内容。

3、输出波形周期计算
在这里插入图片描述

三、输出正弦波

1、计算需要生成点数

需要2000Hz的正弦波,由上述公式计算得出需要生成1800个点。
可用以下python代码生成采样点

#! python3
#coding=utf-8

"""
Python版本:3.x
外部库:matplotlib1.5.3、numpy1.11.2

运行方式:
在命令行中输入:python sinWave.py 

运行结果:
命令行中会打印计算得的各点数据,
在当前目录下会生成py_dac_sinWav.c文件,包含上述数据,
并且会弹出描绘曲线的对话框。
"""

import matplotlib.pyplot as plt 
import numpy as np
import math

#修改本变量可以更改点数,如16、32、64等
POINT_NUM = 32

pi = math.pi

#一个周期 POINT_NUM 个点
n = np.linspace(0,2*pi,POINT_NUM)

#计算POINT_NUM个点的正弦值
a = map(math.sin,n)

r =[]
for i in a:
    #调整幅值至在0~1区间
    i+=1       
    
    #按3.3V电压调整幅值
    i*= 3.3/2   

    #求取dac数值,12位dac LSB = 3.3V/2**12 
    ri = round(i*2**12/3.3) 

    #检查参数
    if ri >= 4095:
        ri = 4095

    #得到dac数值序列
    r.append( ri )


print(list(map(int,r)))

#写入序列到文件
with open("py_dac_sinWav.c",'w',encoding= 'gb2312') as f:
    print(list(map(int,r)),file= f)

#绘图
plt.plot(n,r,"-o")
plt.show()




2、将生成的采样点放入dac.c文件的采样点数组
在这里插入图片描述
3、2000Hz正弦波形
在这里插入图片描述

四、输出音频

1、生成音频数据

  • 使用AU软件编辑音频文件,截取3s-5s的音频,以8000Hz的采样率,生成16位的wav文件
    在这里插入图片描述
    在这里插入图片描述
    2、使用Uedit等工具打开生成的wav文件
    在这里插入图片描述
    3、选择中间数据区域的数据,保存在文本文件中,使用以下代码,增加前缀0x
import re

path=r'C:\Users\G3\Desktop\test.txt'	#文件路径
t=re.compile(r'\d\d')
file=open(path)	
txt=file.read()
print(file.read())
file.close()
test=t.findall(txt)

file=open(path,'w')
j=0
for i in test:
    i=''.join(['0x',str(i),', '])
    if j == 16:
        j = 0
        file.write('\n')	#换行
    file.write(i)
    j = j + 1
file.close()

4、将转换好的内容复制到上面正弦波的数据数组中
在这里插入图片描述
5、音频波形
在这里插入图片描述

STM32中的DAC输出是指将数字信号转换成模拟信号的过程,在嵌入式系统开发中广泛运用。在STM32中,可以通过设置系统时钟和打开DAC输出通道来实现DAC输出功能。首先,需要设置系统时钟以确保DAC模块正常工作。然后,打开DAC输出通道,可以通过生成代码并在User Code 2处开启DAC通道来实现。通过将数值映射成端口的电压值,并通过大量的采样点输出,可以实现输出指定波形的目的。 在DAC转换过程中,不能直接对DAC_DORx寄存器进行写入数据,而是需要将数据写入到DAC_DHRx寄存器中。具体来说,输出DAC通道x的数据必须写入到DAC_DHRx寄存器中,其中x表示通道的编号。如果选择了软件触发模式,即将寄存器DAC_CR1的TENx位置为0,那么存入DAC_DHRx寄存器的数据会在一个APB1时钟周期后自动传输到DAC_DORx寄存器。如果选择了硬件触发模式,即将寄存器DAC_CR1的TENx位置为1,那么数据传输将在触发事件发生后的3个APB1时钟周期内完成。一旦数据从DAC_DHRx寄存器传输到DAC_DORx寄存器后,在经过一段时间的tSETTLING之后,输出电压即可有效。这段时间的长短会受到电源电压和模拟输出负载的影响。 总结来说,STM32中的DAC输出是通过将数字信号转换成模拟信号的过程实现的。可以通过设置系统时钟、打开DAC输出通道,并将数据写入到DAC_DHRx寄存器中来实现DAC输出功能。在输出电压有效前需要经过一段时间的tSETTLING,并受到电源电压和模拟输出负载的影响。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值