WAV和WM8978

WAV

简介

WAVE文件 是最常用的数字化声音文件格式之一
扩展名为 .wav 符合RIFF文件规范
适用Windows平台
支持MS ADPCM 、CCITT A LAW等压缩运算法
支持多种音频数字 取样频率和声道
(MS ADPCM 针对16bit或更高声音波形数据的一种有损压缩算法,它将声音流中每次采样的16bit数据以4bit存储 即压缩比1:4,ADPCM针对连续的波形数据,保存波形的变化情况,已达到描述整个波形的目的
CCITT A LAW 彩铃格式 A率压缩算法

组成

WAV由若干Chunk组成
包括①RIFF WAV Chunk 、②Format Chunk、③Fact Chunk和④Data Chunk
各部分由块标识符(4ASCLL)、数据大小和数据三部分组成

RIFF Chunk
//RIFF块
typedef_packed struct
{
   u32 ChunkID;
   u32 ChunkSize;   //集合大小 文件总大小8
   u32 Format;           //集合大小 WAVE 即0X45564157
}ChunkRIFF;
Format块
//fmt 块
typedef _packed struct
{
    u32 ChunkID;                 //chunk id  固定fmt ,即0X2074D66
    u32 ChunkSize;             //子集合大小
    u16 AudioFormat;          //音频格式 表示线性PCM
    u16 NumOfChannels;    //通道数量 1:单声道 2:双声道
    u32 SampleRate;          //采样率0X1F40 表示8Khz
    u32 ByteRate;               //字节速率 =采样率*通道数*(ADC位数/8)
    u16 BlockAlign;             //块对齐(字节)
     u16 BitsPerSamples;    //单个采样的位数 16位PCM 设置为16
    u16 ByteExtraData;        //附加数据字节2个
}ChunkFMT;
Fact Chunk

非PCM格式的文件中 一般会在Format结构后加入一个FACT块

typedef _packed struct
{
    u32 ChunkID ;    //chunk id 
    u32 ChunkSize;  //子集合大小 这里为4
    u32 DataFactSize; //数据转换为PCM格式后的大小
}ChunkFACT;
Data Chunk

typedef _packed struct
{
u32 ChunkID; //chunk id 固定为data 即0X61746164
u32 ChunkSize; //子集合大小
}ChunkDATA;

数据

在这里插入图片描述
每个取样为4或6个字节 低字节在前 高字节在后
得到WAV数据 经I2S传输到WM8978

WM8978

全功能音频处理 带有HIFI级数字信号处理内核
输出功率达0.9W

特点

I2S接口 支持最高192K 24bit音频播放
DAC信噪比98DB ADC信噪比90DB
支持无电容耳机驱动 扬声器输出 麦克风输入 左右声道音量独立调节 5路EQ调节

接口

通过I2S接口同MCU进行音频数据传输 通过两线(MODE=0,即IIC接口)或三线(MODE=1)接口进行配置
4个引脚组成
ADCDAT: ADC数据输出
DACDAT:DAC数据输入
LRC:数据左右对齐时钟
BCLK :位时钟 用于同步
数据传输协议:
在这里插入图片描述
数据在跟随LRC传输的BCLK的第二个上升沿传输MSB 其他位一直到LSB按顺序传输
LRC频率就是音频信号的采样率
对于STM32F4 提供MCLK时钟 频率必须等于256fs 也就是音频采样率的256倍
在这里插入图片描述

寄存器(9位)

R0寄存器
在这里插入图片描述
用于控制WM8978的软复位 写任意值到该寄存器地址 可实现软复位

R1寄存器:
在这里插入图片描述
第三位设置为1 使模拟部分的放大器工作

R2寄存器:
在这里插入图片描述
R3寄存器:
在这里插入图片描述
ROUT1EN 和 LOUT1EN设置为1 使能耳机 SLEEP=0 进入正常工作模式

R4寄存器:
在这里插入图片描述WL设置字长 00表示16位音频 10表示24位音频 FMT用于设置I2S音频数据格式 10即为飞利浦模式
R6寄存器:
在这里插入图片描述MCLK和BCLK都来自STM32F4

R10寄存器:
在这里插入图片描述
SOFTMUTE设置为0 关闭软件静音
DACOSR128设置为1 DAC得到最好的SNR

R49寄存器
在这里插入图片描述
音量大小:SPKBOOST
TSDEN:过热保护

R50 R51:左右声道
在这里插入图片描述
需要将左右声道DAC输出接入左右声道混合器里面

R52 R53寄存器
在这里插入图片描述
设置耳机输出的左右声道

初始化

初始化WM8978

即配置WM8978 的寄存器

初始化I2S

使能SPI_I2SCFGR 寄存器 设置I2S模式 I2S标准 使能I2S外设

解析WAV文件

获取音频信号采样率和位数并设置I2S时钟分频器

设置DMA

F4具有双缓冲机制 设置为双缓冲循环模式 外设和存储器都是16位宽 开启DMA传输完成中断

编写DMA传输完成中断服务函数

在这里插入图片描述
音频数据流进入DMA 每一个缓冲数据发送完后 硬件自动切换为下一个缓冲 同时进入中断服务函数
填充数据到发送完的这个缓冲

开启DMA传输 填充数据

开启DMA传输 及时填充WAV数据到DMA的两个缓冲区

代码

u8 WM8978_Init(void)
u8 res;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHBlPeriph_GPIOC, ENABLE);
//使能外设GPIOB,GPIOC时钟
//PB12/13 复用功能输出
GPIO InitStructure.GPIO_Pin = GPIO Pin 12 I GPIO Pin 13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_l00MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
//PC2/PC3/PC6复用功能输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 I GPIO_Pin_3|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_lOOMHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPdUP;//上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
GPIO_PinAFConfig(GPIOB,GPIO_PinSourcel2,GPIO_AF_SPI2);//PB12,AF5 I2S_LRCK
GPIO_PinAFConfig(GPIOB,GPIO_PinSourcel3,GPIO_AF_SPI2):;//PB13,AF5 I2S_SCLK
GPIO_PinAFConfig(GPIOC,GPIO_PinSource3,GPIO_AF_SPI2);//PC3 ,AF5 I2S DACDATA
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_SPI2):;//PC6 ,AF5 I2S MCK
GPIO_PinAFConfig(GPIOC,GPIO_PinSource2,GPIO_AF6_SPI2); //PC2 ,AF6 I2S_ADCDATA I2S2ext_SD是AF

IIC_Init();//初始化IIC接口
res=WM8978_Write_Reg(0,0);
//软复位WM8978
if(res)return 1;
//发送指令失败,WM8978异常
//以下为通用设置
WM8978_Write_Reg(1,0X1B);//R1,MICEN设置为1(MIc使能),BIASEN设置为1(模拟器工作),VMIDSEL[1:0]设置为:11(5K)
WM8978_Write_Reg(2,0X1B0); //R2,ROUT1,LOUT1输出使能(耳机可以工作),BOOSTENR,BOOSTENL使能
WM8978_Write_Reg(3,0X6C);//R3,LOUT2,ROUT2输出使能(喇叭工作),RMIX,LMIX使能
WM8978_Write_Reg(6,0);
//R6,MCLK由外部提供
WM8978_Write_Reg(43,1<<4);
//R43,INVROUT2反向,驱动喇叭
WM8978_Write_Reg(47,1<<8);
//R47设置,PGABOOSTL,左通道MIC获得20倍增益
WM8978_Write_Reg(48,1<<8);
//R48设置,PGABOOSTR,右通道MIC获得20倍增益
WM8978_Write_Reg(49,1<<1);
: //R49,TSDEN,开启过热保护
WM8978_Write_Reg(10,1<<3);
//R10,SOFTMUTE关闭,128x采样,最佳SNR
WM8978_Write_Reg(l4,l<<3);
//R14,ADC 128x采样率
return 0;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

。✧* ꧁流痕꧂✧*。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值