STM32之音频数据的Flash读取与DAC播放

文章目录

  • 一. STM32103之内部Flash原理
    • 1. Flash介绍
    • 2. Flash的组成
    • 3. STM32内部框架图
  • 二. SD卡的读写
    • 1. 实验过程
    • 2. 查看hello.txt
    • 3. 从SD卡里读出数据
  • 三. Flash地址空间的数据读取
    • 1. Flash写入流程
    • 2. 配置STM32CubeMX
    • 3. 修改代码
    • 4. 设置ST-Link
    • 5. Keil配置
    • 6. 调试程序
  • 四. 实例——基于片内Flash的提示音播放程序
    • 1. DAC介绍
    • 2. 使用DAC输出周期2KHZ的正弦波
    • 3. 数字音频还原播放
  • 五. 总结
  • 六. 参考资料

一. STM32103之内部Flash原理

1. Flash介绍

Flash 中文名字叫闪存,是一种长寿命的非易失性(断电数据不丢失)的存储器,可以对称为块的存储器单元块进行擦写和再编程,在进行写入操作之前必须先执行擦除。
一个Nand Flash由多个块(Block)组成,每个块里面又包含很多页(page)。每个页对应一个空闲区域/冗余区域(spare area),这个区域不是用来存储数据的,用于放置数据的校验值检测和纠错的。
块,是Nand Flash的擦除操作的基本/最小单位。
页,是Nand Flash的写入操作的基本/最小的单位。

2. Flash的组成

STM32F1 的闪存(Flash)模块由:主存储器信息块闪存存储器接口寄存器三部分组成

模块 作用
主存储器 该部分用来存放代码和数据常数(如 const 类型的数据)。对于大容量产品,其被划分为 256 页,每页 2K 字节。注意,小容量和中容量产品则每页只有 1K 字节。从上图可以看出主存储器的起始地址就是0X08000000, BOOT0、BOOT1 都接 GND 的时候,就是从 0X08000000 开始运行代码的。
信息块 该部分分为 2 个小部分,其中启动程序代码,是用来存储 ST 自带的启动程序,用于串口下载代码,当 BOOT0 接 V3.3, BOOT1 接 GND 的时候,运行的就是这部分代码。用户选择字节,则一般用于配置写保护、读保护等功能
闪存存储器接口寄存器 该部分用于控制闪存读写等,是整个闪存模块的控制机构。对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压由内部产生。

在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;
在进行写或擦除操作时,不能进行代码或数据的读取操作。
它们的地址分布及大小如下:
STM32之音频数据的Flash读取与DAC播放_第1张图片
STM32的Flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的Flash大小,不同的芯片flash大小不同。

3. STM32内部框架图

STM32F103系列的FLASH 容量一般为 512K 字节,属于大容量芯片

  • STM32内部框架图
    STM32之音频数据的Flash读取与DAC播放_第2张图片
    其中的SRAM为静态随机存取存储器,是随机存取存储器的一种,只要保持通电,里面储存的数据就可以恒常保持。但是当电力供应停止时,SRAM储存的数据是会消失的;而Flash不会断电丢失数据的特性就被无限放大。

二. SD卡的读写

在SD卡创建一个.txt文件,循环(不加延时)分批一次写入256字节,累计写入不少于64KB字节;然后读取此文件数据,通过串口显示出来,并分析写入和读取的速率。

具体操作参考博客:STM32F103之完成对SD卡的数据读取

1. 实验过程

  • 打开串口助手,观察输出结果
    STM32之音频数据的Flash读取与DAC播放_第3张图片
    总共用了12分钟,写了64K字节。

2. 查看hello.txt

STM32之音频数据的Flash读取与DAC播放_第4张图片

3. 从SD卡里读出数据

利用FATS从SD卡读出数据,并且串口输出
(1)代码修改

  • 因为要进行读取,所以将写入部分的函数改为读出函数
    STM32之音频数据的Flash读取与DAC播放_第5张图片
  • 声明读出函数,定义双字节数据类型s,用来保存地址(或者存放指针),再定义字节类型格式的变量和一个存储读取的数组
    STM32之音频数据的Flash读取与DAC播放_第6张图片
    ① 修改f_open函数的第三个参数设置为打开状态为FA_READ模式
    ②文件指针移至相应位置,否则无输出
    ③指针加地址
    ④使用FATS的read函数,第一个参数是指针,第二个是存储数组,第三个是数组大小,第四个是强制转换br为UINT格式
    ⑤输出
    STM32之音频数据的Flash读取与DAC播放_第7张图片
    (2)结果显示
    STM32之音频数据的Flash读取与DAC播放_第8张图片

三. Flash地址空间的数据读取

STM32F103C8T6只有20KB内存(RAM)供程序代码和数组变量存放,因此针对内部Flash的总计64KB存储空间(地址从0x08000000开始),运行一次写入8KB数据,总计复位运行代码4次,将32KB数据写入Flash。并验证写入数据的正确性和读写速率。

链接:https://pan.baidu.com/s/11Tn8TocHT8qithneDyKFIQ
提取码:pmvn

1. Flash写入流程

  1. 解锁(固定的KEY值)
    由于内部 FLASH 空间主要存储的是应用程序,是非常关键的数据,为了防止误操作修改了这些内容,芯片复位后默认会给控制寄存器 FLASH_CR 上锁,这个时候不允许设置 FLASH 的控制寄存器,从而不能修改 FLASH 中的内容。所以对 FLASH 写入数据前,需要先给它解锁。
    解锁的操作步骤如下:
    (1)往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123
    (2)再往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB

  2. 页擦除
    在写入新的数据前,需要先擦除存储区域,STM32 提供了页(扇区)擦除指令和整个 FLASH 擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。
    页擦除的过程如下:
    (1)检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何 Flash 操作;
    (2)在 FLASH_CR 寄存器中,将“激活页擦除寄存器位 PER ”置 1;
    (3)用 FLASH_AR 寄存器选择要擦除的页;
    (4)将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;
    (5)等待 BSY 位被清零时,表示擦除完成。
    STM32之音频数据的Flash读取与DAC播放_第9张图片

  3. 写入数据
    擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还需要配置一系列的寄存器,步骤如下:
    (1)检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;
    (2)将 FLASH_CR 寄存器中的 “激活编程寄存器位 PG” 置 1;
    (3)向指定的 FLASH 存储器地址执行数据写入操作,每次只能以 16 位的方式写入;
    (4)等待 BSY 位被清零时,表示写入完成。
    STM32之音频数据的Flash读取与DAC播放_第10张图片

2. 配置STM32CubeMX

  • 时钟配置
    STM32之音频数据的Flash读取与DAC播放_第11张图片
  • SYS 配置
    STM32之音频数据的Flash读取与DAC播放_第12张图片
  • 设置PC13为GPIO_Output
    STM32之音频数据的Flash读取与DAC播放_第13张图片
  • 使能GPIO引脚
    STM32之音频数据的Flash读取与DAC播放_第14张图片
  • 设置堆栈大小为4K
    STM32之音频数据的Flash读取与DAC播放_第15张图片
    之后导出即可

3. 修改代码

  1. 将准备好的flash.h加入到工程中
    STM32之音频数据的Flash读取与DAC播放_第16张图片
  2. 在main.c中添加代码
  • 修改数组大小
    STM32之音频数据的Flash读取与DAC播放_第17张图片
  • 添加头文件 #include "flash.h"
    在这里插入图片描述
  • 修改数据内容
    STM32之音频数据的Flash读取与DAC播放_第18张图片
  • 读取数据
    STM32之音频数据的Flash读取与DAC播放_第19张图片
    编译后没有错误

4. 设置ST-Link

电路连线:

ST-Link STM32F103
SWCLK/TCK SWCLK/TCK
SWDIO/TMS SWDIO/TMS
GND GND
VCC VCC

STM32之音频数据的Flash读取与DAC播放_第20张图片
连接好后,安装好ST-Link驱动
链接:https://pan.baidu.com/s/1cmreV0
安装好驱动后,上电,查看设备管理器,可以看到STLink在电脑上显示出来
STM32之音频数据的Flash读取与DAC播放_第21张图片

5. Keil配置

  • 进入keil 配置,设置Debug为ST-Link Debugger
    STM32之音频数据的Flash读取与DAC播放_第22张图片
  • 点击Settings可以看到要检测出SWDIO有信息
    STM32之音频数据的Flash读取与DAC播放_第23张图片

6. 调试程序

  • 点击LOAD将程序下载到STM32中
    STM32之音频数据的Flash读取与DAC播放_第24张图片
    注意:download后,要将STM32调整为工作模式,并按下复位键
  • 进入Debug,全速运行,View->memory windows->memory 1打开内存观察窗口
    STM32之音频数据的Flash读取与DAC播放_第25张图片
    并在地址栏中输入0x800c000后回车
    在这里插入图片描述
  • 在Memory1窗口可观察到成功写入内容
    STM32之音频数据的Flash读取与DAC播放_第26张图片
  • View->Watch windows->Watch 1打开一个变量观察窗口
    STM32之音频数据的Flash读取与DAC播放_第27张图片
    在main.c文件中,找到变量FlashWBuff 和FlashRBuff,右健单击 'Add FlashWBuff’ to watch1,将变量FlashWBuff 和 FlashRBuff加入到 Watch 1 观察窗口
    STM32之音频数据的Flash读取与DAC播放_第28张图片
  • 全速运行,可以观察到FlashWBuffFlashRBuff内容相同
    STM32之音频数据的Flash读取与DAC播放_第29张图片

四. 实例——基于片内Flash的提示音播放程序

1. DAC介绍

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

STM32的DAC模块主要特点有:

  • 2个DAC转换器,每个转换器对应1个输出通道
  • 8位或12位单调输出
  • 12位模式下数据左对齐或右对齐
  • 同步更新功能
  • 噪声波形形成
  • 三角波形形成
  • 双DAC通道同时或者分别转换

DAC结构框图如下
STM32之音频数据的Flash读取与DAC播放_第30张图片

2. 使用DAC输出周期2KHZ的正弦波

建议先用单音音频(比如2000Hz的正弦波)的wav数据进行实验,通过DAC或PCM音频模块能够基本还原出原始正弦波声音后,再用语言/音乐信号进行实验。

工程链接:https://pan.baidu.com/s/1gEATonRXK7km3yf-Mu0eEQ
提取码:1234

  • 打开Adobe Audition CS6,点击文件->新建->音频文件
    STM32之音频数据的Flash读取与DAC播放_第31张图片
  • 效果->生成基本音色
    STM32之音频数据的Flash读取与DAC播放_第32张图片
  • 文件->导出->设置导出为wav文件
    STM32之音频数据的Flash读取与DAC播放_第33张图片
  • 用UltraEdit打开刚才保存的wav文件
    STM32之音频数据的Flash读取与DAC播放_第34张图片
  • CTRL+A,接着鼠标右键,选择十六进制复制选定视图,将内容粘贴到一个新建文件中
    在新建文件中,CTRL+A,然后右键,选择范围输入起始的行号和列号,确定就选中了整个内容
    STM32之音频数据的Flash读取与DAC播放_第35张图片
  • 然后将上面选中的内容复制到notepad++中,Edit->Column editor(列块编辑-)>输入,0x
    点击第一行的每个数字后面,列编辑插入,0x
    STM32之音频数据的Flash读取与DAC播放_第36张图片
  • 将生成的十六进制写入FLASH
    打开keil工程的bsp_dac.c文件,将内容复制波形数据位置,在下图中进行替换
    STM32之音频数据的Flash读取与DAC播放_第37张图片
    STM32之音频数据的Flash读取与DAC播放_第38张图片
    然后编译下载,看能否观察到预期的正弦波

3. 数字音频还原播放

编程读取此段音频,通过stm32f103c8t6自带的DAC通道,转换为模拟音频进行播放,并用示波器观察波形,用耳机/喇叭收听,评判音乐还原效果。

  • 用Adobe Audition CS6打开一个音频文件
    STM32之音频数据的Flash读取与DAC播放_第39张图片
  • 右键,点击存储选择为,然后更改参数
    STM32之音频数据的Flash读取与DAC播放_第40张图片
  • 点击确定,完成
    STM32之音频数据的Flash读取与DAC播放_第41张图片
    接下来用“使用DAC输出周期2KHZ的正弦波”一样的方法:
    ① 用UltraEdit打开刚才保存wav文件-> ② 选择十六进制复制选定视图,将内容粘贴到一个新建文件中-> ③ 将选中的内容复制到notepad++中-> ④ 采用列编辑,在每一列前面加上0x-> ⑤ 将生成的音频十六进制写入FLASH-> ⑥ 打开keil中的文件bsp_dac.c,将正弦波数据换成音频文件生成的数据(刚刚从FLASH写入并读出的数据)-> ⑦ 替换后,烧录程序,通过DAC模块可收听音乐。

五. 总结

本文介绍了STM32内部的Flash原理,以及认识了DAC。通过实例——使用DAC输出周期2KHZ的正弦波和使用STM32F103的DAC功能实现音频输出,进一步了解了Flash的写入过程,将音频文件写入Flash比较复杂,要通过采用audition、ultraedit、notepad++ 手工将wav音频数据提取、再将音频歌曲数据转换为模拟音频波形输出(循环)一系列过程才能成功做出来。

六. 参考资料

https://blog.csdn.net/lushoumin/article/details/87694389
https://www.cnblogs.com/pertor/p/9484663.html
https://blog.csdn.net/zhanglifu3601881/article/details/96632971
https://www.jianshu.com/p/a0c6ec6fcff4
https://blog.csdn.net/qq_43279579/article/details/111990896
https://blog.csdn.net/qq_45748462/article/details/112392144

你可能感兴趣的:(stm32,音视频,arm)