chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

使用FPGA播放音頻文件

OpenFPGA ? 來源:OpenFPGA ? 2024-01-17 09:26 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

9b3d3e8c-b4d0-11ee-8b88-92fbcf53809c.png

讓我們看一下I2S規(guī)范,并嘗試用FPGA播放音頻文件。

開篇第一步

Inter-IC Sound Interface(簡稱I2S)是由飛利浦公司開發(fā),用于通過不同IC之間的串行接口(例如從處理器DAC)傳輸數(shù)字音頻數(shù)據(jù)。該接口使用以下信號進行數(shù)據(jù)傳輸:

SCK (串行時鐘)——用于數(shù)據(jù)傳輸?shù)臅r鐘。

SD (串行數(shù)據(jù))- 每個數(shù)據(jù)字的各個位通過該線傳輸。

WS (字選擇)- 定義傳輸數(shù)據(jù)字的長度。它用于標記右或左音頻通道。

僅音頻數(shù)據(jù)通過 I2S 傳輸。附加數(shù)據(jù)(例如各個總線用戶的配置)通過其他接口傳輸。數(shù)據(jù)傳輸總是在兩個總線之間沿一個方向進行,其中一路總線必須充當主機并負責生成時鐘信號。在由多個發(fā)送器和接收器組成的復雜系統(tǒng)中,時鐘信號由外部總線主控器生成,并且相應的發(fā)送器生成數(shù)據(jù)。

9b4c1128-b4d0-11ee-8b88-92fbcf53809c.png

所有數(shù)據(jù)均以二進制補碼和 MSB 優(yōu)先的方式傳輸。如果接收方和發(fā)送方的字寬存在正差(即一方的字寬小于另一方的字寬),則剩余位填充0。根據(jù)規(guī)范,數(shù)據(jù)可以同步于正時鐘沿或負時鐘沿,從而數(shù)據(jù)總是在負時鐘沿讀入。

WS信號選擇活動通道,并將低或高相位內(nèi)的所有數(shù)據(jù)分配給相應的通道:

WS = 0 – 通道 1(左)

WS = 1 – 通道 2(右)

?WS信號必須在下一個數(shù)據(jù)字的 MSB 之前的一個時鐘周期發(fā)生變化,以便接收器可以將數(shù)據(jù)讀入正確的通道。WS信號的時鐘頻率通常對應于音頻信號的采樣頻率。

9b593894-b4d0-11ee-8b88-92fbcf53809c.png

在這篇文章中,展示如何設計一個簡單的 I2S 發(fā)射器,并使用 CS4344 立體聲 D/A 轉換器通過揚聲器輸出恒定的聲音。

要輸出的聲音將存儲在 FPGA 的block memory中,并由發(fā)送器讀出,并將數(shù)據(jù)發(fā)送到 D/A 轉換器。整個項目分為三個部分,將逐步討論:

集成系統(tǒng)時鐘和I2S模塊的Top設計

集成ROM和I2S發(fā)送器的I2S模塊

I2S發(fā)送器

I2S發(fā)送器

設計的最底層應該是 I2S 發(fā)送器,其任務是通過 I2S 接口發(fā)送各個數(shù)據(jù)字。

9b739d56-b4d0-11ee-8b88-92fbcf53809c.png

該框圖產(chǎn)生了以下發(fā)送器:

entityI2S_Transmitteris
Generic(WIDTH:INTEGER:=16
);
Port(Clock:inSTD_LOGIC;
nReset:inSTD_LOGIC;
Ready:outSTD_LOGIC;
Tx:inSTD_LOGIC_VECTOR(((2*WIDTH)-1)downto0);
LRCLK:outSTD_LOGIC;
SCLK:outSTD_LOGIC;
SD:outSTD_LOGIC
);
endI2S_Transmitter;

數(shù)據(jù)字的大小通過WIDTH參數(shù)定義。

三級狀態(tài)機控制發(fā)送器,描述如下:

architectureI2S_Transmitter_ArchofI2S_Transmitteris

typeState_tis(State_Reset,State_LoadWord,State_TransmitWord);

signalCurrentState:State_t:=State_Reset;

signalTx_Int:STD_LOGIC_VECTOR(((2*WIDTH)-1)downto0):=(others=>'0');
signalReady_Int:STD_LOGIC:='0';
signalLRCLK_Int:STD_LOGIC:='1';
signalSD_Int:STD_LOGIC:='0';
signalEnable:STD_LOGIC:='0';

begin

process
variableBitCounter:INTEGER:=0;
begin
waituntilfalling_edge(Clock);

caseCurrentStateis
whenState_Reset=>
Ready_Int<=?'0';
????????????????LRCLK_Int?<=?'1';
????????????????Enable?<=?'1';
????????????????SD_Int?<=?'0';
????????????????Tx_Int?<=?(others?=>'0');
CurrentState<=?State_LoadWord;
????????????when?State_LoadWord?=>
BitCounter:=0;
Tx_Int<=?Tx;
????????????????LRCLK_Int?<=?'0';
????????????????CurrentState?<=?State_TransmitWord;
????????????when?State_TransmitWord?=>
BitCounter:=BitCounter+1;
if(BitCounter>(WIDTH-1))then
LRCLK_Int<=?'1';
????????????????end?if;
????????????????if(BitCounter?

復位期間,輸出信號被置位,SCLK時鐘被停用。復位后,機器從State_Reset狀態(tài)變?yōu)镾tate_TransmitWord狀態(tài)。在此狀態(tài)下,機器Tx_Int通過 I2S 接口傳輸緩沖區(qū)的內(nèi)容。

一旦開始傳輸最后一個數(shù)據(jù)位,Ready就設置為表示傳輸結束并準備好接受新數(shù)據(jù)。然后機器更改為 stateState_LoadWord狀態(tài),其中發(fā)送緩沖區(qū)填充有新的數(shù)據(jù)字并開始新的傳輸。

I2S模塊

I2S 模塊使用 I2S 發(fā)送器將數(shù)據(jù)從 ROM 傳輸?shù)?D/A 轉換器。

9b7cc9c6-b4d0-11ee-8b88-92fbcf53809c.png

具有以下代碼:

entityI2Sis
Generic(RATIO:INTEGER:=8;
WIDTH:INTEGER:=16
);
Port(MCLK:inSTD_LOGIC;
nReset:inSTD_LOGIC;
LRCLK:outSTD_LOGIC;
SCLK:outSTD_LOGIC;
SD:outSTD_LOGIC
);
endI2S;

參數(shù)RATIO 定義了SCLK與MCLK WIDTH的比率以及每個通道的數(shù)據(jù)字的寬度。

除了 I2S 發(fā)送器之外,該模塊還使用 ROM,該 ROM 可以通過block memory生成器創(chuàng)建并填充數(shù)據(jù)。兩者都可以使用 Vivado 的 IP 來完成。

9b875b48-b4d0-11ee-8b88-92fbcf53809c.png

最后,通過其他選項使用正弦信號 coe 文件(參見附件)對 ROM 進行初始化。

I2S 模塊使用狀態(tài)機從 ROM 讀取數(shù)據(jù)并將其傳輸?shù)?I2S 發(fā)送器。

architectureI2S_ArchofI2Sis

typeState_tis(State_Reset,State_WaitForReady,State_IncreaseAddress,State_WaitForStart);

signalCurrentState:State_t:=State_Reset;

signalTx:STD_LOGIC_VECTOR(((2*WIDTH)-1)downto0):=(others=>'0');
signalROM_Data:STD_LOGIC_VECTOR((WIDTH-1)downto0):=(others=>'0');
signalROM_Address:STD_LOGIC_VECTOR(6downto0):=(others=>'0');

signalReady:STD_LOGIC;
signalSCLK_Int:STD_LOGIC:='0';

componentI2S_Transmitteris
Generic(WIDTH:INTEGER:=16
);
Port(Clock:inSTD_LOGIC;
nReset:inSTD_LOGIC;
Ready:outSTD_LOGIC;
Tx:inSTD_LOGIC_VECTOR(((2*WIDTH)-1)downto0);
LRCLK:outSTD_LOGIC;
SCLK:outSTD_LOGIC;
SD:outSTD_LOGIC
);
endcomponent;

componentSineROMis
Port(Address:inSTD_LOGIC_VECTOR(6downto0);
Clock:inSTD_LOGIC;
DataOut:outSTD_LOGIC_VECTOR(15downto0)
);
endcomponentSineROM;

begin

Transmitter:I2S_Transmittergenericmap(WIDTH=>WIDTH
)
portmap(Clock=>SCLK_Int,
nReset=>nReset,
Ready=>Ready,
Tx=>Tx,
LRCLK=>LRCLK,
SCLK=>SCLK,
SD=>SD
);

ROM:SineROMportmap(Clock=>MCLK,
Address=>ROM_Address,
DataOut=>ROM_Data
);

process
variableCounter:INTEGER:=0;
begin
waituntilrising_edge(MCLK);
if(Counter
WordCounter:=0;
CurrentState<=?State_WaitForReady;
????????????when?State_WaitForReady?=>
if(Ready='1')then
CurrentState<=?State_WaitForStart;
????????????????else
????????????????????CurrentState?<=?State_WaitForReady;
????????????????end?if;
????????????when?State_WaitForStart?=>
ROM_Address<=?STD_LOGIC_VECTOR(to_unsigned(WordCounter,?ROM_Address'length));
????????????????Tx?<=?x"0000"?&?ROM_Data;
????????????????if(Ready?=?'0')?then
????????????????????CurrentState?<=?State_IncreaseAddress;
????????????????else
????????????????????CurrentState?<=?State_WaitForStart;
????????????????end?if;
????????????when?State_IncreaseAddress?=>
if(WordCounter

第一個過程用于從MCLK生成發(fā)送器所需的時鐘信號SCLK 。

process
variableCounter:INTEGER:=0;
begin
waituntilrising_edge(MCLK);
if(Counter

第二個進程負責狀態(tài)機的處理。離開State_Reset狀態(tài)后,機器在該State_WaitForReady狀態(tài)下等待,直到發(fā)送器發(fā)出就緒信號Ready 。??

一旦發(fā)送器準備就緒,機器就會更改State_WaitForStart狀態(tài)。在此狀態(tài)下,從 ROM 讀取當前數(shù)據(jù)字并將其傳輸?shù)桨l(fā)送器。

PS:此處顯示的 ROM 僅包含一個通道的信息。第二個通道的數(shù)據(jù)需進行擴展。

一旦發(fā)送器清除就緒信號并開始發(fā)送數(shù)據(jù),狀態(tài)機就會更改為State_IncreaseAddress狀態(tài)。該狀態(tài)下ROM地址加1,然后切換回State_WaitForReady狀態(tài)

top模塊

最后一個組件是頂層設計,包括 I2S 模塊和時鐘PLL。

本示例使用以下參數(shù)來控制 CS4344:

MCLK:12.288MHz

SCLK:1.536 MHz

LRCLK:48kHz

比率:8

寬度:16

時鐘PLL生成 12.288 MHz 時鐘,并與之前代碼中完成的 I2S 模塊一起實例化。

9b96a652-b4d0-11ee-8b88-92fbcf53809c.png

entityTopis
Generic(RATIO:INTEGER:=8;
WIDTH:INTEGER:=16
);
Port(Clock:inSTD_LOGIC;
nReset:inSTD_LOGIC;
MCLK:outSTD_LOGIC;
LRCLK:outSTD_LOGIC;
SCLK:outSTD_LOGIC;
SD:outSTD_LOGIC;
LED:outSTD_LOGIC_VECTOR(3downto0)
);
endTop;

architectureTop_ArchofTopis

signalnSystemReset:STD_LOGIC:='0';
signalMCLK_DCM:STD_LOGIC:='0';
signalLocked:STD_LOGIC:='0';

componentI2Sis
Generic(RATIO:INTEGER:=8;
WIDTH:INTEGER:=16
);
Port(MCLK:inSTD_LOGIC;
nReset:inSTD_LOGIC;
LRCLK:outSTD_LOGIC;
SCLK:outSTD_LOGIC;
SD:outSTD_LOGIC
);
endcomponent;

componentAudioClockis
Port(ClockIn:inSTD_LOGIC;
Locked:outSTD_LOGIC;
MCLK:outSTD_LOGIC;
nReset:inSTD_LOGIC
);
endcomponent;

begin

InputClock:AudioClockportmap(ClockIn=>Clock,
nReset=>nReset,
MCLK=>MCLK_DCM,
Locked=>Locked
);

I2S_Module:I2Sgenericmap(RATIO=>RATIO,
WIDTH=>WIDTH
)
portmap(MCLK=>MCLK_DCM,
nReset=>nSystemReset,
LRCLK=>LRCLK,
SCLK=>SCLK,
SD=>SD
);

nSystemReset<=?nReset?and?Locked;
????LED(0)?<=?nReset;
????LED(1)?<=?Locked;
????LED(2)?<=?nSystemReset;
????MCLK?<=?MCLK_DCM;

end?Top_Arch;

最后就可以進行測試。理想情況下,D/A 轉換器輸出 480 Hz 正弦信號。因為來自 ROM 的信號模式的長度為 100 個樣本,采樣頻率為 48 kHz。可以用示波器檢查總線和信號:

9ba75fd8-b4d0-11ee-8b88-92fbcf53809c.png

此外,還可以檢查音頻信號(示波器的 FFT 功能是實現(xiàn)此目的的最佳工具)。

9bb38236-b4d0-11ee-8b88-92fbcf53809c.png

附件-Coe

memory_initialization_radix=16;
memory_initialization_vector=
0000,
0809,
100A,
17FB,
1FD4,
278D,
2F1E,
367F,
3DA9,
4495,
4B3B,
5196,
579E,
5D4E,
629F,
678D,
6C12,
7029,
73D0,
7701,
79BB,
7BF9,
7DBA,
7EFC,
7FBE,
7FFF,
7FBE,
7EFC,
7DBA,
7BF9,
79BB,
7701,
73D0,
7029,
6C12,
678D,
629F,
5D4E,
579E,
5196,
4B3B,
4495,
3DA9,
367F,
2F1E,
278D,
1FD4,
17FB,
100A,
0809,
0000,
F7F7,
EFF6,
E805,
E02C,
D873,
D0E2,
C981,
C257,
BB6B,
B4C5,
AE6A,
A862,
A2B2,
9D61,
9873,
93EE,
8FD7,
8C30,
88FF,
8645,
8407,
8246,
8104,
8042,
8001,
8042,
8104,
8246,
8407,
8645,
88FF,
8C30,
8FD7,
93EE,
9873,
9D61,
A2B2,
A862,
AE6A,
B4C5,
BB6B,
C257,
C981,
D0E2,
D873,
E02C,
E805,
EFF6,
F7F7,

下一篇文章,將向 I2S 發(fā)送器添加 AXI-Stream 接口,并將其與 ZYNQ 的處理系統(tǒng)連接,播放 SD 卡中的音頻文件。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 處理器
    +關注

    關注

    68

    文章

    20069

    瀏覽量

    242791
  • FPGA
    +關注

    關注

    1650

    文章

    22207

    瀏覽量

    626869
  • 接口
    +關注

    關注

    33

    文章

    9269

    瀏覽量

    155451
  • 音頻
    +關注

    關注

    31

    文章

    3098

    瀏覽量

    84513

原文標題:使用 FPGA 播放音頻(一)

文章出處:【微信號:Open_FPGA,微信公眾號:OpenFPGA】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    請問如何使用PSoC4播放音頻文件?

    如何使用 PSoC4 播放音頻文件
    發(fā)表于 07-02 07:19

    音頻文件(WAV)特技播放的原理及實現(xiàn)

    本帖最后由 eehome 于 2013-1-5 10:08 編輯 音頻文件播放是開發(fā)多媒體軟件中的一個重要內(nèi)容,但有時需要對它進行特技播放,如快速播放,慢速
    發(fā)表于 03-12 00:42

    LabVIEW 播放音頻文件-

    LabVIEW 播放音頻文件-
    發(fā)表于 01-20 17:30

    labview 數(shù)組轉換成數(shù)組波形并寫入音頻文件重新播放

    我先對一個音頻文件進行處理 將左右聲道的波形分別進行量化編碼調制解調解碼了 請問 各位大神解碼后 如果我想把一個數(shù)組轉換回數(shù)組波形 并寫入一個音頻文件 重新播放 怎么實現(xiàn)?
    發(fā)表于 05-12 20:30

    FPGA+VS1003+flash方案,播放音頻文件耳機沒有任何聲音

    大家好,公司項目采用的是FPGA+VS1003+flash方案,flash用于保存音頻文件。目前播放遇到問題了,描述如下:首先我確認了以下幾點:1.首先是硬件方面,目前已經(jīng)完成了寄存器配置的測試
    發(fā)表于 01-16 23:10

    5509A播放音頻文件感覺全是雜音

    我將音頻文件放到SD卡中,用DSP5509A將其讀取出來,并發(fā)送給AIC23,但是播放出來的音樂感覺全是雜音,請問是對AIC23的配置不對嗎?我放在SD卡中的文件是MP3文件,比特率是
    發(fā)表于 02-12 11:41

    Matlab處理音頻文件

    文章目錄Matlab處理音頻文件DAC播放DAC配置Tim配置開始應用層數(shù)據(jù)流向Matlab處理音頻文件Audio_filename = 'Audio.wav';% 獲取原音頻數(shù)據(jù)[A
    發(fā)表于 08-17 06:36

    如何用STM32F103xx單片機通過外部I2S音頻編解碼器來播放音頻文件

    如何用高密度STM32F103xx單片機通過外部 I2S音頻編解碼器來播放音頻文件,本手冊僅適用于STM32F103系列,可以實現(xiàn)音頻播放功能
    發(fā)表于 12-01 07:42

    103xx通過外部I2S音頻解碼器播放音頻文件

    103xx通過外部I2S音頻解碼器播放音頻文件。
    發(fā)表于 01-12 18:26 ?56次下載

    基于ESP32構建的音頻播放

    在這里,我們將使用LM386 和一個帶有 ESP32 的揚聲器來播放音樂文件。音頻輸出可能不大,但此應用程序顯示了 ESP32 板播放音頻文件的能力。
    發(fā)表于 08-08 15:37 ?2.6w次閱讀
    基于ESP32構建的<b class='flag-5'>音頻</b><b class='flag-5'>播放</b>器

    AN4309_將STM32L1xx微控制器與外部I2S音頻編解碼器連接起來播放音頻文件

    AN4309_將STM32L1xx微控制器與外部I2S音頻編解碼器連接起來播放音頻文件
    發(fā)表于 11-21 08:11 ?0次下載
    AN4309_將STM32L1xx微控制器與外部I2S<b class='flag-5'>音頻</b>編解碼器連接起來<b class='flag-5'>播放音頻文件</b>

    AN2739 如何用高密度STM32F103xx單片機來播放音頻文件

    AN2739 如何用高密度STM32F103xx單片機來播放音頻文件
    發(fā)表于 11-24 08:30 ?4次下載
    AN2739 如何用高密度STM32F103xx單片機來<b class='flag-5'>播放音頻文件</b>

    在Arduino中播放音頻

    電子發(fā)燒友網(wǎng)站提供《在Arduino中播放音頻.zip》資料免費下載
    發(fā)表于 06-25 15:16 ?0次下載
    在Arduino中<b class='flag-5'>播放音頻</b>

    使用STM32L1xx微控制器與外部I2S音頻編解碼器播放音頻文件

    電子發(fā)燒友網(wǎng)站提供《使用STM32L1xx微控制器與外部I2S音頻編解碼器播放音頻文件.pdf》資料免費下載
    發(fā)表于 09-21 11:30 ?3次下載
    使用STM32L1xx微控制器與外部I2S<b class='flag-5'>音頻</b>編解碼器<b class='flag-5'>播放音頻文件</b>

    如何使用音頻接口播放音頻文件

    ZDP1440是一款基于開源GUI引擎的圖像顯示專用驅動芯片,內(nèi)部集成16MB顯示內(nèi)存、2D圖形加速器、音頻解碼器等豐富多媒體功能,本文將介紹如何使用音頻接口播放音頻文件。
    的頭像 發(fā)表于 08-06 16:12 ?1352次閱讀
    如何使用<b class='flag-5'>音頻</b>接口<b class='flag-5'>播放音頻文件</b>