一、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、音频波形