美文网首页菜鸟工程师成长之路
基于VHDL的输出长度可变的SPI通信模块

基于VHDL的输出长度可变的SPI通信模块

作者: 言丶武 | 来源:发表于2017-04-25 21:14 被阅读209次

    在电子设计中,通常我们会遇到FPGA和MCU联合开发的问题,而SPI是一种用于二者通信的好方式。在本代码中,并行输入可变长度的数据,串行输出,实用性非常好,可作为模块进行移植。(以128位为例)

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_arith.all;
    use ieee.std_logic_unsigned.all;
    
    entity SPI is
    port(
    Data_Bus: in std_logic_vector(127 downto 0);   --数据输入
    Data_Valid: in std_logic;                     --数据发送有效,检测到下降沿开始发送
    Sys_Rst,Sys_Clk: in std_logic;                --复位端,高电平复位;时钟信号
    SPI_CE,SPI_Clk,SPI_Data: out std_logic);      --SPI的三条线
    end entity;
    
    architecture Behavior_SPI_Port of SPI is
    signal  Data_Int,Data_Res: std_logic;            --
    signal  SPI_Reg: std_logic_vector(127 downto 0);   --发送数据缓存
    signal  Bit_Cnt: integer range 0 to 128;         --发送数据位
    signal  Step_cnt: integer range 0 to 5;     --状态机
    signal   start,spi_clk_temp,spi_ce_temp,spi_data_temp: std_logic:='0';
    begin
               SPI_CE<=spi_ce_temp;
                  SPI_Clk<=SPI_clk_temp;
                  spi_Data<=spi_data_temp;
    
    process(Data_Valid,Sys_Clk)
    begin
       if(Sys_Clk'event and Sys_Clk='0') then
           start<=Data_Valid;
            end if;
            end process;
      
    
    process(start,Data_Res)
    begin
    if(Data_Res='1' or Sys_Rst='1')then
        Data_Int<='0';
    elsif(start'event and start='0')then
        SPI_Reg<=Data_Bus;
        Data_Int<='1';
    end if;
    end process;
    
    process(Sys_Rst,Sys_Clk,Data_Int)
    begin
    if(Sys_Rst='1')then
        Step_Cnt<=0;
        spi_ce_temp<='0';
        spi_clk_temp<='0';
        Bit_Cnt<=0;
    elsif(Sys_Clk'event and Sys_Clk='1')then
        case Step_Cnt is
            when    0=> if(Data_Int='1')then
                            Step_Cnt<=Step_Cnt+1;
                            Data_Res<='1';  
                            Bit_Cnt<=0;
                        end if;     
            when    1=> spi_ce_temp<='1';
                        Step_Cnt<=Step_Cnt+1;
            when    2=> spi_data_temp<=SPI_Reg(Bit_Cnt);
                        Step_Cnt<=Step_Cnt+1;
            when    3=> spi_clk_temp<='1';
                        Step_Cnt<=Step_Cnt+1;               
            when    4=> spi_clk_temp<='0';
                        if(Bit_Cnt=127)then
                            Step_Cnt<=Step_Cnt+1;
                        else
                            Bit_Cnt<=Bit_Cnt+1;
                            Step_Cnt<=2;
                        end if;
            when    5=> Data_Res<='0';
                        Step_Cnt<=0;
            when    others=>Step_Cnt<=0;
        end case;
    end if;
    end process;
    
    end Behavior_SPI_Port;
    

    相关文章

      网友评论

        本文标题:基于VHDL的输出长度可变的SPI通信模块

        本文链接:https://www.haomeiwen.com/subject/oilbzttx.html