VHDL и DS18B20
В статье представлен рабочий код на VHDL для работы FPGA с датчиком температуры Dallas DS18B20.
Очень рекомендую обеспечить качественное питание. Была проблема — начальное 85 считывалось без проблем, но после запуска конвертации 44h датчик возвращал стабильно FF. Оказалось проблема была в питании.
Код рабочий.
На вход необходимо подавать 1МГц.
English: Code is working and testing. Use original DS18B20 and good power for temperature sensor. Input clk: 1 MHz.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity temperature_2 is port ( clk1m: in std_logic; temper: out std_logic_vector(15 downto 0); wireout: inout std_logic ); end temperature_2; architecture Behavioral of temperature_2 is type state_type is (reset,s5,s6,s7,s8,w0,w3,w1,w2,read0,read1,read2,read3); signal state: state_type; signal temp: std_logic_vector( 15 downto 0); signal S_reset: std_logic; signal i: integer range 0 to 2000000; begin temper<= temp; process(clk1m) variable j : integer range 0 to 15; variable flag : integer range 0 to 70; begin if rising_edge(clk1m) then case state is when reset => S_reset <= '0'; --включаем счетчик if (i=0) then wireout<='0'; --опускаем шину на 485 мкс elsif (i=485) then wireout<='Z'; --отпускаем шину elsif (i=1000) then state <= s5; S_reset <= '1'; -- переходим к ROM командам end if; when s5 => --CCh if (flag = 0 ) then flag:=1;state <=w0; elsif (flag = 1 ) then flag:=2;state <=w0; elsif (flag = 2 ) then flag:=3;state <=w2;wireout<='0'; elsif (flag = 3 ) then flag:=4;state <=w2;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 <=w2;wireout<='0'; elsif (flag = 7 ) then flag:=8;state <=w2;wireout<='0'; --elsif (flag = 65 ) then flag:=28;state <=s8;wireout<='Z'; -- пауза без ресета --44h elsif (flag = 8 ) then flag:=9 ;state <=w0; elsif (flag = 9 ) then flag:=10;state <=w0; elsif (flag = 10 ) then flag:=11;state <=w2;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 <=w2;wireout<='0'; elsif (flag = 15 ) then flag:=16;state <=w0; elsif (flag = 16 ) then flag:=20;state <=s6;wireout<='Z'; --пауза и ресет --elsif (flag = 16 ) then flag:=0;state <=s6;wireout<='Z'; --пауза и ресет --CCh elsif (flag = 20 ) then flag:=21;state <=w0; elsif (flag = 21 ) then flag:=22;state <=w0; elsif (flag = 22 ) then flag:=23;state <=w2;wireout<='0'; elsif (flag = 23 ) then flag:=24;state <=w2;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 <=w2;wireout<='0'; elsif (flag = 27 ) then flag:=28;state <=w2;wireout<='0'; --elsif (flag = 66 ) then flag:=8;state <=s8;wireout<='Z'; -- пауза без ресета --BEh elsif (flag = 28 ) then flag:=29;state <=w0; elsif (flag = 29 ) then flag:=30;state <=w2;wireout<='0'; elsif (flag = 30 ) then flag:=31;state <=w2;wireout<='0'; elsif (flag = 31 ) then flag:=32;state <=w2;wireout<='0'; elsif (flag = 32 ) then flag:=33;state <=w2;wireout<='0'; elsif (flag = 33 ) then flag:=34;state <=w2;wireout<='0'; elsif (flag = 34 ) then flag:=35;state <=w0; elsif (flag = 35 ) then flag:=36;state <=w2;wireout<='0'; elsif (flag = 36 ) then flag:=40;state <=s7; end if; when s6 => S_reset<='0'; if (i = 750000) then state <= reset; S_reset<='1'; end if; when s7 => if (flag = 40 ) then flag:=41; state<=read0;j:=0; wireout<='0'; elsif (flag = 41 ) then flag:=42; state<=read0;j:=1; wireout<='0'; elsif (flag = 42 ) then flag:=43; state<=read0;j:=2; wireout<='0'; elsif (flag = 43 ) then flag:=44; state<=read0;j:=3; wireout<='0'; elsif (flag = 44 ) then flag:=45; state<=read0;j:=4; wireout<='0'; elsif (flag = 45 ) then flag:=46; state<=read0;j:=5; wireout<='0'; elsif (flag = 46 ) then flag:=47; state<=read0;j:=6; wireout<='0'; elsif (flag = 47 ) then flag:=48; state<=read0;j:=7; wireout<='0'; elsif (flag = 48 ) then flag:=49; state<=read0;j:=8; wireout<='0'; elsif (flag = 49 ) then flag:=50; state<=read0;j:=9; wireout<='0'; elsif (flag = 50 ) then flag:=51; state<=read0;j:=10;wireout<='0'; elsif (flag = 51 ) then flag:=52; state<=read0;j:=11;wireout<='0'; elsif (flag = 52 ) then flag:=53; state<=read0;j:=12;wireout<='0'; elsif (flag = 53 ) then flag:=54; state<=read0;j:=13;wireout<='0'; elsif (flag = 54 ) then flag:=55; state<=read0;j:=14;wireout<='0'; elsif (flag = 55 ) then flag:=60; state<=read0;j:=15;wireout<='0'; elsif (flag = 60 ) then flag:=0;state<=reset; end if; when s8 => S_reset<='0'; if (i = 800000) then state <= s5; S_reset<='1'; end if; ---------------------------------------------------------------- when w0 => --запись 0 в датчик wireout<='0'; S_reset<='0'; if (i = 80) then wireout<='Z'; S_reset<='1'; state<=w1; end if; when w1 => state<=s5; when w2=> --запись 1 в датчик state<=w3; when w3 => wireout<='Z'; S_reset<='0'; if (i = 80) then S_reset<='1'; state<=s5; end if; ---------------------------------------------------------------------------- when read0=> state <= read1; when read1=> wireout <= 'Z'; S_reset<='0'; if (i = 10) then S_reset<='1'; state <= read2; end if; when read2=> temp(j)<= wireout; state <= read3; when read3=> S_reset<='0'; if (i = 55) then S_reset<='1'; state <= s7; end if; ------------------------------------------------------------------------------ when others => state <= reset; end case; end if; end process; process(clk1m,S_reset) begin if (S_reset = '1')then i<=0; elsif rising_edge(clk1m) then i<=i+1; end if; end process; end Behavioral;
nlinberg
19.01.2017На aliexpress и ebay продается много поддельных датчиков. По факту это перемаркированные транзисторы. При подаче питания, согласно схеме подключения DS18B20, «датчик» начинает сильно греться. Если Вы столкнулись с данной ситуацией, отключите питание, датчик отложите в сторону, и напишите у кого и где вы купили данный датчик. Возможно вы кого-то спасете от покупки транзисторов с маркировокой Dallas DS18B20.