你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用PWM实现语音播放

[复制链接]
y369369 发布时间:2021-4-23 16:16
使用PWM实现语音播放
事实上大部分MCU都可以实现语音播放
" K0 o  N' L$ X5 h. t* N
下面是一段音频数据的波形

5 n8 C1 N4 k) H, }' S7 s: j, s; n2 [
1.1.png
1 M2 F; C" @& C+ J$ @6 x
局部放大图:

% q: T5 k! ^' b( G% s8 [
1.2.png

$ B9 V7 F5 Y: l# ~- c' g
以一定的速度采样(ADC)这些波形进行存储,就是音频数据了,所以播放就是按原来采样的速率再用DAC输出对应的数据即可。
% P/ n& \* d6 l, a3 y, r! r
这里的音频有两个主要的参数,采样速率和采样位数。

; n- q0 i6 A8 x7 |
采样速率:指1s中采样多少个数据点,比如1s种采集16000个点,那么采样率就是16KHz。采样速率越高,越能抓到频率较高的声音,比如CD的采样率就是44.1KHz,确保人耳能听到的声音都会被抓到。

; ^$ V4 s+ q% Z; g+ E) z/ f
采样位数:指音频幅度最大值与最小值分为了多少阶,比如满幅度是3.3V,如果是8Bit位数,那么每一阶就是3.3V/256 = 12.89mv,采样位数越高,声音细节越好。所以采样速率和位数越高,声音还原越逼真,但存储的数据量也越大,一首三四分钟的歌曲,如果不采用编码按原始波形数据存储,数据量有好几十兆大小,这涉及到音频编码的问题,这里不展开讲了,有兴趣的同学可以找相关资料。
$ s7 z3 }$ `% F# W! o
接下来看怎么播放,最简单的当然是把采样(ADC)的数据按原样输出(DAC)了。但我们有些芯片本身不带有DAC,所以只能用PWM代替DAC,PWM即脉冲宽度调制。这里只需要把DAC的幅度值转换成PWM的占空比即可,例如16KHz 8Bit的声音转换成16Khz 256阶占空比的PWM。但有一个问题,如果用16KHz的PWM播放语音,声音是可以播放,但有一个16Khz的谐波存在,这个声音会被人耳听到,所以需要更高频率的PWM,数据还是按照16Khz更新。

+ @) `. ~/ E# |6 u1 V, B
我这里使用32KHz的PWM,用16KHz 8Bit PCM格式的音频数据,8Bit的数据对应一个Byte,16KHz采样,1秒种占用存储空间就是16K Byte,F429有2MByte的Flash存储空间,理论上可以存储2048K/16K= 128秒的音频。

* a7 T$ Y/ p/ u: T6 b
下面是用NucleoF429实现音频播放的具体过程:
3 [  M! y- L$ B& K7 o. {: [0 t4 S- e
一、配置PWM
  n; a# ]/ j# {9 ?: D
1、用STM32CubeMx建立工程,配置两个定时器TIM1和TIM2,TIM用于PWM产生,TIM2用于16KHz数据更新。
+ L2 L, q3 z9 r% {% S
1.3.png

* j1 |: }% L% }4 {# u8 X* f
TIM1选择PWM互补输出(单通道也可以),将PE8和PE9复用为PWMN和PWMP。
0 u- s9 \" W, e& U3 h( s* l
TIM1在APB2总线上,TIM2在APB1总线上

# {/ u6 y) Q, D% f; i/ F
1.4.png

' x  k6 v: {' R2 u7 y: r- J
所以TIM1和TIM2的时钟频率分别为180M和90M,系统时钟用HSE输入的8MHz。
7 z! \+ [) @& Q. s: Q
1.5.png
! M! ]/ y* h  l* z. l+ g7 T
将TIM1设置为32KHz,即31.25us。8Bit占空比,一个LSB为31.25us / 256 = 0.1220703125us = 8.192MHz,TIM1180M / 8.192M = 21.97265625,这里取整数22。所以实际的PWM频率为1/(180 / 22) *256 =  31.289us = 31.96KHz
4 t- d4 a$ F: M0 o4 P6 l9 m3 g' G
1.6.png

( f; |: F0 \3 [
TIM2 为90MHz,45分频后为2MHz即0.5us,周期125即62.5us = 16KHz。

2 }% D  F% b7 a4 G5 |
1.7.png

6 ^# B0 W: V9 t5 K/ u
NVIC开启TIM2中断。生成工程名和目录后生成Keil工程。
9 B; l$ w) e0 ]2 @# s/ F! x
二、播放语音
1、先编译后,编写TIM中断服务程序。
1.8.png

- e. c+ P( V0 {3 W+ g: L
完成后,开启TIM2中断和PWM,(PWM是互补输出,需要单独开启各个通道)
& O2 h+ o0 K9 L4 z
1.9.png
) r- F2 |$ x: Y% W, Y5 s0 z& M; z
用逻辑分析仪测量输出波形。

' N5 K7 f9 `  g8 v( ?* g9 r+ x
1.10.png

( D  F& N9 Y3 s
如图所示,TIM1 PWM为31.96KHz,TIM2为62.5us即16KHz,结果正确。

8 e" D% X0 s' @; |& ~' h1 x
接下来处理音频:
这里使用的音频是PCM格式,是未进行压缩编码的原始数据,可以直接给PWM输出。

) ^5 Q$ o5 ]- m/ @+ r% `0 U# k$ `
音频处理的软件有许多,只要能把格式转为PCM即可,下面是我用Cool Edit这款软件做的音频格式转换。
0 r$ z8 O: c$ n' y
选择菜单 文件-->批量转换
1 }% E' Y$ w  [2 U+ r# `+ |
1.11.png
. d# `/ I" i% U
选择新的采样率和采样位数。

# ]! r5 Y& ~( C6 |: u& O! u
1.12.png
1 ^% m5 r. ^# j4 R8 j
选择PCM格式。设置输出目录后运行批处理完成转换。
! i( S6 I# I/ S, z# u  u, U; |
1.13.png
( f  e+ Y" @! T$ W$ ^% K$ p
完成后的音频文件用WinHeX这个软件打开。
9 P/ ~/ }" V: n% V  o: g
1.14.png
0 i. S' c3 T$ J. G  R8 r: e6 w
图中红框中的44个Byte为PCM格式的文件头信息,后面的的数据为音频数据,数据全选后利用WinHex的可选格式复制

$ R- _1 h9 G( u* ]  `8 U* o9 [
1.15.png
: W+ b, C& c  D) C% `2 S" U' a, p( p
将数据以C数组的形式导出,在工程目录下新建.h文件,将复制的文件粘帖到.H文件并在工程中Include进来,定义起始和结束地址,数组的大小即为文件结束地址,数组用const修饰,可以将数据存储到Flash中。
. C1 ~2 s) y7 z6 F% M! H" W
1.16.png

: a' Q8 k" ~% }6 Q9 V6 O" ^
在TIM2中,以16KHz的速度更新PWM数据即可实现音频播放。
2 J$ J- I  x2 T' U* u( F
1.17.png
7 s& Q; S) e( S7 X! L$ O
编译工程,下载到NucleoF429板子上,在PE8或PE9上接一个喇叭即可听到声音。

+ {( U' ?# x( R" Z' u& V2 x
以上用的音频采样是16K 8Bit,要想提高音质,提高采样和Bit数即可,音量可以用外接三极管或功放放大,音频数据也可以用ADC采集后存储到SPI Flash后播放,实现录音回放。
: c0 S4 R- Z$ V
为了方便阅读,附件中包含了此文的PDF文档,Source Code也在附件中,可以直接下载到Nucleo运行。
1 U% A0 }0 j: o7 s* ~
文章出处: ARM中文社区

/ F7 F* o4 [) o
收藏 评论0 发布时间:2021-4-23 16:16

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版