查看: 1122|回复: 0
打印 上一主题 下一主题

FPGA控制DS18B20代码

[复制链接]
跳转到指定楼层
沙发
发表于 2016-5-28 22:19:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ds1820 is
        port(clk : in std_logic;                 
               dq  : inout std_logic;
            temp_h : out std_logic_vector(7 downto 0);
            temp_l : out std_logic_vector(7 downto 0));
end ds1820;

architecture Behavioral of ds1820 is

TYPE STATE_TYPE is (RESET,CMD_CC,WRITE_BYTE,WRITE_LOW,WRITE_HIGH,READ_BIT,CMD_44,WAIT800MS,CMD_BE,GET_TMP,WAIT4MS);
signal STATE: STATE_TYPE:=RESET;

signal clk_temp : std_logic:='0';
signal clk1m : std_logic;

signal write_temp : std_logic_vector(7 downto 0):="00000000";

signal TMP : std_logic_vector(11 downto 0);
signal tmp_bit : std_logic;

signal WRITE_BYTE_CNT : integer range 0 to 8:=0;
signal WRITE_LOW_CNT : integer range 0 to 2:=0;
signal WRITE_HIGH_CNT : integer range 0 to 2:=0;
signal READ_BIT_CNT : integer range 0 to 3:=0;
signal GET_TMP_CNT : integer range 0 to 12:=0;

signal cnt : integer range 0 to 100001:=0;
signal count : integer range 0 to 25:=0;

signal WRITE_BYTE_FLAG : integer range 0 to 4:=0;

begin

ClkDivider:process (clk)
begin
if rising_edge(clk) then
   if (count = 24) then
      count <= 0;
      clk_temp<= not clk_temp;
   else
      count <= count +1;
   end if;
end if;
   clk1m<=clk_temp;
end Process;


STATE_TRANSITION:process(STATE,clk1m)
begin        
   if rising_edge(clk1m) then
      case STATE is
         when RESET=>                        
            if (cnt>=0 and cnt<500) then        
               dq<='0';        
            cnt<=cnt+1;
            STATE<=RESET;
           elsif (cnt>=500 and cnt<1000) then
            dq<='Z';
            cnt<=cnt+1;
            STATE<=RESET;
        elsif (cnt>=1000) then
            cnt<=0;                                
            STATE<=CMD_CC;        
        end if;
        when CMD_CC=>                        
        write_temp<="11001100";                        
        STATE<=WRITE_BYTE;
        when WRITE_BYTE=>
        case WRITE_BYTE_CNT is
        when 0 to 7=>
           if (write_temp(WRITE_BYTE_CNT)='0') then
              STATE<=WRITE_LOW;
           else
              STATE<=WRITE_HIGH;
           end if;
              WRITE_BYTE_CNT<=WRITE_BYTE_CNT+1;                                
        when 8=>
           if (WRITE_BYTE_FLAG=0) then -- 第一次写0XCC完毕
              STATE<=CMD_44;
              WRITE_BYTE_FLAG<=1;
           elsif (WRITE_BYTE_FLAG=1) then --写0X44完毕
              STATE<=RESET;
              WRITE_BYTE_FLAG<=2;
           elsif (WRITE_BYTE_FLAG=2) then --第二次写0XCC完毕
              STATE<=CMD_BE;
              WRITE_BYTE_FLAG<=3;
           elsif (WRITE_BYTE_FLAG=3) then --写0XBE完毕
              STATE<=GET_TMP;
              WRITE_BYTE_FLAG<=0;
           end if;
           WRITE_BYTE_CNT<=0;                                       
        end case;
        when WRITE_LOW=>
        case WRITE_LOW_CNT is
           when 0=>
              dq<='0';
              if (cnt=78) then                                                
                 cnt<=0;
                 WRITE_LOW_CNT<=1;
              else
                 cnt<=cnt+1;                                                
              end if;
           when 1=>
              dq<='Z';
              if (cnt=2) then                                                
                 cnt<=0;
                 WRITE_LOW_CNT<=2;
              else
                 cnt<=cnt+1;                                                
              end if;
           when 2=>
              STATE<=WRITE_BYTE;
              WRITE_LOW_CNT<=0;                                       
           when others=>WRITE_LOW_CNT<=0;
        end case;
        when WRITE_HIGH=>
         case WRITE_HIGH_CNT is
            when 0=>
               dq<='0';                                       
               if (cnt=8) then                                                
                  cnt<=0;
                  WRITE_HIGH_CNT<=1;
               else
                  cnt<=cnt+1;                                                
               end if;
            when 1=>
               dq<='Z';
               if (cnt=72) then                                                
                  cnt<=0;
                  WRITE_HIGH_CNT<=2;
               else
                  cnt<=cnt+1;
               end if;
            when 2=>
               STATE<=WRITE_BYTE;
               WRITE_HIGH_CNT<=0;
            when others=>WRITE_HIGH_CNT<=0;
         end case;
         when READ_BIT=>                        
         case READ_BIT_CNT is
            when 0=>
               dq<='0';
               if (cnt=4) then
                READ_BIT_CNT<=1;
                cnt<=0;
               else
                  cnt<=cnt+1;                                                
               end if;
            when 1=>
               dq<='Z';
               if (cnt=4) then
                  READ_BIT_CNT<=2;
                  cnt<=0;
               else
                  cnt<=cnt+1;
               end if;
            when 2=>
               TMP_BIT<=dq;
               if (cnt=1) then
                  READ_BIT_CNT<=3;
                  cnt<=0;                                                
               else
                  cnt<=cnt+1;                                                
               end if;
            when 3=>
               if (cnt=45) then                                                
                  cnt<=0;
                  READ_BIT_CNT<=0;
                  STATE<=GET_TMP;
               else
                  cnt<=cnt+1;                                                
               end if;
            when others=>READ_BIT_CNT<=0;
         end case;
         when CMD_44=>                        
         write_temp<="01000100";
         STATE<=WRITE_BYTE;
         when WAIT800MS=>
         if (cnt>=100000) then
            STATE<=RESET;
            cnt<=0;
         else
            cnt<=cnt+1;
            STATE<=WAIT800MS;
         end if;               
         when CMD_BE=>                        
         write_temp<="10111110";
         STATE<=WRITE_BYTE;
         when GET_TMP=>
         case GET_TMP_CNT is
            when 0 to 11=>
               STATE<=READ_BIT;
               TMP(GET_TMP_CNT)<=TMP_BIT;
               GET_TMP_CNT<=GET_TMP_CNT+1;
            when 12=>
               GET_TMP_CNT<=0;
               STATE<=WAIT4MS;                                       
         end case;
         when WAIT4MS=>
         if (cnt>=4000) then
            STATE<=RESET;
            cnt<=0;
         else
            cnt<=cnt+1;
            STATE<=WAIT4MS;
         end if;                                
         when others=>STATE<=RESET;
      end case;        
   end if;
end process;
                        
temp_h<='0'&TMP(11 downto 5);
temp_l<="0000"&TMP(4 downto 1);

end Behavioral;


今天刚编好的,在XILINX SPARTAN3 STARTER KIT 上测试能正常显示温度
代码中还存在一些不当之处,欢迎大家指教
还有一点不解的是,代码中的WAIT800MS这个状态不要,也就是不用等待800ms,也能正常工作,请高手不吝赐教!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表