------------------------------------------------- --------------------------
-- DS18B20.vhd - DS18B20 temperature sensor communication module
-------------------------------------------------- --------------------------
-- Author: Pavel Gregar
-- Created: 15:11:15 11/29/2013
-- Module: DS18B20 - Behavioral
-- Project: Weather station
-- Target device: Nexys4
-- Use tools: Xilinx 14.6
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-- This module is used to communicate with the DS18B20 temperature sensor. Use the command sequence
-- 44h (CONVERT TEMPERATURE),
-- CCH (SKIP ROM),
-- BEh (READ SCRATCHPAD) is loaded The contents of the scrathpad sensor memory that is sent to the CRC port for dataOut.
-- Module ports:
-- clk1m 1 MHz clock.
-- crc_en Control of starting CRC calculations from data received from the sensor sent to the dataOut port.
-- ds_data_bus 1-wire I / O, sensor input / output data port.
-- dataOut Output a data signal containing the contents of the scratchpad memory
----------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DS18B20 is
port
(
clk1m : IN STD_LOGIC;
crc_en : OUT STD_LOGIC;
dataOut : OUT STD_LOGIC_VECTOR(71 downto 0);
ds_data_bus : INOUT STD_LOGIC
);
end DS18B20;
architecture Behavioral of DS18B20 is
--FSM states needed
TYPE STATE_TYPE is (WAIT_800ms, RESET, PRESENCE, SEND, WRITE_BYTE, WRITE_LOW, WRITE_HIGH, GET_DATA, READ_BIT);
SIGNAL state: STATE_TYPE; -- present state of FSM
SIGNAL data : STD_LOGIC_VECTOR(71 downto 0); -- read data from scratchpad sensor memory
SIGNAL S_reset : STD_LOGIC; -- synchronous reset
SIGNAL i:INTEGER RANGE 0 TO 799999; -- citac
SIGNAL write_command : STD_LOGIC_VECTOR(7 downto 0); -- sensor instruction sent
SIGNAL presence_signal : STD_LOGIC; -- signal for sensor detection on the bus
SIGNAL WRITE_BYTE_CNT : INTEGER RANGE 0 TO 8 := 0; -- for sending bytes
SIGNAL write_low_flag : INTEGER RANGE 0 TO 2 := 0; -- position flag in WRITE_LOW state
SIGNAL write_high_flag : INTEGER RANGE 0 TO 2 := 0; -- position flag in WRITE_HIGH state
SIGNAL read_bit_flag : INTEGER RANGE 0 TO 3 := 0; -- position flag in READ_BIT state
SIGNAL GET_DATA_CNT : INTEGER RANGE 0 TO 72 := 0; -- citation for the number of read bits
begin
-- Process for communication with DS18B20 sensor
process(clk1m)
--- output data in case of sensor detection error on bus
CONSTANT PRESENCE_ERROR_DATA : STD_LOGIC_VECTOR(71 downto 0):= "101010101010101010101010101010101010101010101010101010101010101010101010";
VARIABLE bit_cnt : INTEGER RANGE 0 TO 71; --- just read bit
VARIABLE flag : INTEGER RANGE 0 TO 5; --flag for sent command
begin
if rising_edge(clk1m) then
case state is
when RESET => -- sensor reset status
S_reset <= '0'; -- reset instruction
if (i = 0) then
ds_data_bus <= '0'; -- start of reset pulse
elsif (i = 485) then
ds_data_bus <= 'Z'; -- bus release
elsif (i = 550) then
presence_signal <= ds_data_bus; -- taking a sample to detect the presence of the sensor
elsif (i = 1000) then
state <= PRESENCE; -- transition to PRESENCE
end if;
when PRESENCE => -- state for detecting the presence of a sensor on the busi
-- Bus sensor detection
if (presence_signal = '0' and ds_data_bus = '1') then -- the sensor has been detected
S_reset <= '1'; -- reset instruction
state <= SEND; -- initialization complete, transition to SEND state
else
-- sensor not detected
S_reset <= '1'; -- reset instruction
dataOut <= PRESENCE_ERROR_DATA; -- setting data indicating error to output
crc_en <= '1'; -- start of CRC calculation
state <= WAIT_800ms; -- transition to WAIT_800ms
end if;
when SEND => -- status for sending command for sensor
-- sequence of commands sent by flag flag
if (flag = 0) then -- first command
flag := 1;
write_command <="11001100"; -- command CCh - SKIP ROM
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 1) then -- second order
flag := 2;
write_command <="01000100"; -- order 44h - CONVERT TEMPERATURE
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 2) then -- the third command
flag := 3;
state <= WAIT_800ms; -- transition to WAIT_800ms, waiting for command to end 44h
elsif (flag = 3) then -- the fourth command
flag := 4;
write_command <="11001100"; -- command CCh - SKIP ROM
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 4) then -- fourth command
flag := 5;
write_command <="10111110"; -- command BEh - READ SCRATCHPAD
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 5) then -- stop sending command
flag := 0; -- reset flag for outgoing command
state <= GET_DATA; -- transition to GET_DATA
end if;
when WAIT_800ms => -- waiting state for 800 ms
CRC_en <= '0'; -- reset flag to start CRC calculation
S_reset <= '0'; -- running instruction
if (i = 799999) then -- end of quote period
S_reset <='1'; -- reset instruction
state <= RESET; -- return to the RESET state
end if;
when GET_DATA => -- scratchpad memory read status
case GET_DATA_CNT is -- position in GET_DATA state
when 0 to 71=> -- read individual bits of scratchpad memory
ds_data_bus <= '0'; -- start reading on the bus
GET_DATA_CNT <= GET_DATA_CNT + 1; -- increment quotes for just read bit
state <= READ_BIT; -- transition to READ_BIT
when 72=> -- read memory (72 bits)
bit_cnt := 0; -- reset quote for just read bit
GET_DATA_CNT <=0; -- reset instruction of read bits
dataOut <= data(71 downto 0); -- send the read data to the output port
CRC_en <= '1'; -- start calculating CRC of read data
state <= WAIT_800ms; -- return to WAIT_800ms
when others => -- error in GET_DATA state
read_bit_flag <= 0; -- reset position in READ_BIT state
GET_DATA_CNT <= 0; -- reset citation for the number of read bits
end case;
when READ_BIT => -- state for reading the bit
-- bit read sequence controlled by the read_bit_flag
case read_bit_flag is --position in READ_BIT
when 0=> -- sending start time slot for reading
read_bit_flag <= 1;
when 1=>
ds_data_bus <= 'Z'; -- releasing the bus to receive a bit from the sensor
S_reset <= '0'; -- turn on instruction
if (i = 13) then --waiting 14 us
S_reset <= '1'; -- reset instruction
read_bit_flag <= 2;
end if;
when 2=> -- sampling of data from the bus
data(bit_cnt) <= ds_data_bus; -- saving a sample of data into the registr
bit_cnt := bit_cnt + 1; -- increase citation for just read bit
read_bit_flag <= 3;
when 3=> -- complete the time slot
S_reset <= '0'; -- turn on quotes
if (i = 63) then -- waiting 62 us
S_reset<='1'; -- reset quote
read_bit_flag <= 0; -- reset position in READ_BIT state
state <= GET_DATA; -- return to GET_DATA
end if;
when others => -- error in READ_BIT state
read_bit_flag <= 0; -- reset position in READ_BIT state
bit_cnt := 0; -- reset quote for just read bit
GET_DATA_CNT <= 0; -- reset citation of read bits
state <= RESET; -- Sensor reset
end case;
when WRITE_BYTE => -- state for writing a data byte on the bus
-- byte sequence of data byte controlled by WRITE_BYTE CNT
case WRITE_BYTE_CNT is -- position in WRITE_BYTE
when 0 to 7=> -- sending bit 0-7
if (write_command(WRITE_BYTE_CNT) = '0') then -- the bit sent is log. 0
state <= WRITE_LOW; -- transition to WRITE_LOW
else -- the bit sent is log. 1
state <= WRITE_HIGH; -- prechod do stavu WRITE_HIGH
end if;
WRITE_BYTE_CNT <= WRITE_BYTE_CNT + 1; -- inkrementace citace odesilaneho bitu
when 8=> -- odesilani bajtu dokonceno
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
state <= SEND; -- navrat do stavu SEND
when others=> -- chyba ve stavu WRITE_BYTE
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
write_low_flag <= 0; -- reset pozice ve stavu WRITE_LOW
write_high_flag <= 0; -- reset pozice ve stavu WRITE_HIGH
state <= RESET; -- reset senzoru
end case;
when WRITE_LOW => -- stav pro zapis log. 0 na sbernici
-- casovy slot pro zapis log 0 rizeny priznakem write_low_flag
case write_low_flag is -- pozice ve stavu WRITE_LOW
when 0=> -- vyslani zacatku casoveho slotu pro zapis log. 0
ds_data_bus <= '0'; -- zacatek casoveho slotu
S_reset <= '0'; -- zapnuti citace
if (i = 59) then -- cekani 60 us
S_reset <='1'; -- reset citace
write_low_flag <= 1;
end if;
when 1=> -- uvolneni sbernice pro ukonceni casoveho slotu
ds_data_bus <= 'Z'; -- uvolneni sbernice
S_reset <= '0'; -- zapnuti citace
if (i = 3) then -- cekani 4 us na ustaleni sbernice
S_reset <= '1'; -- reset citace
write_low_flag <= 2;
end if;
when 2=> -- konec zapisu log. 0
write_low_flag <= 0; -- reset pozice ve stavu WRITE_LOW
state <= WRITE_BYTE; -- navrat do stavu WRITE_BYTE
when others=> -- chyba zapisu log. 0
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
write_low_flag <= 0; -- reset pozice ve stavu WRITE_LOW
state <= RESET; -- reset senzoru
end case;
when WRITE_HIGH => -- stav pro zapis log. 1 na sbernici
-- casovy slot pro zapis log 1 rizeny priznakem write_high_flag
case write_high_flag is -- pozice ve stavu WRITE_HIGH
when 0=> -- vyslani zacatku casoveho slotu pro zapis log. 1
ds_data_bus <= '0'; -- zacatek casoveho slotu
S_reset <= '0'; -- zapnuti citace
if (i = 9) then -- cekani 10 us
S_reset <= '1'; -- reset citace
write_high_flag <= 1;
end if;
when 1=> -- uvolneni sbernice pro ukonceni casoveho slotu
ds_data_bus <= 'Z'; -- uvolneni sbernice
S_reset <= '0'; -- zapnuti citace
if (i = 53) then -- cekani 54 us
S_reset <= '1'; -- reset citace
write_high_flag <= 2;
end if;
when 2=> -- konec zapisu log. 1
write_high_flag <= 0; -- reset pozice ve stavu WRITE_HIGH
state <= WRITE_BYTE; -- navrat do stavu WRITE BYTE
when others => -- chyba zapisu log. 1
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
write_high_flag <= 0; -- reset pozice ve stavu WRITE_HIGH
state <= RESET; -- reset senzoru
end case;
when others => -- chyba FSM
state <= RESET; -- reset senzoru
end case;
end if;
end process;
-- Proces citace se synchronnim resetem
process(clk1m, S_reset)
begin
if (rising_edge(clk1m)) then
if (S_reset = '1')then -- reset citace
i <= 0; -- vynulovani citace
else
i <= i + 1; -- inkrementace citace
end if;
end if;
end process;
Question
Hos Sam97
------------------------------------------------- --------------------------
-- DS18B20.vhd - DS18B20 temperature sensor communication module
-------------------------------------------------- --------------------------
-- Author: Pavel Gregar
-- Created: 15:11:15 11/29/2013
-- Module: DS18B20 - Behavioral
-- Project: Weather station
-- Target device: Nexys4
-- Use tools: Xilinx 14.6
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-- This module is used to communicate with the DS18B20 temperature sensor. Use the command sequence
-- 44h (CONVERT TEMPERATURE),
-- CCH (SKIP ROM),
-- BEh (READ SCRATCHPAD) is loaded The contents of the scrathpad sensor memory that is sent to the CRC port for dataOut.
-- Module ports:
-- clk1m 1 MHz clock.
-- crc_en Control of starting CRC calculations from data received from the sensor sent to the dataOut port.
-- ds_data_bus 1-wire I / O, sensor input / output data port.
-- dataOut Output a data signal containing the contents of the scratchpad memory
----------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DS18B20 is
port
(
clk1m : IN STD_LOGIC;
crc_en : OUT STD_LOGIC;
dataOut : OUT STD_LOGIC_VECTOR(71 downto 0);
ds_data_bus : INOUT STD_LOGIC
);
end DS18B20;
architecture Behavioral of DS18B20 is
--FSM states needed
TYPE STATE_TYPE is (WAIT_800ms, RESET, PRESENCE, SEND, WRITE_BYTE, WRITE_LOW, WRITE_HIGH, GET_DATA, READ_BIT);
SIGNAL state: STATE_TYPE; -- present state of FSM
SIGNAL data : STD_LOGIC_VECTOR(71 downto 0); -- read data from scratchpad sensor memory
SIGNAL S_reset : STD_LOGIC; -- synchronous reset
SIGNAL i:INTEGER RANGE 0 TO 799999; -- citac
SIGNAL write_command : STD_LOGIC_VECTOR(7 downto 0); -- sensor instruction sent
SIGNAL presence_signal : STD_LOGIC; -- signal for sensor detection on the bus
SIGNAL WRITE_BYTE_CNT : INTEGER RANGE 0 TO 8 := 0; -- for sending bytes
SIGNAL write_low_flag : INTEGER RANGE 0 TO 2 := 0; -- position flag in WRITE_LOW state
SIGNAL write_high_flag : INTEGER RANGE 0 TO 2 := 0; -- position flag in WRITE_HIGH state
SIGNAL read_bit_flag : INTEGER RANGE 0 TO 3 := 0; -- position flag in READ_BIT state
SIGNAL GET_DATA_CNT : INTEGER RANGE 0 TO 72 := 0; -- citation for the number of read bits
begin
-- Process for communication with DS18B20 sensor
process(clk1m)
--- output data in case of sensor detection error on bus
CONSTANT PRESENCE_ERROR_DATA : STD_LOGIC_VECTOR(71 downto 0):= "101010101010101010101010101010101010101010101010101010101010101010101010";
VARIABLE bit_cnt : INTEGER RANGE 0 TO 71; --- just read bit
VARIABLE flag : INTEGER RANGE 0 TO 5; --flag for sent command
begin
if rising_edge(clk1m) then
case state is
when RESET => -- sensor reset status
S_reset <= '0'; -- reset instruction
if (i = 0) then
ds_data_bus <= '0'; -- start of reset pulse
elsif (i = 485) then
ds_data_bus <= 'Z'; -- bus release
elsif (i = 550) then
presence_signal <= ds_data_bus; -- taking a sample to detect the presence of the sensor
elsif (i = 1000) then
state <= PRESENCE; -- transition to PRESENCE
end if;
when PRESENCE => -- state for detecting the presence of a sensor on the busi
-- Bus sensor detection
if (presence_signal = '0' and ds_data_bus = '1') then -- the sensor has been detected
S_reset <= '1'; -- reset instruction
state <= SEND; -- initialization complete, transition to SEND state
else
-- sensor not detected
S_reset <= '1'; -- reset instruction
dataOut <= PRESENCE_ERROR_DATA; -- setting data indicating error to output
crc_en <= '1'; -- start of CRC calculation
state <= WAIT_800ms; -- transition to WAIT_800ms
end if;
when SEND => -- status for sending command for sensor
-- sequence of commands sent by flag flag
if (flag = 0) then -- first command
flag := 1;
write_command <="11001100"; -- command CCh - SKIP ROM
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 1) then -- second order
flag := 2;
write_command <="01000100"; -- order 44h - CONVERT TEMPERATURE
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 2) then -- the third command
flag := 3;
state <= WAIT_800ms; -- transition to WAIT_800ms, waiting for command to end 44h
elsif (flag = 3) then -- the fourth command
flag := 4;
write_command <="11001100"; -- command CCh - SKIP ROM
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 4) then -- fourth command
flag := 5;
write_command <="10111110"; -- command BEh - READ SCRATCHPAD
state <= WRITE_BYTE; -- transition to WRITE BYTE
elsif (flag = 5) then -- stop sending command
flag := 0; -- reset flag for outgoing command
state <= GET_DATA; -- transition to GET_DATA
end if;
when WAIT_800ms => -- waiting state for 800 ms
CRC_en <= '0'; -- reset flag to start CRC calculation
S_reset <= '0'; -- running instruction
if (i = 799999) then -- end of quote period
S_reset <='1'; -- reset instruction
state <= RESET; -- return to the RESET state
end if;
when GET_DATA => -- scratchpad memory read status
case GET_DATA_CNT is -- position in GET_DATA state
when 0 to 71=> -- read individual bits of scratchpad memory
ds_data_bus <= '0'; -- start reading on the bus
GET_DATA_CNT <= GET_DATA_CNT + 1; -- increment quotes for just read bit
state <= READ_BIT; -- transition to READ_BIT
when 72=> -- read memory (72 bits)
bit_cnt := 0; -- reset quote for just read bit
GET_DATA_CNT <=0; -- reset instruction of read bits
dataOut <= data(71 downto 0); -- send the read data to the output port
CRC_en <= '1'; -- start calculating CRC of read data
state <= WAIT_800ms; -- return to WAIT_800ms
when others => -- error in GET_DATA state
read_bit_flag <= 0; -- reset position in READ_BIT state
GET_DATA_CNT <= 0; -- reset citation for the number of read bits
end case;
when READ_BIT => -- state for reading the bit
-- bit read sequence controlled by the read_bit_flag
case read_bit_flag is --position in READ_BIT
when 0=> -- sending start time slot for reading
read_bit_flag <= 1;
when 1=>
ds_data_bus <= 'Z'; -- releasing the bus to receive a bit from the sensor
S_reset <= '0'; -- turn on instruction
if (i = 13) then --waiting 14 us
S_reset <= '1'; -- reset instruction
read_bit_flag <= 2;
end if;
when 2=> -- sampling of data from the bus
data(bit_cnt) <= ds_data_bus; -- saving a sample of data into the registr
bit_cnt := bit_cnt + 1; -- increase citation for just read bit
read_bit_flag <= 3;
when 3=> -- complete the time slot
S_reset <= '0'; -- turn on quotes
if (i = 63) then -- waiting 62 us
S_reset<='1'; -- reset quote
read_bit_flag <= 0; -- reset position in READ_BIT state
state <= GET_DATA; -- return to GET_DATA
end if;
when others => -- error in READ_BIT state
read_bit_flag <= 0; -- reset position in READ_BIT state
bit_cnt := 0; -- reset quote for just read bit
GET_DATA_CNT <= 0; -- reset citation of read bits
state <= RESET; -- Sensor reset
end case;
when WRITE_BYTE => -- state for writing a data byte on the bus
-- byte sequence of data byte controlled by WRITE_BYTE CNT
case WRITE_BYTE_CNT is -- position in WRITE_BYTE
when 0 to 7=> -- sending bit 0-7
if (write_command(WRITE_BYTE_CNT) = '0') then -- the bit sent is log. 0
state <= WRITE_LOW; -- transition to WRITE_LOW
else -- the bit sent is log. 1
state <= WRITE_HIGH; -- prechod do stavu WRITE_HIGH
end if;
WRITE_BYTE_CNT <= WRITE_BYTE_CNT + 1; -- inkrementace citace odesilaneho bitu
when 8=> -- odesilani bajtu dokonceno
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
state <= SEND; -- navrat do stavu SEND
when others=> -- chyba ve stavu WRITE_BYTE
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
write_low_flag <= 0; -- reset pozice ve stavu WRITE_LOW
write_high_flag <= 0; -- reset pozice ve stavu WRITE_HIGH
state <= RESET; -- reset senzoru
end case;
when WRITE_LOW => -- stav pro zapis log. 0 na sbernici
-- casovy slot pro zapis log 0 rizeny priznakem write_low_flag
case write_low_flag is -- pozice ve stavu WRITE_LOW
when 0=> -- vyslani zacatku casoveho slotu pro zapis log. 0
ds_data_bus <= '0'; -- zacatek casoveho slotu
S_reset <= '0'; -- zapnuti citace
if (i = 59) then -- cekani 60 us
S_reset <='1'; -- reset citace
write_low_flag <= 1;
end if;
when 1=> -- uvolneni sbernice pro ukonceni casoveho slotu
ds_data_bus <= 'Z'; -- uvolneni sbernice
S_reset <= '0'; -- zapnuti citace
if (i = 3) then -- cekani 4 us na ustaleni sbernice
S_reset <= '1'; -- reset citace
write_low_flag <= 2;
end if;
when 2=> -- konec zapisu log. 0
write_low_flag <= 0; -- reset pozice ve stavu WRITE_LOW
state <= WRITE_BYTE; -- navrat do stavu WRITE_BYTE
when others=> -- chyba zapisu log. 0
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
write_low_flag <= 0; -- reset pozice ve stavu WRITE_LOW
state <= RESET; -- reset senzoru
end case;
when WRITE_HIGH => -- stav pro zapis log. 1 na sbernici
-- casovy slot pro zapis log 1 rizeny priznakem write_high_flag
case write_high_flag is -- pozice ve stavu WRITE_HIGH
when 0=> -- vyslani zacatku casoveho slotu pro zapis log. 1
ds_data_bus <= '0'; -- zacatek casoveho slotu
S_reset <= '0'; -- zapnuti citace
if (i = 9) then -- cekani 10 us
S_reset <= '1'; -- reset citace
write_high_flag <= 1;
end if;
when 1=> -- uvolneni sbernice pro ukonceni casoveho slotu
ds_data_bus <= 'Z'; -- uvolneni sbernice
S_reset <= '0'; -- zapnuti citace
if (i = 53) then -- cekani 54 us
S_reset <= '1'; -- reset citace
write_high_flag <= 2;
end if;
when 2=> -- konec zapisu log. 1
write_high_flag <= 0; -- reset pozice ve stavu WRITE_HIGH
state <= WRITE_BYTE; -- navrat do stavu WRITE BYTE
when others => -- chyba zapisu log. 1
WRITE_BYTE_CNT <= 0; -- reset citace odesilaneho bitu
write_high_flag <= 0; -- reset pozice ve stavu WRITE_HIGH
state <= RESET; -- reset senzoru
end case;
when others => -- chyba FSM
state <= RESET; -- reset senzoru
end case;
end if;
end process;
-- Proces citace se synchronnim resetem
process(clk1m, S_reset)
begin
if (rising_edge(clk1m)) then
if (S_reset = '1')then -- reset citace
i <= 0; -- vynulovani citace
else
i <= i + 1; -- inkrementace citace
end if;
end if;
end process;
end Behavioral;
Link to comment
Share on other sites
1 answer to this question
Recommended Posts
Archived
This topic is now archived and is closed to further replies.