我正在開發一個項目,我需要在Altera DE1開發板上編碼WM8731音頻編解碼器芯片。該項目非常基礎。它不需要處理輸入音頻信號。來自輸入端的信號應該直接傳送到輸出端。時鐘配置 - VHDL編碼Altera DE1音頻編解碼器芯片
主要任務是通過I2C協議設置編解碼芯片。我是VHDL的新手,我有一些理解這個概念的問題。
在使用之前,編解碼芯片需要被初始化。這包括通過I2C傳遞數據組。下面給出了要傳遞的數據和說明。
constant sdin_load : std_logic_vector (11*24-1 downto 0)
--this contains codec configuration data
問題 -主時鐘頻率爲50MHz,且I2C總線頻率爲100KHz。所以項目要求:
1)聲明位計數器; - 位計數器,在100kHz下運行,
2)聲明字計數器; - 字計數器,運行在5kHz左右
3)聲明位長的計數器; - 運行在50MHz的分頻計數器
我的理解是,由於主時鐘和I2C時鐘的頻率不同,我們需要有一個計數器來跟蹤事件。我的理解:
1)位計數器可以計數從1到500,這是50MHz/100KHz。所以每當計數器進入500時,下一個信息位就被傳送。
2)這是我不明白的部分。如果字計數器運行在5KHz,那麼它將只計數I2C脈衝的20個脈衝(100KHz/5KHz),而不是它發送的29位信息。
3)最後,爲什麼我們需要聲明一個以50MHz運行的位長計數器?我們已經有了這個頻率的時鐘。
我們已經給出了一個示例代碼。爲櫃檯的執行。我附上完整的體系結構以供參考。
library ieee;
use ieee.std_logic_1164.all;
entity codec_init is
port
(
CLOCK_50 : in std_logic; -- master clock
RES_N : in std_logic; -- reset, active 0
SCLK : out std_logic; -- serial clock
SDIN : out std_logic -- serial data
);
end entity;
architecture rtl of codec_init is
constant sdin_load : std_logic_vector (11*24-1 downto 0)
--this contains codec configuration data
begin
process (CLOCK_50)
begin
if (rising_edge(CLOCK_50)) then
-- reset actions
if (RES_N = '0') then
-- reset the counters to an appropriate state
...; -- load the frequency divider,
-- 50MHz/500=100kHz bus speed
...; -- load the shift register
...; -- load the bit counter,
-- 29 bits in the word protocol
...; -- load the word counter, 11 words
-- reset the outputs to an appropriate state
...;
...;
elsif (...) then -- deadlock in the end
-- do nothing, wait for the next reset
-- modify reference counters
-- for frequency divider, bits and words
elsif (...) then -- at the end of each bit
...; -- reload the frequency divider counter
if (bcnt = 0) then -- at the end of each word
...; -- reset the bit counter
...; --modify the word counter
else -- the bit is not the end of a word
...; --modify the bit counter
end if;
else -- if not the end of the bit
...; -- modify the frequency divider
end if;
-- generating SCLK, it is going up and then down inside each bit
if (...) then -- condition when SCLK goes up
...;
elsif (...) then -- condition when SCLK goes down
...;
end if;
-- generating serial data output
if (...) then -- start transition condition
...;
elsif (...) then -- ack bit condition
...;
elsif (...) then -- stop transition condition
...;
elsif(...) then -- condition for the non-special bits
...; -- shifting
...;
end if;
-----------------------------
end if;
end process;
-- forming the output with high impedance states for ack-s
SDIN <= 'Z' when (...condition for ack bits...)
else (sdout);
end rtl;
謝謝。
請參閱[I2C時鐘速度](https://www.i2c-bus.org/speed/),它似乎是一個全速I2C(最大400 kbits/sec)將適合您的目的。什麼阻止你使用更快的I2C? – user1155120
我曾經與賽靈思的Ken Chapman就此主題進行了討論(FPGA邏輯上的I2C和RS232)。他曾嘗試過使用PicoBlaze,並發現需要較少的硬件來在一個(非常小的)軟核CPU中實現這些協議,然後在FPGA架構上實現這些協議。你可以考慮這一點。 – JHBonarius
請不要通過刪除代碼破壞帖子。 –