Möchte man seine EA-Ports erweitern, bietet sich das SPI Protokoll geradezu an, denn fast jeder uC hat eine solche Schnittstelle. Und falls keine da ist, kann sie leicht in Software gehackt werden. Auf der Empfängerseite bieten sich CPLDs an: viele IO-Pins ergeben viele Anschlussmöglichkeiten, und die Registerdichte ist ausreichend. Hier eine Implementation für 24 Ein- und Ausgänge, die in einem XC9572 CPLD realisiert wurde.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SPI_Slave is
Generic ( breite: natural := 24);
Port ( SCLK : in STD_LOGIC;
SS : in STD_LOGIC;
MOSI : in STD_LOGIC;
MISO : out STD_LOGIC;
Dout : out STD_LOGIC_VECTOR (breite-1 downto 0);
Din : in STD_LOGIC_VECTOR (breite-1 downto 0));
end SPI_Slave;
architecture Behavioral of SPI_Slave is
signal dinsr : STD_LOGIC_VECTOR (breite-1 downto 0);
signal doutsr : STD_LOGIC_VECTOR (breite-1 downto 0);
begin
-- Parallel-Eingänge --> MISO
process (SS, Din, SCLK)
begin
if (SS='1') then
dinsr <= Din;
elsif falling_edge(SCLK) then -- nach der fallenden SCLK-Flanke
dinsr <= dinsr(dinsr'left-1 downto 0) & '0'; -- wird MISO aktualisiert
end if;
end process;
MISO <= dinsr(dinsr'left) when SS='0' else 'Z';
-- MOSI --> Parallel-Ausgänge
process (SCLK)
begin
if rising_edge(SCLK) then -- mit der steigenden SCLK-Flanke
doutsr <= doutsr(doutsr'left-1 downto 0) & MOSI; -- wird MOSI eingelesen
end if;
end process;
process (SS)
begin
if rising_edge(SS) then -- Device wird deselektiert
Dout <= doutsr; -- Ausgangssignale an die Pins durchgeben
end if;
end process;
end Behavioral;
Die Kommunikation findet im SPI-Modus 0 statt. Ruhezustand SCLK ist demnach LOW, die Daten werden an der steigenden Flanke eingelesen, und an der fallenden Flanke geändert.
Im weiteren Eintrag findet sich eine Testbench für das obige Design.
"SPI-Slave im CPLD" vollständig lesen »