原创 FPGA控制DS18B20代码,绝对原创,欢迎拍砖

2008-5-16 00:05 2769 9 10 分类: FPGA/CPLD

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,也能正常工作,请高手不吝赐教!


http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1079713&bbs_page_no=1&bbs_id=9999

文章评论1条评论)

登录后参与讨论

用户377235 2013-1-21 23:45

temp_h<='0'&TMP(11 downto 5); temp_l<="0000"&TMP(4 downto 1); 这是什么意思,DS18B20不是低13位有效吗?而高5位是符号位吗

jizzll_617398179 2008-5-31 18:08

什么,不懂

用户506238 2008-5-31 17:23

不好意思,是我电脑的问题,抱歉。
相关推荐阅读
jizzll_617398179 2010-02-08 10:53
正确理解A/D转换器的输入
http://www.freescale.com.cn/tech_ariticles/2005/1102_1.asp 许多嵌入式应用都会用到A/D转换器。然而,如果错误连接了A/D转换器输入端的电路,...
jizzll_617398179 2010-01-12 13:37
好久没来,都长草了
好久没来,都长草了,呵呵。整天忙得很,不过估计再过两个月会轻松点~\(≧▽≦)/~啦啦啦...
jizzll_617398179 2009-03-16 21:57
很奇怪,我收到站内信,但是却找不到发信人呢
发信人是个[],点击就跳到我自己的主页了。只好在这里给那位朋友留言了。 我不知道你说的哪篇文章,还有我也不知道你的EDN的ID。你可以在博客上面留言的。...
jizzll_617398179 2009-03-14 13:08
如何在EXCEL中使用16进制数
最近需要计算串口发送的数据,太多而且比较麻烦。知道EXECL功能强大,所以网上找了找,刚好,不错,很方便。网上找到的http://hi.bccn.net/space-99452-do-blog-id-...
jizzll_617398179 2009-03-05 14:37
〖常识〗不同晶振的最大波特率及其误差
最近犯了个错误,呵呵,晶振和波特率的问题,特查了记在这里,O(∩_∩)O~〖常识〗不同晶振的最大波特率及其误差http://www.aoxue.org/bbs/read.php?tid=65585不同...
jizzll_617398179 2009-02-11 14:30
大端模式和小端模式
转载http://www.cnblogs.com/TsuiLei/archive/2008/10/29/1322504.html大端格式:在这种格式中,字数据的高字节存储在低地址中,而字数据的低字节则...
我要评论
1
9
关闭 站长推荐上一条 /2 下一条