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;

 

One Comments

  • nlinberg

    19.01.2017

    На aliexpress и ebay продается много поддельных датчиков. По факту это перемаркированные транзисторы. При подаче питания, согласно схеме подключения DS18B20, «датчик» начинает сильно греться. Если Вы столкнулись с данной ситуацией, отключите питание, датчик отложите в сторону, и напишите у кого и где вы купили данный датчик. Возможно вы кого-то спасете от покупки транзисторов с маркировокой Dallas DS18B20.

    Reply

Добавить комментарий