📄 ds18b20.vhd
字号:
---------------------------------------------------------------------------------------------------
--*************************************************************************************************
-- CreateDate : 2007-07-24
-- ModifData : 2007-07-26
-- Description : DS18B20 ( Asynchronous, Data bits: 16 )
-- Author : Explorer01
-- Version : V1.0
--*************************************************************************************************
---------------------------------------------------------------------------------------------------
-- VHDL library Declarations
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Entity Declarations
ENTITY DS18B20 IS
PORT
(
RESET: IN STD_LOGIC;
CLK: IN STD_LOGIC;
Fresh: IN STD_LOGIC;
DQ: INOUT STD_LOGIC;
EOC: OUT STD_LOGIC;
PDATA: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END DS18B20;
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Architecture of Entity Declarations
ARCHITECTURE Behavioral OF DS18B20 IS
------------------------------------------------
CONSTANT STATE_RST1 : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
CONSTANT STATE_WRITE1 : STD_LOGIC_VECTOR(2 DOWNTO 0) := "001";
CONSTANT STATE_READ : STD_LOGIC_VECTOR(2 DOWNTO 0) := "010";
CONSTANT STATE_RST2 : STD_LOGIC_VECTOR(2 DOWNTO 0) := "011";
CONSTANT STATE_WRITE2 : STD_LOGIC_VECTOR(2 DOWNTO 0) := "100";
CONSTANT STATE_WAIT : STD_LOGIC_VECTOR(2 DOWNTO 0) := "101";
SIGNAL state : STD_LOGIC_VECTOR(2 DOWNTO 0);
------------------------------------------------
-- Command for DS18B20 : 0xBECC, 0x44CC
CONSTANT COMMAND1 : STD_LOGIC_VECTOR(15 DOWNTO 0) := B"1011_1110_1100_1100";
CONSTANT COMMAND2 : STD_LOGIC_VECTOR(15 DOWNTO 0) := B"0100_0100_1100_1100";
SIGNAL DATA : STD_LOGIC_VECTOR(15 DOWNTO 0); -- Temperature
------------------------------------------------
SIGNAL CLKCNT : STD_LOGIC_VECTOR(5 DOWNTO 0); -- 64uS
SIGNAL CLKRW, CLKread, CLKwrite0, CLKwrite1 : STD_LOGIC;
SIGNAL Count : INTEGER RANGE 0 TO 20;
------------------------------------------------
SIGNAL EOCtemp, VALUE : STD_LOGIC;
BEGIN
-------------------------------------------------
-- State
PROCESS( RESET, CLK, CLKCNT, CLKRW, Count, CLKwrite0, CLKwrite1, state, VALUE, Fresh )
BEGIN
-----------------------------------------------
-- The primary period for write and read
IF( RESET='0' ) THEN
CLKCNT <= "000000";
ELSIF( CLK'EVENT AND CLK='1' ) THEN
CLKCNT <= CLKCNT + 1;
END IF;
CLKRW <= CLKCNT(5); -- Period : 64uS
-----------------------------------------------
-- Write plus
-- Write "0"
IF( CLKCNT<61 ) THEN CLKwrite0 <= '0';
ELSE CLKwrite0 <= '1';
END IF;
-- Write "1"
IF( CLKCNT<5 ) THEN CLKwrite1 <= '0';
ELSE CLKwrite1 <= '1';
END IF;
-----------------------------------------------
-- Read plus
IF( CLKCNT<14 ) THEN CLKread <= '0';
ELSE CLKread <= '1';
END IF;
--=============================================
-- Update the state
IF( RESET='0' ) THEN
state <= STATE_RST1;
Count <= 0;
ELSIF( CLKRW'EVENT AND CLKRW='0' ) THEN
CASE state IS
-----------------------------------
-- RESET
WHEN STATE_RST1 =>
IF( Count>20 ) THEN Count <= 0; state <= STATE_WRITE1;
ELSE Count <= Count + 1;
END IF;
-----------------------------------
-- Write command to DS18B20 : 0xCC, 0xBE
WHEN STATE_WRITE1 =>
IF( Count>14 ) THEN Count <= 0; state <= STATE_READ;
ELSE Count <= Count + 1;
END IF;
-----------------------------------
-- Read the temperature from DS18B20
WHEN STATE_READ =>
IF( Count>14 ) THEN Count <= 0; state <= STATE_RST2;
ELSE Count <= Count + 1;
END IF;
-----------------------------------
-- Interval power
-----------------------------------
-----------------------------------
-- Start the converter for the next turn
WHEN STATE_RST2 =>
IF( Count>20 ) THEN Count <= 0; state <= STATE_WRITE2;
ELSE Count <= Count + 1;
END IF;
-----------------------------------
-- Write command to DS18B20 : 0xCC, 0x44
WHEN STATE_WRITE2 =>
IF( Count>14 ) THEN Count <= 0; state <= STATE_WAIT;
ELSE Count <= Count + 1;
END IF;
-----------------------------------
-----------------------------------
-- Wait for the next turn ... ( Update rate : 1S )
WHEN STATE_WAIT =>
Count <= 0;
IF( Fresh='0' ) THEN state <= STATE_RST1;
END IF;
-----------------------------------
WHEN OTHERS => Count <= 0;
END CASE;
END IF;
END PROCESS;
--==============================================
------------------------------------------------
-- End of getting temperature
PROCESS( state, Count, CLKwrite0, CLKwrite1 )
BEGIN
CASE state IS
-----------------------------------
-- RESET
WHEN STATE_RST1 =>
-- RESET PLUS
IF( Count<11 ) THEN VALUE <= '0'; -- 0
ELSE VALUE <= '1'; -- 1
END IF;
-----------------------------------
-- Write command to DS18B20 : 0xCC, 0xBE
WHEN STATE_WRITE1 =>
IF( COMMAND1(Count)='0' ) THEN VALUE <= CLKwrite0;
ELSE VALUE <= CLKwrite1;
END IF;
-----------------------------------
-- Read the temperature from DS18B20
WHEN STATE_READ =>
VALUE <= CLKwrite1;
-----------------------------------
-- Interval power
-----------------------------------
-----------------------------------
-- RESET
WHEN STATE_RST2 =>
-- RESET PLUS
IF( Count<11 ) THEN VALUE <= '0'; -- 0
ELSE VALUE <= '1'; -- 1
END IF;
-----------------------------------
-- Write command to DS18B20 : 0xCC, 0xBE
WHEN STATE_WRITE2 =>
IF( COMMAND2(Count)='0' ) THEN VALUE <= CLKwrite0;
ELSE VALUE <= CLKwrite1;
END IF;
-----------------------------------
WHEN OTHERS => VALUE <= '1';
END CASE;
END PROCESS;
--==============================================
------------------------------------------------
-- Getting the temperature
-- Read datum from DS18B20
PROCESS( RESET, DQ, VALUE, state, Count, CLKread, EOCtemp )
VARIABLE Receive : STD_LOGIC;
BEGIN
IF( RESET='0' ) THEN
DATA <= "0000000000000000";
ELSIF( state=STATE_READ ) THEN
IF( CLKread'EVENT AND CLKread='1' ) THEN
IF( Receive='0' ) THEN DATA(Count) <= '0';
ELSE DATA(Count) <= '1';
END IF;
END IF;
EOCtemp <= '0';
ELSE
EOCtemp <= '1';
END IF;
-----------------------------------------------
IF( VALUE='0' ) THEN DQ <= '0'; Receive := '1'; -- Output
ELSE DQ <= 'Z'; Receive := DQ; -- Input
END IF;
END PROCESS;
--==============================================
------------------------------------------------
-- End of getting temperature
PROCESS( RESET, EOCtemp, DATA )
VARIABLE FIGURE : INTEGER RANGE 0 TO 255;
VARIABLE VLOW, VHIGH : INTEGER RANGE 0 TO 15;
BEGIN
IF( RESET='0' ) THEN
PDATA <= "00000000";
ELSIF( EOCtemp'EVENT AND EOCtemp='1' ) THEN
-- BCD Code
PDATA <= CONV_STD_LOGIC_VECTOR(VHIGH, 4) & CONV_STD_LOGIC_VECTOR(VLOW, 4);
-- HEX Code
-- PDATA <= CONV_STD_LOGIC_VECTOR(FIGURE, 8);
END IF;
FIGURE := CONV_INTEGER( DATA(11 DOWNTO 4) );
-- HEX TO BCD
VHIGH := FIGURE / 10;
VLOW := FIGURE REM 10;
EOC <= EOCtemp;
END PROCESS;
-------------------------------------------------
-------------------------------------------------
END Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -