⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20.vhd

📁 这是一个工业用的普通温度传感器DS18b20的VHDL文件
💻 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 + -