📄 ds18b20.vhd
字号:
--测温仪表的顶层文件
--本设计主要使用了有限状态机来实现DS18B20所需要的
--1-Wire总线的各种操作时序
--硬件测试:通过
--作者:Michael
--时间:2006.10.20
--版本:定稿版
Library IEEE;
use ieee.std_logic_1164.all;
Library LPM;
use LPM.lpm_components.all;
Entity DS18b20 is
Port(dq:inout std_logic_vector(0 to 0); --双向I/O
clock:in std_logic; --20MHz系统时钟输入
-- closedots:out std_logic_vector(7 downto 0); --关闭点阵显示
-- bitvector:out std_logic_vector(7 downto 0); --数码管段选信号
-- wordselect:out std_logic_vector(5 downto 0)); --数码管位选信号
ramdata:out std_logic_vector(10 downto 0));
END DS18b20;
Architecture rtl of DS18b20 is
--1MHz的时钟
signal clk_1u:std_logic;
--定义了主控状态机的各种状态
type statetype is (resetstart,wait_480u,wait_70u,wait_410u,reset_jump,
wmaster1,write1_1,wait1_64u,write1_0,wait1_10u,wstop1,
tempstay_750m,wmaster2,write2_1,wait2_64u,write2_0,
wait2_10u,wstop2,rmaster,rwait_6u,rwait_9u,rwait_55u,rstop,display);
signal allstate:statetype :=resetstart;
--与三态门的接口信号
signal result:std_logic_vector(0 to 0) :="0"; --dq端口的输入值
constant data:std_logic_vector(0 to 0) :="0"; --dq端口的输出值
signal enabledt:std_logic; --data->>dq传送使能控制
constant enabletr:std_logic :='1'; --dq->>result传送使能控制,一直打开
--三态门的元件声明
COMPONENT lpm_bustri
GENERIC (
lpm_type : STRING;
lpm_width : NATURAL
);
PORT (
enabletr : IN STD_LOGIC ;
enabledt : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
tridata : INOUT STD_LOGIC_VECTOR (0 DOWNTO 0)
);
END COMPONENT;
--与显示数据模块接口信号
-- signal ramdata:std_logic_vector(11 downto 1); --从RAM 中读出的数据
-- signal gate:std_logic :='0'; --是否显示新数据的门控信号
--显示数据的元件声明
-- COMPONENT led_convertor
-- Port(clock:in std_logic;
-- gate:in std_logic;
-- temperaturein:in std_logic_vector(10 downto 0);
-- bitvector:out std_logic_vector(7 downto 0);
-- wordselect:out std_logic_vector(5 downto 0));
-- END COMPONENT;
Begin
--三态门的元件例化
lpm_bustri_component : lpm_bustri
GENERIC MAP (
lpm_type => "LPM_BUSTRI",
lpm_width => 1
)
PORT MAP (
enabletr => enabletr,
enabledt => enabledt,
data => data,
result => result,
tridata => dq
);
-- --显示数据部分元件例化
--display_component:led_convertor
-- PORT MAP(clock=>clk_1u,gate=>gate,
-- temperaturein=>ramdata,
-- bitvector=>bitvector,
-- wordselect=>wordselect);
--
-- --关闭点阵显示
-- closedots<="11111111";
--分频得到1MHz的时钟
subclk_1us:Process(clock,clk_1u)
variable temp:integer range 0 to 10 :=0;
Begin
if(clock'event and clock='1') then
if(temp=10) then
temp:=0;
clk_1u<=not clk_1u;
else
temp:=temp+1;
end if;
end if;
End Process;
--状态机处理转换程序
Reset1:Process(clk_1u)
variable temp0: integer range 0 to 750000 :=0; --延时变量
variable cnter: integer range 0 to 17 :=0; --读写计数变量
variable present: std_logic :='1'; --复位应答数据暂存器
variable flag:std_logic :='0'; --跳转标志
--暂存读取DS18B20的RAM中的数据
variable buf:std_logic_vector(10 downto 0);
Begin
if(clk_1u'event and clk_1u='1') then
case allstate is
when resetstart => --start reset phase
allstate<=wait_480u;
enabledt<='1'; --将dq强制拉低
when wait_480u =>
if(temp0=480) then
allstate<=wait_70u;
enabledt<='0'; --放开总线
temp0:=0;
else
allstate<=wait_480u;
temp0:=temp0+1;
end if;
when wait_70u =>
if(temp0=70) then
allstate<=wait_410u;
present:=result(0); --读取dq的值
temp0:=0;
else
allstate<=wait_70u;
temp0:=temp0+1;
end if;
when wait_410u =>
if(temp0=410) then
allstate<=reset_jump;
temp0:=0;
else
allstate<=wait_410u;
temp0:=temp0+1;
end if;
when reset_jump =>
if(present='0') then
present:='1';
if(flag='0') then
allstate<=wmaster1;
flag:='1';
elsif(flag='1') then
allstate<=wmaster2;
flag:='0';
end if;
else
allstate<=resetstart;
present:='1';
end if;
when wmaster1 => --write command CCH and 44H
if(cnter=17) then
allstate<=wstop1;
cnter:=0;
else
cnter:=cnter+1;
case cnter is
when 1 => allstate<=write1_0;enabledt<='1';--将dq强制拉低
when 2 => allstate<=write1_0;enabledt<='1';
when 5 => allstate<=write1_0;enabledt<='1';
when 6 => allstate<=write1_0;enabledt<='1';
when 9 => allstate<=write1_0;enabledt<='1';
when 10 => allstate<=write1_0;enabledt<='1';
when 12 => allstate<=write1_0;enabledt<='1';
when 13 => allstate<=write1_0;enabledt<='1';
when 14 => allstate<=write1_0;enabledt<='1';
when 16 => allstate<=write1_0;enabledt<='1';
when 3 => allstate<=write1_1;enabledt<='1';
when 4 => allstate<=write1_1;enabledt<='1';
when 7 => allstate<=write1_1;enabledt<='1';
when 8 => allstate<=write1_1;enabledt<='1';
when 11 => allstate<=write1_1;enabledt<='1';
when 15 => allstate<=write1_1;enabledt<='1';
when others => allstate<=wmaster1;
end case;
end if;
when write1_1 => --write '1'
if(temp0=6) then
allstate<=wait1_64u;
enabledt<='0'; --6us后放开总线
temp0:=0;
else
allstate<=write1_1;
temp0:=temp0+1;
end if;
when wait1_64u =>
if(temp0=64) then
allstate<=wmaster1;
temp0:=0;
else
allstate<=wait1_64u;
temp0:=temp0+1;
end if;
when write1_0 => --write '0'
if(temp0=60) then
allstate<=wait1_10u;
enabledt<='0'; --60us后放开总线
temp0:=0;
else
allstate<=write1_0;
temp0:=temp0+1;
end if;
when wait1_10u =>
if(temp0=10) then
allstate<=wmaster1;
temp0:=0;
else
allstate<=wait1_10u;
temp0:=temp0+1;
end if;
when wstop1 =>
enabledt<='0';--写命令结束放开总线
allstate<=tempstay_750m;
when tempstay_750m => --wait for 750ms
if(temp0=5) then --The prevalue is 750000 ,now modified to 5us
allstate<=resetstart;
temp0:=0;
else
allstate<=tempstay_750m;
temp0:=temp0+1;
end if;
when wmaster2 => --write command CCH and BEH
if(cnter=17) then
allstate<=wstop2;
cnter:=0;
else
cnter:=cnter+1;
case cnter is
when 1 => allstate<=write2_0;enabledt<='1';--将总线强制拉低
when 2 => allstate<=write2_0;enabledt<='1';
when 5 => allstate<=write2_0;enabledt<='1';
when 6 => allstate<=write2_0;enabledt<='1';
when 9 => allstate<=write2_0;enabledt<='1';
when 15 => allstate<=write2_0;enabledt<='1';
when 3 => allstate<=write2_1;enabledt<='1';
when 4 => allstate<=write2_1;enabledt<='1';
when 7 => allstate<=write2_1;enabledt<='1';
when 8 => allstate<=write2_1;enabledt<='1';
when 10 => allstate<=write2_1;enabledt<='1';
when 11 => allstate<=write2_1;enabledt<='1';
when 12 => allstate<=write2_1;enabledt<='1';
when 13 => allstate<=write2_1;enabledt<='1';
when 14 => allstate<=write2_1;enabledt<='1';
when 16 => allstate<=write2_1;enabledt<='1';
when others => allstate<=wmaster2;
end case;
end if;
when write2_1 =>
if(temp0=6) then
allstate<=wait2_64u;
enabledt<='0'; --6us后放开总线
temp0:=0;
else
allstate<=write2_1;
temp0:=temp0+1;
end if;
when wait2_64u =>
if(temp0=64) then
allstate<=wmaster2;
temp0:=0;
else
allstate<=wait2_64u;
temp0:=temp0+1;
end if;
when write2_0 =>
if(temp0=60) then
allstate<=wait2_10u;
enabledt<='0';--60us后放开总线
temp0:=0;
else
allstate<=write2_0;
temp0:=temp0+1;
end if;
when wait2_10u =>
if(temp0=10) then
allstate<=wmaster2;
temp0:=0;
else
allstate<=wait2_10u;
temp0:=temp0+1;
end if;
when wstop2 =>
enabledt<='0';--写命令结束放开总线
allstate<=rmaster;
when rmaster => --读取温度数据
if(cnter=11) then
allstate<=rstop;
cnter:=0;
else
allstate<=rwait_6u;
cnter:=cnter+1;
enabledt<='1'; --将dq强制拉低
end if;
when rwait_6u =>
if(temp0=6) then
allstate<=rwait_9u;
enabledt<='0'; --放开总线
temp0:=0;
else
allstate<=rwait_6u;
temp0:=temp0+1;
end if;
when rwait_9u =>
if(temp0=9) then
allstate<=rwait_55u;
buf(cnter-1):=result(0); --读入dq的数值
temp0:=0;
else
allstate<=rwait_9u;
temp0:=temp0+1;
end if;
when rwait_55u =>
if(temp0=55) then
allstate<=rmaster;
temp0:=0;
else
allstate<=rwait_55u;
temp0:=temp0+1;
end if;
when rstop =>
enabledt<='0'; --读数据结束放开总线
ramdata<=buf; --将数据传送出去
allstate<=display;
when display => --start display process
if(temp0=1) then
allstate<=resetstart;
-- gate<='0';
temp0:=0;
else
temp0:=temp0+1;
-- gate<='1';
allstate<=display;
end if;
end case;
end if;
end process;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -