spi--master

来源:互联网 发布:驻韩大使 间谍 知乎 编辑:程序博客网 时间:2024/05/29 14:32
------------------------------------------------------------------------------------ Company: -- Engineer: -- -- Create Date:    14:08:05 04/09/2015 -- Design Name: -- Module Name:    spi_master - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: ---- Dependencies: ---- Revision: -- Revision 0.01 - File Created-- Additional Comments: ------------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;---- Uncomment the following library declaration if instantiating---- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity spi_master is    generic (   CLK_DIV : std_logic_vector(7 downto 0) := x"05");    Port ( rst :in  STD_LOGIC;  -- reset signal, active '1'           clk : in  STD_LOGIC;  -- 40MHz  cs_ctrl:inSTD_LOGIC;-- CS control           data_in : in  STD_LOGIC_VECTOR (7 downto 0);           data_out : out STD_LOGIC_VECTOR (7 downto 0);  data_valid:outSTD_LOGIC;           spi_send : in  STD_LOGIC;  spi_busy:outSTD_LOGIC;           cs : out  STD_LOGIC;-- same as CS_CTRL           sclk : out  STD_LOGIC;           mosi : out  STD_LOGIC;           miso: in  STD_LOGIC);end spi_master;architecture Behavioral of spi_master is    constant RESET_ACTIVE : std_logic := '1';--    constant CLK_DIV : std_logic_vector(7 downto 0) := x"01";    signal reg_tx : std_logic_vector(7 downto 0);    signal reg_rx : std_logic_vector(7 downto 0);    signal send : std_logic_vector(1 downto 0);    signal sck : std_logic;    signal clk_en :  std_logic;    signal t_clk : std_logic_vector(7 downto 0); --1/2CLK counter    signal ct_bit : std_logic_vector(7 downto 0);--send bits counter    type state_type is (idle,tx_prep,tx_state,tx_end);     signal currt_state, next_state : state_type;begin    process(clk,rst) -- SPI send active    begin        if rst = RESET_ACTIVE then            send <= "00";        elsif rising_edge(clk) then            send(0) <= spi_send;            send(1) <= send(0);        end if;    end process;    process(rst,clk) --generate SPI SCLK    begin        if rst = RESET_ACTIVE then            t_clk <= x"00";            ct_bit <= x"00";            sck <= '0';        elsif rising_edge(clk) then            if clk_en = '1' then                if t_clk = CLK_DIV then                    t_clk <= x"00";                    ct_bit <= ct_bit + '1';                    sck <= not(sck);                else                    t_clk <= t_clk + '1';                end if;            else                t_clk <= x"00";                ct_bit <= x"00";                sck <= '0';            end if;                    end if;    end process;    sclk <= sck;            --64 divider        process(next_state,rst) --SPI state meachine    begin        if rst = RESET_ACTIVE then            currt_state <= idle;        else            currt_state <= next_state;        end if;    end process;  cs <= cs_ctrl;        process(clk,rst)    begin        if rst = RESET_ACTIVE then--            cs <= '1';            mosi <= '0';            clk_en <= '0';            reg_tx <= (others => '0');            reg_rx <= (others => '0');            data_out <= (others => '0');            next_state <= idle;data_valid <= '0';spi_busy <= '0';        elsif rising_edge(clk) then            case currt_state is                when idle =>--                    cs <= '1';                    mosi <= '0';                    clk_en <= '0';                    reg_tx <= (others => '0');                    next_state <= idle;                                        if send = "01" then --posedge send                                           reg_tx <= data_in;                        clk_en <= '0';                        next_state <= tx_prep;                    end if;  spi_busy <= '0';                when tx_prep =>--                    cs <= '0';                    mosi <= reg_tx(7);                    clk_en <= '1';                    next_state <= tx_state;  spi_busy <= '1';                when tx_state =>                    if ct_bit(0) = '0' and t_clk = CLK_DIV then --SCLK posedge                        reg_rx <= reg_rx(6 downto 0) & miso;                        next_state <= tx_state;                        clk_en <= '1';                        reg_tx <= reg_tx(6 downto 0) & '0';                    elsif ct_bit(0) = '1' and t_clk = CLK_DIV then --SCLK negedge                                               mosi <= reg_tx(7);                        next_state <= tx_state;                        clk_en <= '1';                    elsif ct_bit = x"10" and t_clk = (CLK_DIV-'1') then --the last data--                        cs <= '0';                        clk_en <= '0';                                            --mosi <= '0';                                                next_state <= tx_end;--                        if CLK_DIV = x"01" then--                            data_out <= reg_rx;--                        end if;                    elsif ct_bit = x"10" thendata_valid <= '1';                        data_out <= reg_rx;                    else--                        cs <= '0';                        clk_en <= '1';                        next_state <= tx_state;                    end if;                when tx_end => --                    cs <= '1';                    clk_en <= '0';                                        mosi <= '0';                      next_state <= idle;  spi_busy <= '0';  data_valid <= '0';            end case;        end if;    end process;end Behavioral;

0 0
原创粉丝点击