Ich versuche, I²C-Slave mit Schreib-und Leseoperationen (8 Bit Daten) zu implementieren, und in meinem Code schreibt Teil funktioniert gut und auf der Leseseite müssen die Daten gelesen werden kommt nicht richtig, ich meine es ist alles "11111111".i2c Slave Schreiben und Lesen von Speicherplätzen in VHDL
Im Lese-Teil wird die Slave-Adresse bekommen und danach, anstatt die Registernummer zu schreiben, von der ich lesen muss, es zeigt alle "11111111" s. Ich brauche Hilfe dabei. Und sowohl das Schreiben als auch das Lesen sollte von 256 Registerstandorten aus geschehen. Wie schreibe und lese ich Daten in den Registern?
Hier in meinem Code versuche ich nur einige Register zu implementieren, anstatt alle 256 zu verwenden. Ich habe nur 10 Register verwendet. Dazu brauche ich einige Vorschläge.
Ich verwende Artix-7 Digilent Basys 3 Board und Vivado 2016.4. Hier sind meine Code- und Simulationsergebnisse.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity I2C is
Port (clk : in std_logic;
rst : in std_logic;
ena : in std_logic;
rw : in std_logic;
state_cnt : out std_logic_vector(3 downto 0);
data_read : out std_logic_vector(7 downto 0);
sda : inout std_logic;
scl : out std_logic);
end I2C;
architecture Behavioral of I2C is
type machine is (ready,start,slave_addr,slv_ack1,reg_num,act_data,read_data,slv_ack2,mas_ack,stop,slv_ack3);
signal pre_state,next_state : machine;
signal data_clk : std_logic;
signal scl_clk : std_logic;
signal scl_ena : std_logic := '0';
signal sda_int : std_logic := '1';
signal sda_ena : std_logic;
signal addr_rw : std_logic_vector(7 downto 0);
signal data_tx : std_logic_vector(7 downto 0);
signal data_rx : std_logic_vector(7 downto 0);
signal bit_count : integer range 0 to 7 := 7;
signal addr : std_logic_vector(6 downto 0) := "1010000";
signal data_wr : std_logic_vector(7 downto 0) := "01010110";--"11110000";
--signal data_rd : std_logic_vector(7 downto 0) := "01010110";
signal wr_addr : std_logic_vector(7 downto 0) := "00000001";
signal count : integer range 0 to 250;
type slv_array is array (0 to 9) of std_logic_vector (7 downto 0);
signal reg_array : slv_array;
begin
reg_array(0) <= "00000000";
reg_array(1) <= "00000001";
reg_array(2) <= "00000010";
reg_array(3) <= "00000011";
reg_array(4) <= "00000100";
reg_array(5) <= "00000101";
reg_array(6) <= "00000110";
reg_array(7) <= "00000111";
reg_array(8) <= "00001000";
reg_array(9) <= "00001001";
process (clk, rst)
begin
if (rst = '1') then
count <= 0;
elsif (rising_edge(clk))then
if (count = 249) then
-- temp <= not temp;
count <= 0;
else
count <= count + 1;
end if;
end if;
end process;
--scl_clk <= temp;
process (clk,rst,count)
begin
if (rst = '1') then
scl_clk <= '0';
data_clk <= '0';
elsif (rising_edge(clk)) then
case count is
when 0 to 62 =>
scl_clk <= '0';
data_clk <= '0';
when 63 to 124 =>
scl_clk <= '0';
data_clk <= '1';
when 125 to 187 =>
scl_clk <= '1';
data_clk <= '1';
when 188 to 249 =>
scl_clk <= '1';
data_clk <= '0';
when others => null;
end case;
end if;
end process;
process (clk,rst)
begin
if (rst = '1') then
pre_state <= ready;
elsif (rising_edge(clk))then
pre_state <= next_state;
end if;
end process;
process(data_clk,rst)
begin
if (rst = '1') then
next_state <= ready;
scl_ena <= '0';
sda_int <= '1';
bit_count <= 7;
data_read <= "00000000";
state_cnt <= "1111";
elsif (rising_edge(data_clk)) then
case pre_state is
when ready =>
state_cnt <= "0001";
if (ena ='1') then
addr_rw <= addr & rw;
data_tx <= wr_addr;
next_state <= start;
else
next_state <= ready;
end if;
when start =>
state_cnt <= "0010";
scl_ena <= '1';
sda_int <= addr_rw(bit_count);
next_state <= slave_addr;
when slave_addr =>
state_cnt <= "0011";
if (bit_count = 0) then
sda_int <= '1';
bit_count <= 7;
next_state <= slv_ack1;
else
bit_count <= bit_count - 1;
sda_int <= addr_rw(bit_count -1);
next_state <= slave_addr;
end if;
when slv_ack1 =>
state_cnt <= "0100";
if (addr_rw(0) = '0') then
sda_int <= data_tx(bit_count);
next_state <= reg_num;
else
sda_int <= '1';
next_state <= read_data;
end if;
when reg_num =>
state_cnt <= "0101";
if (bit_count = 0) then
sda_int <= '1';
bit_count <= 7;
next_state <= slv_ack2;
else
bit_count <= bit_count - 1;
sda_int <= data_tx(bit_count -1);
next_state <= reg_num;
end if;
when slv_ack2 =>
state_cnt <= "0110";
if (ena ='1') then
data_tx <= data_wr;
sda_int <= data_wr(bit_count);
next_state <= act_data;
else
scl_ena <= '0';
next_state <= stop;
end if;
when act_data =>
state_cnt <= "0111";
if (bit_count =0) then
sda_int <= '1';
bit_count <= 7;
next_state <= slv_ack3;
else
bit_count <= bit_count - 1;
sda_int <= data_tx(bit_count-1);
next_state <= act_data;
end if;
when slv_ack3 =>
state_cnt <= "1000";
scl_ena <= '0';
next_state <= stop;
when stop =>
state_cnt <= "1001";
if (rw = '1') then
next_state <= ready;
else
next_state <= stop;
end if;
when read_data =>
state_cnt <= "1010";
if (bit_count = 0) then
if (ena ='1' and rw ='1') then
sda_int <= '0';
else
sda_int <= '1';
end if;
data_read(0) <= sda;
data_read(7 downto 1) <= data_rx(7 downto 1);
bit_count <= 7;
next_state <= stop;
else
data_rx(bit_count) <= sda;
bit_count <= bit_count - 1;
next_state <= read_data;
end if;
when mas_ack =>
state_cnt <= "1011";
if (ena = '1') then
addr_rw <= addr & rw;
data_tx <= data_wr;
if (rw = '0') then
next_state <= start;
else
sda_int <= '1';
next_state <= read_data;
end if;
else
scl_ena <='0';
next_state <= stop;
end if;
when others => null;
end case;
end if;
end process;
WITH pre_state select
sda_ena <= data_clk when start,
not data_clk when stop,
sda_int when others;
scl <= scl_clk;
sda <= '0' when sda_ena = '0' else sda_ena;
end Behavioral;
I²C schreiben:
(zum Vergrößern klicken)
I²C zu lesen:
(zum Vergrößern klicken)