|
发表于 2008-5-16 08:54:49
|
显示全部楼层
我们刚开始学fpga是做过18b20,使用数百个状态机累出来了,那个真痛苦
Library IEEE;
Use IEEE.Std_Logic_1164.All;
Entity b is
Port
(
led : out std_logic_vector(0 to 16);
wireout : inout std_logic;
clk : in std_logic;
rst : in std_logic );
End entity b;
Architecture init of b is
type init_states is (s00,s0,s1,s2,s3,s4,s5,s6,s7,w0,w1,w00,w01,read0,read1,read2,read3);
signal state : init_states;
signal i : integer Range 0 to 1000000;
signal reset : std_logic;
begin
process (rst,wireout,clk)
--variable i : Integer Range 0 to 1000;
variable flag: Integer Range 0 to 200;
variable light: Integer Range 0 to 16;
begin
if rst = '0' then
state <= s00;
wireout <= 'Z';
flag:=0;
elsif rising_edge(clk) then
case state is
when s00=> flag:=0;
led(0 )<='1';
led(1 )<='1';
led(2 )<='1';
led(3 )<='1';
led(4 )<='1';
led(5 )<='0';
led(6 )<='0';
led(7 )<='0';
led(8 )<='0';
led(9 )<='0';
led(10 )<='0';
led(11 )<='0';
led(12 )<='0';
led(13 )<='0';
led(14 )<='0';
led(15 )<='0';
led(16)<='0';
--标志位置0
state <=s0;
when s0 => --初始化18b20
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') then --若18b20拉低总线,初始化成功
state <=s4;
led(16)<='1'; --led16灯亮
elsif (wireout ='1') then --否则,初始化不成功,返回S0
state <= s0;
end if;
when s4 => reset<='0';
if (i = 400) then --再延时400us
reset<='1';
state <= s5;
end if;
when s5 => --写数据
if (flag = 0 ) then flag:=1;state <=w0; --cch
elsif (flag = 1 ) then flag:=2;state <=w0;
elsif (flag = 2 ) then flag:=3;state <=w01;wireout<='0';
elsif (flag = 3 ) then flag:=4;state <=w01;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 <=w01;wireout<='0';
elsif (flag = 7 ) then flag:=8;state <=w01;wireout<='0';
elsif (flag = 8 ) then flag:=9 ;state <=w0; --44h
elsif (flag = 9 ) then flag:=10;state <=w0;
elsif (flag = 10 ) then flag:=11;state <=w01;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 <=w01;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 <=w01;wireout<='0';
elsif (flag = 23 ) then flag:=24;state <=w01;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 <=w01;wireout<='0';
elsif (flag = 27 ) then flag:=28;state <=w01;wireout<='0';
elsif (flag = 28 ) then flag:=29;state <=w0; --beh 10111110
elsif (flag = 29 ) then flag:=30;state <=w01;wireout<='0';
elsif (flag = 30 ) then flag:=31;state <=w01;wireout<='0';
elsif (flag = 31 ) then flag:=32;state <=w01;wireout<='0';
elsif (flag = 32 ) then flag:=33;state <=w01;wireout<='0';
elsif (flag = 33 ) then flag:=34;state <=w01;wireout<='0';
elsif (flag = 34 ) then flag:=35;state <=w0;
elsif (flag = 35 ) then flag:=36;state <=w01;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;light:=0; wireout<='0';
elsif (flag = 41 ) then flag:=42;state <=read0;light:=1; wireout<='0';
elsif (flag = 42 ) then flag:=43;state <=read0;light:=2; wireout<='0';
elsif (flag = 43 ) then flag:=44;state <=read0;light:=3; wireout<='0';
elsif (flag = 44 ) then flag:=45;state <=read0;light:=4; wireout<='0';
elsif (flag = 45 ) then flag:=46;state <=read0;light:=5; wireout<='0';
elsif (flag = 46 ) then flag:=47;state <=read0;light:=6; wireout<='0';
elsif (flag = 47 ) then flag:=48;state <=read0;light:=7; wireout<='0';
elsif (flag = 48 ) then flag:=49;state <=read0;light:=8; wireout<='0';
elsif (flag = 49 ) then flag:=50;state <=read0;light:=9; wireout<='0';
elsif (flag = 50 ) then flag:=51;state <=read0;light:=10;wireout<='0';
elsif (flag = 51 ) then flag:=52;state <=read0;light:=11;wireout<='0';
elsif (flag = 52 ) then flag:=53;state <=read0;light:=12;wireout<='0';
elsif (flag = 53 ) then flag:=54;state <=read0;light:=13;wireout<='0';
elsif (flag = 54 ) then flag:=55;state <=read0;light:=14;wireout<='0';
elsif (flag = 55 ) then flag:=60;state <=read0;light:=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<=w00;
end if;
when w00 => state<=s5; --空状态
when w01=> state<=w1; --空状态
when w1 => wireout<='Z'; --输出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=> led(light)<=wireout; --读到的数据给LED
state <= read3;
when read3=> reset<='0';
if (i = 55) then --再延时55us
reset<='1';
state <= s7;
end if;
------------------------------------------------------------------------------
when others =>
state <=s00;
end case;
end if;
end process;
process(clk,reset)
begin
if (reset='1')then
i<=0;
elsif rising_edge(clk) then i<=i+1;
end if;
end process;
end architecture init; |
|