下面是当时我实现该需求的具体思路,基本上以库函数为基础,再深层次的研究并未考虑。




所使用的库

STM32F103ZET6 库函数版本

参考资料

STM32中文参考手册_V10.pdf ->12.3.8 噪声产生(点我下载相关资料)

esp32 i2s 音质不好_arm

整体思路

定时器5自动重装载值,利用其更新事件触发 DACDAC 通道2输出噪声。

具体思路(使用DAC通道2输出噪声)

  1. 通过阅读,有以下关键词:
    WAVE[1:0]位DAC_CR寄存器的MAMPx[3:0]位WAVEx[1:0]DAC_CR寄存器的TENx位
  2. PDF 中查找 WAVEx[1:0],并向下查询,可以发现如下信息

    这两者不同点在于:
    12.4.2 说两个 DAC 通道使用相同的 LSFR 屏蔽值,从而产生幅度相等的噪声;
    12.4.3 说两个 DAC 通道使用不同的 LSFR 屏蔽值,从而产生幅度不等的噪声。
    我下面以单个 DAC 通道输出噪声为例,进行说明。
  3. 首先设置 DAC 通道的触发使能位 TEN21
    PDF 中搜索 TEN1,得到下图,说明 TENxDAC_CR 寄存器中。

    打开库函数例程,找到 DAC 实验,找到 DAC 初始化函数。红框中的注释提示,结构体成员 DAC_Trigger 的值包含了对 TENx 的设置。

上图蓝框中的函数是对 DAC_InitType 结构体中各成员的初始化,即是对 DAC 各寄存器的相关位置的初始化。

打开上述函数定义,得下图,即可验证“DAC_Trigger 的值包含了对 TENx 的设置”的观点。

esp32 i2s 音质不好_stm32_02


也就是说,设置了 DAC 触发源,就同时设置了 TENx 位,所以不用担心漏掉对 TENx 位的定义。

4. 通过设置 TSEL2[2:0] 位为不同值,配置 DAC 通道2的触发源。

DAC 实验例程中全工程搜索 TSEL(不全字匹配),得知对 DAC_CR 寄存器的 TSEL 位赋值,与 DAC_Trigger 有关。

esp32 i2s 音质不好_stm32_02


在自定义 DAC 初始化函数中,如下图红框所示,设置 DAC 的触发事件是定时器5。

esp32 i2s 音质不好_寄存器_04

  1. DAC_CR 寄存器中,设置 DAC 通道2的 WAVE2[1:0] 位为 01
  2. esp32 i2s 音质不好_arm_05

  3. DAC 例程中搜索 WAVE,如下图,则需要改 DAC_WaveGeneration 的值。
  4. esp32 i2s 音质不好_stm32_06

  5. 在自定义 DAC 初始化函数中,设置 DAC_WaveGeneration 的值为 DAC_WaveGeneration_Noise
  6. MAMP2[3:0] 为特定的 LFSR 屏蔽值,从而控制噪声的幅度。

    DAC 例程中搜索 MAMP,如下图所示,需要设置 DAC_LFSRUnmask_TriangleAmplitude 的值。

    在自定义 DAC 初始化函数中,设置该参数的值。为了使结果更显眼,我选择了最大的值。
  7. DAC 的其他设置
  8. 关闭定时器5的中断
  9. 设置 TIM5 通道1的更新事件触发 DAC 产生噪声(可以参考 PWM 输出实验例程)

波形结果

esp32 i2s 音质不好_单片机_07


改变示波器的视野,即可得到近似于噪声的波形。

注意

STM32F103ZET6英文版芯片手册 中,搜索 DAC2,得到输出引脚是 PA5

esp32 i2s 音质不好_esp32 i2s 音质不好_08

应用

STM32 实现连续信号和离散信号的傅里叶变换

工程下载

点我下载