You are on page 1of 6

12 Bit SPI ADC

These ADCs are SPI Bus based which is a serial bus. So the number of pins in IC is very low.

Interfacing SPI ADC with Spartan-3E FPGA

The Spartan-3E board has 2-channel 12 Bit SPI ADC, indicated as in Figure. As you know in synchronous serial
communication there is a clock line (SCK in case of SPI) which synchronizes the transfer. The clock is always controlled
by the MASTER. In our case the Spartan3AN is the MASTER and the MCP3202 is a slave on the bus. SPI is full duplex,
which means data can be sent and received simultaneously.

A SPI transfer is initiated by the MASTER pulling the CS line low. The CS line sits at HIGH during idle state. Now master
can write to the bus in 8bit (or 1 byte) chunks. One most important thing to note about SPI is that for every byte MASTER
writes to SLAVE the MASTER receives one byte in return. So the only transaction possible is exchange of data.

Pin Assignment with Spartan-3E FPGA

ADC PIN

SPARTAN3E
FPGA Lines

DOUT

P39

DIN

P40

SCK

P36

CS

P35

Circuit Diagram to Interface SPI ADC with Spartan-3E

VHDL Program for ADC to UART using Spartan-3E FPGA

***************************************************************************************

Title : Program for UART to LED Display

***************************************************************************************

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 adc_ch0 is
port ( clk : in std_logic;

cs : out std_logic;
sc : out std_logic;
do : out std_logic;
din : in std_logic;
dout : out std_logic);
end adc_ch0;
architecture Behavioral of adc_ch0 is
type state is (spi,conversion,transmission);
signal presentstate : state := spi;
signal f : std_logic;
type arr is array (0 to 12) of std_logic_vector(9 downto 0);
signal store : arr;
begin
process(clk)
--variable i : std_logic_vector(12 downto 0) := "0000000000000";
variable i,j,k : integer := 0;
variable tot : std_logic_vector(11 downto 0) := "000000000000";
begin
if clk'event and clk = '1' then
if presentstate = spi then
if i <= 50 then ---"0000000110010" then
i := i + 1;
sc <= '1';
elsif i > 50 and i < 100 then ---"0000000110010" and i < "0000001100100" then
i := i + 1;
sc <= '0';
elsif i = 100 then ---"0000001100100" then
i := 0; ----"0000000000000";
if j < 18 then
j := j + 1;
elsif j = 18 then
presentstate <= conversion;
j := 0;
end if;
end if;
if j = 0 or j >= 18 then
cs <= '1';
else
cs <= '0';
end if;
if i > 40 and i < 60 then --- "0000000101000" and i < "0000000111100" then
case j is
when 0 =>
do <= '0';
when 1 =>
do <= '1';
when 2 =>
do <= '1';

when 3 =>
do <= '0';
-----channel bit
when 4 =>
do <= '1';
when others =>
null;
end case;
end if;
if i >= 0 and i < 10 then --"0000000000000" and i < "0000000001010" then
case j is
when 6 =>
tot(3) := din;
when 7 =>
tot(2) := din;
when 8 =>
tot(1) := din;
when 9 =>
tot(0) := din;
when 10 =>
tot(7) := din;
when 11 =>
tot(6) := din;
when 12 =>
tot(5) := din;
when 13 =>
tot(4) := din;
when 14 =>
tot(11) := din;
when 15 =>
tot(10) := din;
when 16 =>
tot(9) := din;
when 17 =>
tot(8) := din;
when others =>
null;
end case;
end if;
end if;
-------------------------------------------------------------if presentstate = conversion then
cs <= '1';
store(0) <= "1010000010";
store(1) <= "1010001000";
store(2) <= "1010000110";
store(3) <= "1010111110";
store(4) <= "1010011110";
store(5) <= "1010101010";
store(6) <= "1010101000";
store(7) <= "1001110100";

if tot(3 downto 0) <= "1001" then


store(8) <= "10011" & tot(3 downto 0) & '0';
elsif tot(3 downto 0) > "1001" then
store(8) <= "10011" & "1001" & '0';
end if;
store(9) <= "1001011100";
if tot(7 downto 4) <= "1001" then
store(10) <= "10011" & tot(7 downto 4) & '0';
elsif tot(7 downto 4) > "1001" then
store(10) <= "10011" & "1001" & '0';
end if;
if tot(11 downto 8) <= "1001" then
store(11) <= "10011" & tot(11 downto 8) & '0';
elsif tot(11 downto 8) > "1001" then
store(11) <= "10011" & "1001" & '0';
end if;
store(12) <= "1000011010";
---0.0
if i < 5000 then --"1001110001000" then
i := i + 1;
elsif i = 5000 then --"1001110001000" then
i := 0; ---"0000000000000";
presentstate <= transmission;
end if;
end if;
-------------------------------------------------------------if presentstate = transmission then
cs <= '1';
if i < 5209 then --"1010001011001" then
i := i + 1 ; --"0000000000001";
dout <= store(k)(j);
elsif i = 5209 then --"1010001011001" then
if j < 9 then
j := j + 1;
elsif j = 9 then
j := 0 ;
if k < 12 then
k := k + 1;
elsif k = 12 then
presentstate <= spi;
k := 0;
end if;
end if;
i := 0; --"0000000000000";
end if;
end if;
end if;
-----------------------------------------------------end process;
---------------------------------------------------------

end Behavioral;

You might also like