【紫光同创国产FPGA教程】【第十一章】录音与播放例程

描述

 

原创声明:

本原创教程由芯驿电子科技(上海)有限公司(ALINX)创作,版权归本公司所有,如需转载,需授权并注明出处(alinx.com)。

适用于板卡型号:

PGL22G/PGL12G

1. 实验简介

本实验的录音和播放实验因为开发板上没有音频部分的电路,需要外接一个芯驿电子的AUDIO音频模块AN831。

 

 

 

 

AN831

音频模块上有三个音频连接器,其中粉色的接口为麦克风输入;绿色的接口为耳机输出;蓝色的接口为音频输入, 用于连接DVD等音频输出口。本实验将实现音频模块和FPGA之间的数据通信, 通过音频模块把麦克风输入的语音数据存储到SDRAM存储器里, 再把音频数据发送给音频模块,从耳机接口进行语音的播放,从而实现录音和播放的功能。

2. 实验原理

2.1 硬件介绍

开发板通过40PIN的扩展口和AN831音频模块连接,AN831音频模块使用WOLFSON公司的WM8731芯片实现声音信号的A/D和D/A转换功能。以下为AN831音频模块的硬件电路:

 

 

开发板

 

 

2.2 WM8731配置和时序

这里简单介绍一下音频模块AN831用到的音频编/解码芯片WM8731。该芯片在本设计中主要完成声音信号在采集和回放过程中的A/D和D/A转换功能。该芯片的ADC和DAC的采样频率为8KHz到96KHz可调,可转换的数据长度为16-32位可调。WM8731的内部有11个寄存器。该芯片的初始化以及工作时的工作状态和功能都是通过以I2C总线方式对其内部的这11个寄存器进行相应的配置来实现的。本设计中WM8731工作于主模式,采样频率设为48KHZ,转换的数据位长度为16位。WM8731的数字音频接口有5根引脚,分别为:BCLK(数字音频位时钟)、DACDAT(DAC数字音频数据输入)、DACLRC(DAC采样左/右声道信号)、ADCDAT(ADC数字音频信号输出)、ADCLRC(ADC采样左/右声道信号)。在本设计中FPGA为从设备,WM8731为主设备。ADCDAT、DACDAT、ADCLRC和DACLRC与位时钟BCLK同步,在每个BCLK的下降沿进行一次数据传输。BCLK、DACDAT、DACLRC、ADCLRC为WM8731的输入信号。ADCDAT为WM8731的输出信号。

 

开发板

 

在本系统中FPAG和WM8731的控制和数据通信将用到I2C和数字音频总线接口。FPGA通过I2C接口配置WM8731的寄存器,通过I2S总线接口来进行音频数据的通信。关于I2C接口,其他实验中已经有讲解,下面我们主要来了解数字音频接口。

数字音频接口可提供4种模式:

  • Right justified

  • Left justified

  • I2S

  • DSP mode

 

开发板Left justified模式开发板I2S模式开发板Right justified模式开发板DSP/PCM 模式(MODE A)开发板DSP/PCM 模式(MODE B)

 

本实验选择Right justified模式。

 

开发板

 

3. 程序设计

本实验的功能是程序检测按键KEY2是否按下,如果检测到KEY2按下了,开始录音,录音的最长时间为20秒;录音结束后,开始播放刚才录下的音频。本程序设计包含四大部分:SDRAM的读写控制程序,音频录音和播放,按键检测和系统控制。

lut_wm8731模块将寄存器配置地址和配置信息通过查找表的形式通过I2C总线写入音频模块中,具体的请参考例程代码和wm9731的芯片数据手册。

audio_rx接收模块,接收从麦克风输入的语音信号,完成左右声道的音频接收,将串行数据转换成并行数据。通过“Right justified”模式的时序图可以看到接收语音信号时在LRC信号为高电平,且BCLK信号的上升沿时左声道接收数据并完成串行信号转换成并行信号的过程。在LRC信号为低电平,且BCLK 信号的上升沿时右声道接收数据并完成串行信号转换成并行信号的过程。

信号名称 方向 说明
clk in 时钟输入
rst in 异步复位输入,高复位
sck_bclk in 数字音频接口bit时钟
ws_lrc in ADC采样时钟
sdata in 音频数字接口串行数据输入
left_data out 左声道数据
right_data out 右声道数据
data_valid out 音频数据有效

audio_rx音频接收模块端口

audio_tx是音频发送模块,完成左右声道音频数据的串行化。同样通过时序图可以看到,语音信号完成模数,数模转换从SDRAM输出后进入发送模块,在LRC信号上升沿,且即将跳变为高电平时接收左声道数据,BCLK信号下降沿时完成缓存将并行信号转换为串行信号的过程;在LRC信号上升沿且即将跳变为低电平时接收右声道数据,在BCLK信号下降沿时完成缓存将并行信号转换为串行信号的过程。

信号名称 方向 说明
clk in 时钟输入
rst in 异步复位输入,高复位
sck_bclk in 数字音频接口bit时钟
ws_lrc in ADC采样时钟
sdata out 音频数字接口串行数据输入
left_data in 左声道数据
right_data in 右声道数据
read_data_en out 音频数据读取,提前一个采样周期读取

audio_tx音频发送模块端口

在模块‘frame_read_write’中使用到了FIFO 的IP core,通过两个FIFO分别作为DDR3控制器的读写接口,避免复杂的DDR3时序。因为时钟速率的不同,所使用的是异步FIFO。以write_buf写入模块的FIFO为例在vivado中FIFO IP core设置如下:

  1. 打开Tools菜单下的“IP Compiler”, 在弹出的界面下进行如下设置,设置完成后点击”Customize”:

 

开发板

 

  1. 在弹出的界面下进行如下设置,设置完成后点击保存后Generate即可生成IP:

 

开发板

 

 

  1. 接着在模块中直接例化FIFO 的端口名就可以使用FIFO了,在read_buf中也是同样的操作步骤。具体的参数设置和端口例化的信号连接参考例程。

frame_fifo_write模块完成FIFO数据到外部存储器的写入,如果FIFO接口是异步FIFO,可以完成写数据的跨时钟域转换。状态机转换图如下,收到写数据请求后进入应答状态“S_ACK”,如果写请求撤销,则进入检测FIFO空间大小状态“S_CHECK_FIFO”,检查FIFO内数据是否够一次突发写,如果有足够多的数据,进入突发写存储器状态“S_WRITE_BURST”,突发写完成后进入“S_WRITE_BURST_END”状态。

 

开发板frame_fifo_write模块状态机

 

信号名称 方向 说明
mem_clk in 外部存储器用户时钟输入
rst in 异步复位输入,高复位
wr_burst_req out 对接存储器控制器,写请求
wr_burst_len out 对接存储器控制器,写请求长度
wr_burst_addr out 对接存储器控制器,写请求基地址
wr_burst_data_req in 对接存储器控制器,写请求数据索取,提前一个时钟周期发出,用于连接FIFO的读数据
wr_burst_finish in 对接存储器控制器,写请求完整
write_req in 一帧(大量数据)写开始,收到应答后必须撤销请求,新的请求会中断正在进行的请求
write_req_ack out 一帧(大量数据)写应答
write_finish out 一帧(大量数据)完成
write_addr_0 in 一帧(大量数据)写基地址0
write_addr_1 in 一帧(大量数据)写基地址1
write_addr_2 in 一帧(大量数据)写基地址2
write_addr_3 in 一帧(大量数据)写基地址3
write_addr_index in 一帧(大量数据)写基地址选择,0:write_addr_01:write_addr_12:write_addr_23:write_addr_3
write_len in 一帧(大量数据)写长度
fifo_aclr out 在收到写请求后,模块会清空FIFO
rdusedw in FIFO读端的数据使用量

frame_fifo_write模块端口

frame_fifo_read读模块完成从外部存储器读取数据,然后写到FIFO,如果使用异步FIFO可以完成数据从存储器时钟域到其他时钟域的转换。状态机转换图如下图所示,收到读请求以后进入应答状态“S_ACK”,等待读请求撤销后应答,进入FIFO深度检测状态“S_CHECK_FIFO”,如果FIFO空间足够一次突发读,进入突发读状态“S_READ_BURST”,突发读结束后进入“S_READ_BURST_END”。

 

开发板frame_fifo_read模块状态机

 

信号名称 方向 说明
mem_clk in 外部存储器用户时钟输入
rst in 异步复位输入,高复位
rd_burst_req out 对接存储器控制器,读请求
rd_burst_len out 对接存储器控制器,读请求长度
rd_burst_addr out 对接存储器控制器,读请求基地址
rd_burst_data_valid in 对接存储器控制器,读请求数据有效
rd_burst_finish in 对接存储器控制器,读请求完全
read_req in 一帧数据读开始
read_req_ack out 一帧数据读应答
read_finish out 一帧数据读完成
read_addr_0 in 一帧数据读基地址0
read_addr_1 in 一帧数据读基地址1
read_addr_2 in 一帧数据读基地址2
read_addr_3 in 一帧数据读基地址3
read_addr_index in 一帧数据读基地址选择0:read_addr_01:read_addr_12:read_addr_23:read_addr_3
read_len in 帧数据读长度
fifo_aclr out 外部FIFO异步复位
wrusedw in FIFO写端使用空间大小

frame_fifo_read模块端口

audio_key模块主要完成录音播放的按键控制,状态转换如下,当按键按下后进入录音状态,当按键松开时进入播放状态。

 

开发板audio_key模块状态转换图

 

信号名称 方向 说明
clk in 时钟输入
rst in 异步复位输入,高复位
key in 按键输入
record out 录音状态指示
play out 播放状态指示
write_req out 写数据开始
write_req_ack in 写数据应答
read_req out 读数据开始
read_req_ack in 读数据应答

frame_read_write模块完成音频帧数据读写的封装,这里使用了异步FIFO来解决跨时钟问题,例如FIFO 输入宽度和输出宽度的不同来完成数据位宽的转换。

4. 实验现象

开发板首先将音频模块插入扩展口,同时插入麦克风和耳机,然后下载实验程序,按下KEY2不放,进行录音,松开按键后可通过耳机回放录音。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分