⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cus_spi.vhd

📁 此为VHDL的SPI通信代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-- File Name   :  CUS_SPI.Vhd
-- Autor       :  lin
-- CopyRight   :  2411 Communication Engineering of CQ University
-- Date        :  2006-3-9
-- Description :  Hardware description of SPI interface module in language of VHDL. 
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CUS_SPI IS
GENERIC(S_NUM:INTEGER:=1);--指定从选线数
PORT(  
--INPUT
       SYS_CLK  :IN  STD_LOGIC;--模块时钟
       WR_N     :IN  STD_LOGIC;--写信号
       RD_N     :IN  STD_LOGIC;--读信号
       CS       :IN  STD_LOGIC;--片选
       ADDR     :IN  STD_LOGIC_VECTOR(2 DOWNTO 0);
       DATAIN   :IN  STD_LOGIC_VECTOR(7 DOWNTO 0);
--OUTPUT
       INT_SPIF :OUT STD_LOGIC;--传输结束中断
       DATAOUT  :OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
--INOUT
       MISO     :INOUT STD_LOGIC;
       MOSI     :INOUT STD_LOGIC;
       SCK      :INOUT STD_LOGIC;
       SS_NP    :INOUT STD_LOGIC_VECTOR(S_NUM-1 DOWNTO 0));--从选
END; 
ARCHITECTURE LIN OF CUS_SPI IS
  SIGNAL SPIBR     :STD_LOGIC_VECTOR(7 DOWNTO 0);--波特率寄存器
  SIGNAL DIVIDER   :STD_LOGIC_VECTOR(11 DOWNTO 0);
  SIGNAL DIV_COUNT :STD_LOGIC_VECTOR(11 DOWNTO 0);
  SIGNAL SPPR      :STD_LOGIC_VECTOR(2 DOWNTO 0);
  SIGNAL SPPR1     :STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL SPR       :STD_LOGIC_VECTOR(2 DOWNTO 0);
  SIGNAL CLK_TEMP  :STD_LOGIC;
  SIGNAL BAUD_CLK  :STD_LOGIC; --生成的波特时钟
-------------------------------------------------------------------
  SIGNAL SLAVE_SELECT:INTEGER RANGE 0 TO 8;--从选寄存器
  SIGNAL SS_N1       :STD_LOGIC;
  SIGNAL SS_N        :STD_LOGIC; --内部使用的从选端 
  SIGNAL CLK_SCK     :STD_LOGIC; --内部使用的波特时钟 
  SIGNAL CLK_MID     :STD_LOGIC; --中转时钟
  SIGNAL CLK_MASK    :STD_LOGIC; --CPHA='1'时空闲时钟屏蔽
  SIGNAL SPTEF_A     :STD_LOGIC; 
  SIGNAL SPTEF_B     :STD_LOGIC;
  SIGNAL SPIF_A      :STD_LOGIC;
  SIGNAL SPIF_B      :STD_LOGIC;
  SIGNAL XXXX        :STD_LOGIC; --消除系统启动时从选为低信号
  SIGNAL XXXX_A      :STD_LOGIC;
  SIGNAL XXXX_B      :STD_LOGIC;
  SIGNAL DDDD        :STD_LOGIC; --防止系统启动时移位寄存器工作
  SIGNAL DDDD_A      :STD_LOGIC;
  SIGNAL DDDD_B      :STD_LOGIC;
  SIGNAL SHIFTOUT_EMPTY :STD_LOGIC;
  SIGNAL SHIFTOUT_EMPTY_A:STD_LOGIC;
  SIGNAL SHIFTOUT_EMPTY_B:STD_LOGIC;
  SIGNAL SHIFTIN_FULL :STD_LOGIC;
  SIGNAL SHIFTIN_FULL_A:STD_LOGIC;
  SIGNAL SHIFTIN_FULL_B:STD_LOGIC;
  SIGNAL M_COUNT_EN:STD_LOGIC;
  SIGNAL BAUD_CLK_CPHA:STD_LOGIC;
  SIGNAL BAUD_CLK_CPHA_L:STD_LOGIC;
  SIGNAL BAUD_CLK_CPHA_C:STD_LOGIC;
  SIGNAL BAUD_CLK_CPHA_FALLEDGE:STD_LOGIC;
  SIGNAL BAUD_CLK_CPHA_RISINGEDGE:STD_LOGIC;
  SIGNAL BAUD_CLK_L:STD_LOGIC;
  SIGNAL BAUD_CLK_C:STD_LOGIC;
  SIGNAL BAUD_CLK_FALLEDGE:STD_LOGIC;
  SIGNAL BAUD_CLK_RISINGEDGE:STD_LOGIC; 
  SIGNAL CLK_SCK_CPHA:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_L:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_C:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_FALLEDGE:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_RISINGEDGE:STD_LOGIC; 
  SIGNAL CLK_SCK_CPHA_SS_N:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_SS_N_L:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_SS_N_C:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_SS_N_FALLEDGE:STD_LOGIC;
  SIGNAL CLK_SCK_CPHA_SS_N_RISINGEDGE:STD_LOGIC;
  SIGNAL BITIN       :STD_LOGIC; 
  SIGNAL BITOUT      :STD_LOGIC; 
  SIGNAL M_COUNT    :STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL SHIFT_COUNT:STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL SHIFT_IN     :STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL SHIFT_OUT    :STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL DATAIN_BUF  :STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL DATAOUT_BUF :STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL SPICR1      :STD_LOGIC_VECTOR(7 DOWNTO 0);--控制寄存器1
  SIGNAL SPICR2      :STD_LOGIC_VECTOR(7 DOWNTO 0);--控制寄存器2
  SIGNAL SPISR       :STD_LOGIC_VECTOR(7 DOWNTO 0);--状态寄存器
--位信号定义-------------------------------------------------------
  SIGNAL SPIF    :STD_LOGIC;--字节传输结束标志
  SIGNAL SPTEF   :STD_LOGIC;--数据缓冲有空间中断标志
  SIGNAL MODF    :STD_LOGIC;--模式错误标志
  SIGNAL SPIE    :STD_LOGIC;--中断允许
  SIGNAL SPE     :STD_LOGIC;--系统使能
  SIGNAL SPTIE   :STD_LOGIC;--传输中断使能
  SIGNAL MSTR    :STD_LOGIC;--主/从模式选择
  SIGNAL CPOL    :STD_LOGIC;--时钟极性选择
  SIGNAL CPHA    :STD_LOGIC;--时钟相位选择
  SIGNAL SSOE    :STD_LOGIC;--从选输出使能
  SIGNAL LSBFE   :STD_LOGIC;--低位先出势使能
  SIGNAL MODFEN  :STD_LOGIC;--模式错误使能
  SIGNAL BIDIROE :STD_LOGIC;--双向模式输出使能
  SIGNAL SPISWAI :STD_LOGIC;--等待模式下停止位
  SIGNAL SPC0    :STD_LOGIC;--串行端口控制位(双向输出选择)
BEGIN
-----位信号分配-----------------------------------------------------
  SPIE <=SPICR1(7);
  SPE  <=SPICR1(6);
  SPTIE<=SPICR1(5);
  MSTR <=SPICR1(4);
  CPOL <=SPICR1(3);
  CPHA <=SPICR1(2);
  SSOE <=SPICR1(1);
  LSBFE<=SPICR1(0);
  MODFEN <=SPICR2(4);
  BIDIROE<=SPICR2(3);
  SPISWAI<=SPICR2(1);
  SPC0   <=SPICR2(0);
  SPISR<=(SPIF&'0'&SPTEF&MODF&'0'&'0'&'0'&'0');
-----时钟生成-----------------------------------------------------
  SPPR    <=SPIBR(6 DOWNTO 4);
  SPPR1   <=('0'&SPPR)+"0001";
  SPR     <=SPIBR(2 DOWNTO 0);
  BAUD_CLK<=CLK_TEMP;
PROCESS(SPPR1,SPR)
   BEGIN
    CASE SPR IS
      WHEN "000"=>DIVIDER<=("00000000"&SPPR1);
      WHEN "001"=>DIVIDER<=("0000000"&SPPR1&'0');
      WHEN "010"=>DIVIDER<=("000000"&SPPR1&"00");
      WHEN "011"=>DIVIDER<=("00000"&SPPR1&"000");
      WHEN "100"=>DIVIDER<=("0000"&SPPR1&"0000");
      WHEN "101"=>DIVIDER<=("000"&SPPR1&"00000");
      WHEN "110"=>DIVIDER<=("00"&SPPR1&"000000");
      WHEN "111"=>DIVIDER<=('0'&SPPR1&"0000000");
      WHEN OTHERS=>DIVIDER<="XXXXXXXXXXXX";
    END CASE;
END PROCESS;
PROCESS(SYS_CLK,DIV_COUNT,DIVIDER,CLK_TEMP)
   BEGIN
     IF  SYS_CLK'EVENT AND SYS_CLK='1' THEN
        IF DIV_COUNT>=DIVIDER-1 THEN 
         DIV_COUNT<="000000000000";
         CLK_TEMP<=NOT CLK_TEMP;
        ELSE
         DIV_COUNT<=DIV_COUNT+1;
        END IF;      
     END IF; 
END PROCESS;
----内部寄存器写入/读出----------------------------------------------
PROCESS(CS,SYS_CLK,ADDR,DATAIN,SPICR1,SPICR2,SPIBR,SPISR,DATAIN_BUF,SHIFTOUT_EMPTY_B,SPTEF_A,SPIF_A)
   BEGIN
    IF  CS='1' THEN 
     IF  SYS_CLK'EVENT AND SYS_CLK='1' THEN
        IF WR_N='0' THEN 
         CASE ADDR IS
          WHEN "000"=>SPICR1<=DATAIN;XXXX_A<=XXXX_B;DDDD_A<=DDDD_B;
          WHEN "001"=>SPICR2<=DATAIN AND "00011011";
          WHEN "010"=>SPIBR<=DATAIN AND "01110111";
          WHEN "100"=>SLAVE_SELECT<=CONV_INTEGER(DATAIN);
          SHIFTOUT_EMPTY_A<=NOT SHIFTOUT_EMPTY_B;SHIFTIN_FULL_B<=SHIFTIN_FULL_A;
          WHEN "101"=>DATAOUT_BUF<=DATAIN;SPTEF_A<=SPTEF_B;
          WHEN OTHERS=>NULL;
         END CASE;
        ELSIF RD_N='0' THEN
         CASE ADDR IS
          WHEN "000"=>DATAOUT<=SPICR1;
          WHEN "001"=>DATAOUT<=SPICR2;
          WHEN "010"=>DATAOUT<=SPIBR;
          WHEN "011"=>DATAOUT<=SPISR;
          WHEN "100"=>DATAOUT<=CONV_STD_LOGIC_VECTOR(SLAVE_SELECT,8);
          WHEN "101"=>DATAOUT<=DATAOUT_BUF;
          WHEN "110"=>DATAOUT<=DATAIN_BUF;SPIF_B<=SPIF_A;
          WHEN "111"=>DATAOUT<="00000000";
          WHEN OTHERS=>NULL;
         END CASE;
        END IF;      
     END IF; 
    END IF;
END PROCESS;
----端口控制---------------------------------------------------------
     MOSI<=BITOUT WHEN SPE='1' AND MSTR='1' ELSE
           'Z';
     MISO<=BITOUT WHEN SPE='1' AND MSTR='0' ELSE
           'Z';
     BITIN<=MOSI  WHEN SPE='1' AND MSTR='0' ELSE
            MISO  WHEN SPE='1' AND MSTR='1' ELSE
            'Z';
     SS_NP<=(S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=1 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=2 ELSE
            (S_NUM-3=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=3 ELSE
            (S_NUM-4=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=4 ELSE
            (S_NUM-5=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=5 ELSE
            (S_NUM-6=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=6 ELSE
            (S_NUM-7=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=7 ELSE
            (S_NUM-8=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=1 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=2 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=3 ELSE
            (S_NUM-3=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=4 ELSE
            (S_NUM-4=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=5 ELSE
            (S_NUM-5=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=6 ELSE
            (S_NUM-6=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=7 ELSE
            (S_NUM-7=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=2 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=3 AND S_NUM=3 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=3 AND S_NUM=4 ELSE
            (S_NUM-3=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=3 AND S_NUM=5 ELSE
            (S_NUM-4=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=3 AND S_NUM=6 ELSE
            (S_NUM-5=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=3 AND S_NUM=7 ELSE
            (S_NUM-6=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=3 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=4 AND S_NUM=4 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=4 AND S_NUM=5 ELSE
            (S_NUM-3=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=4 AND S_NUM=6 ELSE
            (S_NUM-4=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=4 AND S_NUM=7 ELSE
            (S_NUM-5=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=4 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=5 AND S_NUM=5 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=5 AND S_NUM=6 ELSE
            (S_NUM-3=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=5 AND S_NUM=7 ELSE
            (S_NUM-4=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=5 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=6 AND S_NUM=6 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=6 AND S_NUM=7 ELSE
            (S_NUM-3=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=6 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=7 AND S_NUM=7 ELSE
            (S_NUM-2=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=7 AND S_NUM=8 ELSE
            (S_NUM-1=>SS_N,OTHERS=>'1')  WHEN SSOE='1' AND MSTR='1' AND SLAVE_SELECT=8 AND S_NUM=8 ELSE
            (OTHERS=>'Z');
     SCK<=CLK_MID WHEN SSOE='1' AND MSTR='1' ELSE
           'Z';
PROCESS(SPIE,SPIF)
   BEGIN
    IF SPIE='1' THEN 
     INT_SPIF<=SPIF;  ------中断
    ELSE
     INT_SPIF<='0';
    END IF;
END PROCESS;
--从选生成------------------------------------------------------------
PROCESS(MSTR,SYS_CLK,BAUD_CLK,SS_N,M_COUNT,BAUD_CLK_C,BAUD_CLK_L)
  BEGIN
  IF MSTR='1' THEN 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -