سلام دوستان من یه پروژه دارم راه اندازی سنسور ds18b20 با fpga به زبان vhdl برنامشم چنتا از نت پیدا کردم . فقط میخام دوستان بگند چطور کار میکنه . ممنون

--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity temperature is
port
(
clk1m: in std_logic;
temper: out std_logic_vector(15 downto 0);
wireout: inout std_logic
);
end temperature;

architecture Behavioral of temperature is
type state_type is (s0,s1,s2,s3,s4,s5,s6,s7,w0,w3,w1,w2,read0,read1,r ead2,read3);
signal state: state_type;
signal temp: std_logic_vector( 15 downto 0);
signal reset: std_logic; --对i进行置0
signal i: integer range 0 to 1000000;
begin

temper<= temp;

process(clk1m)
variable j : integer range 0 to 15;
variable flag : integer range 0 to 60;
begin
if rising_edge(clk1m) then
case state is

when s0 => --初始化ds18b20
wireout<='0'; --主机拉底总线
reset<='1';
state<=s1;

when s1 =>
reset<='0';
if(i=500) then --延时500us
wireout<='Z'; --释放总线
reset<='1';
state<=s2;
end if;

when s2 =>
reset<='0';
if (i=100) then --等待100us
reset<='1';
state<=s3;
end if;

when s3 =>
if(wireout='0&#039 then --若18b20拉低总线,初始化成功
state<=s4;
elsif(wireout='1&#039 then --否则,初始化不成功,返回S0
state<=s0;
end if;

when s4 =>
reset<='0';
if(i=400) then --再延时400us
reset<='1';
state<=s5;
end if;

when s5 => --写数据
--cch 忽略 64 位 ROM 地址,直接向 DS1820 发温度变换命令。
if (flag = 0 ) then flag:=1;state <=w0;
elsif (flag = 1 ) then flag:=2;state <=w0;
elsif (flag = 2 ) then flag:=3;state <=w2;wireout<='0';
elsif (flag = 3 ) then flag:=4;state <=w2;wireout<='0';
elsif (flag = 4 ) then flag:=5;state <=w0;
elsif (flag = 5 ) then flag:=6;state <=w0;
elsif (flag = 6 ) then flag:=7;state <=w2;wireout<='0';
elsif (flag = 7 ) then flag:=8;state <=w2;wireout<='0';
--44h 启动DS1820进行温度转换,12位转换时最长为750ms,结果存入内部9字节RAM中。
elsif (flag = 8 ) then flag:=9 ;state <=w0;
elsif (flag = 9 ) then flag:=10;state <=w0;
elsif (flag = 10 ) then flag:=11;state <=w2;wireout<='0';
elsif (flag = 11 ) then flag:=12;state <=w0;
elsif (flag = 12 ) then flag:=13;state <=w0;
elsif (flag = 13 ) then flag:=14;state <=w0;
elsif (flag = 14 ) then flag:=15;state <=w2;wireout<='0';
elsif (flag = 15 ) then flag:=16;state <=w0;

--第一次写完,750ms后,跳回s0
elsif (flag = 16 ) then flag:=20;state <=s6;wireout<='Z';

--再次置数 cch和beh
elsif (flag = 20 ) then flag:=21;state <=w0; --cch
elsif (flag = 21 ) then flag:=22;state <=w0;
elsif (flag = 22 ) then flag:=23;state <=w2;wireout<='0';
elsif (flag = 23 ) then flag:=24;state <=w2;wireout<='0';
elsif (flag = 24 ) then flag:=25;state <=w0;
elsif (flag = 25 ) then flag:=26;state <=w0;
elsif (flag = 26 ) then flag:=27;state <=w2;wireout<='0';
elsif (flag = 27 ) then flag:=28;state <=w2;wireout<='0';
--beh 10111110 读9字节RAM中的植
elsif (flag = 28 ) then flag:=29;state <=w0;
elsif (flag = 29 ) then flag:=30;state <=w2;wireout<='0';
elsif (flag = 30 ) then flag:=31;state <=w2;wireout<='0';
elsif (flag = 31 ) then flag:=32;state <=w2;wireout<='0';
elsif (flag = 32 ) then flag:=33;state <=w2;wireout<='0';
elsif (flag = 33 ) then flag:=34;state <=w2;wireout<='0';
elsif (flag = 34 ) then flag:=35;state <=w0;
elsif (flag = 35 ) then flag:=36;state <=w2;wireout<='0';

--第二次写完,跳到s7,直接开始读数据
elsif (flag = 36 ) then flag:=40;state <=s7;
end if;

when s6 =>
reset<='0';
if (i = 750000 or wireout='1' ) then --延时750ms
state <= s0;
reset<='1'; --跳回s0,再次初始化
end if;

when s7 => --读数据
if (flag = 40 ) then flag:=41; state<=read0;j:=0; wireout<='0';
elsif (flag = 41 ) then flag:=42; state<=read0;j:=1; wireout<='0';
elsif (flag = 42 ) then flag:=43; state<=read0;j:=2; wireout<='0';
elsif (flag = 43 ) then flag:=44; state<=read0;j:=3; wireout<='0';
elsif (flag = 44 ) then flag:=45; state<=read0;j:=4; wireout<='0';
elsif (flag = 45 ) then flag:=46; state<=read0;j:=5; wireout<='0';
elsif (flag = 46 ) then flag:=47; state<=read0;j:=6; wireout<='0';
elsif (flag = 47 ) then flag:=48; state<=read0;j:=7; wireout<='0';
elsif (flag = 48 ) then flag:=49; state<=read0;j:=8; wireout<='0';
elsif (flag = 49 ) then flag:=50; state<=read0;j:=9; wireout<='0';
elsif (flag = 50 ) then flag:=51; state<=read0;j:=10;wireout<='0';
elsif (flag = 51 ) then flag:=52; state<=read0;j:=11;wireout<='0';
elsif (flag = 52 ) then flag:=53; state<=read0;j:=12;wireout<='0';
elsif (flag = 53 ) then flag:=54; state<=read0;j:=13;wireout<='0';
elsif (flag = 54 ) then flag:=55; state<=read0;j:=14;wireout<='0';
elsif (flag = 55 ) then flag:=60; state<=read0;j:=15;wireout<='0';

elsif (flag = 60 ) then flag:=0;state<=s0;
end if;
----------------------------------写状态机------------------------------

when w0 =>
wireout<='0'; --输出0
reset<='0';
if (i = 80) then --延时80us
wireout<='Z'; --释放总线,自动拉高
reset<='1';
state<=w1;
end if;
when w1 =>
state<=s5; --空状态

when w2=>
state<=w3; --空状态
when w3 =>
wireout<='1'; --输出1 释放总线,自动拉高
reset<='0';
if (i = 80) then --延时80us
reset<='1';
state<=s5;
end if;
----------------------------------读状态机------------------------------------------

when read0=>
state <= read1; --空延时状态

when read1=>
wireout <= 'Z'; --释放总线
reset<='0';
if (i = 10) then --再延时10us
reset<='1';
state <= read2;
end if;

when read2=>
temp(j)<= wireout; --读到的数据给LED
state <= read3;

when read3=>
reset<='0';
if (i = 55) then --再延时55us
reset<='1';
state <= s7;
end if;

------------------------------------------------------------------------------

when others =>
state <=s0;
end case;

end if;
end process;

process(clk1m,reset)
begin
if (reset='1&#039then
i<=0;
elsif rising_edge(clk1m) then
i<=i+1;
end if;
end process;

end Behavioral;