搜索
bottom↓
回复: 126

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

[复制链接]

出0入0汤圆

发表于 2008-5-14 22:57:40 | 显示全部楼层 |阅读模式
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,也能正常工作,请高手不吝赐教!

出0入0汤圆

 楼主| 发表于 2008-5-14 22:58:49 | 显示全部楼层
系统输入时钟为50MHz,经分频后得到clk1m为1MHz

出0入0汤圆

 楼主| 发表于 2008-5-15 22:55:08 | 显示全部楼层
没有人感兴趣么,交流一下嘛

出0入0汤圆

发表于 2008-5-16 00:00:24 | 显示全部楼层
用了多少单元?有自动多片查找么?最近想在MAXII上实现

出0入0汤圆

发表于 2008-5-16 00:09:50 | 显示全部楼层
是Verilog HDL就好了,不太喜欢VHDL
不过还是顶一下,支持原创

出0入0汤圆

发表于 2008-5-16 08:36:22 | 显示全部楼层
这个不需要电路图,因为fpga cpld端口都是自己配置的

出0入0汤圆

发表于 2008-5-16 08:41:37 | 显示全部楼层
FPGA貌似无需电路图的样子

不过,用FPGA带18B20的话,FPGA端口帶载能力还是有点困难的

另外,不得不说,任何时候,用FPGA玩通信协议,都是纯粹的自己给自己找麻烦……

出0入0汤圆

发表于 2008-5-16 08:43:35 | 显示全部楼层
【3楼】 s99060
        用了多少单元?有自动多片查找么?最近想在MAXII上实现

=====================

看代码的话,多片查找显然是没有的

而且,要连多片查找都做出来的话,估计一般的5K Cell的FPGA也就别干别的了……

出0入137汤圆

发表于 2008-5-16 08:50:16 | 显示全部楼层
留个记号,不错.

出0入137汤圆

发表于 2008-5-16 08:53:02 | 显示全部楼层
50分频后的波形怎么样?有毛刺吗?

出0入0汤圆

发表于 2008-5-16 08:54:49 | 显示全部楼层
我们刚开始学fpga是做过18b20,使用数百个状态机累出来了,那个真痛苦

Library IEEE;
Use IEEE.Std_Logic_1164.All;


Entity b is
Port
(
led : out std_logic_vector(0 to 16);

wireout : inout std_logic;
clk : in std_logic;
rst : in std_logic );

End entity b;

Architecture init of b is
type init_states is (s00,s0,s1,s2,s3,s4,s5,s6,s7,w0,w1,w00,w01,read0,read1,read2,read3);
signal state : init_states;
signal i : integer Range 0 to 1000000;
signal reset : std_logic;

begin

process (rst,wireout,clk)
--variable i : Integer Range 0 to 1000;
variable flag: Integer Range 0 to 200;
variable light: Integer Range 0 to 16;
begin
   if rst = '0' then
    state <= s00;
    wireout <= 'Z';
    flag:=0;
   elsif rising_edge(clk) then
    case state is
     when s00=>   flag:=0;
        led(0   )<='1';
        led(1   )<='1';
        led(2   )<='1';
        led(3   )<='1';
        led(4   )<='1';
        led(5   )<='0';
        led(6   )<='0';
        led(7   )<='0';
        led(8   )<='0';
        led(9   )<='0';
        led(10 )<='0';
        led(11 )<='0';
        led(12 )<='0';
        led(13 )<='0';
        led(14 )<='0';
        led(15 )<='0';
        led(16)<='0';
               --标志位置0
        state <=s0;      
     when s0 =>          --初始化18b20
        wireout <= '0';
           --主机拉底总线
        reset <='1';           
        state <=s1;      
      
     when s1 =>        
        reset <='0';      
        if (i = 500) then     --延时500us
         wireout <= 'Z';    --释放总线
         reset <='1';     
         state <=s2;        
        end if;      
      
     when s2 =>   reset <='0';      
        if (i = 100) then     --等待100us
         reset <='1';            
         state <=s3;           
        end if;
   
     when s3 => if (wireout = '0') then   --若18b20拉低总线,初始化成功
         state <=s4;
         led(16)<='1';    --led16灯亮
        elsif (wireout ='1') then --否则,初始化不成功,返回S0
         state <= s0;  
        end if;
   
     when s4 =>   reset<='0';
        if (i = 400) then     --再延时400us
         reset<='1';
         state <= s5;
        end if;
      
     when s5 =>         --写数据
        if     (flag = 0   ) then flag:=1;state <=w0;      --cch
        elsif (flag = 1   ) then flag:=2;state <=w0;
        elsif (flag = 2   ) then flag:=3;state <=w01;wireout<='0';   
        elsif (flag = 3   ) then flag:=4;state <=w01;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 <=w01;wireout<='0';
        elsif (flag = 7   ) then flag:=8;state <=w01;wireout<='0';
      
        elsif (flag = 8   ) then flag:=9 ;state <=w0;      --44h
        elsif (flag = 9   ) then flag:=10;state <=w0;
        elsif (flag = 10 ) then flag:=11;state <=w01;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 <=w01;wireout<='0';
        elsif (flag = 15 ) then flag:=16;state <=w0;
      
        --第一次写完,750ms后,跳回s0
        elsif (flag = 16 ) then flag:=20;state <=s6;wireout<='Z';
      
        --再次置数 cch和beh
        elsif (flag = 20   ) then flag:=21;state <=w0;      --cch
        elsif (flag = 21   ) then flag:=22;state <=w0;
        elsif (flag = 22   ) then flag:=23;state <=w01;wireout<='0';   
        elsif (flag = 23   ) then flag:=24;state <=w01;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 <=w01;wireout<='0';
        elsif (flag = 27   ) then flag:=28;state <=w01;wireout<='0';
      
        elsif (flag = 28   ) then flag:=29;state <=w0;      --beh 10111110
        elsif (flag = 29   ) then flag:=30;state <=w01;wireout<='0';
        elsif (flag = 30   ) then flag:=31;state <=w01;wireout<='0';   
        elsif (flag = 31   ) then flag:=32;state <=w01;wireout<='0';
        elsif (flag = 32   ) then flag:=33;state <=w01;wireout<='0';
        elsif (flag = 33   ) then flag:=34;state <=w01;wireout<='0';
        elsif (flag = 34   ) then flag:=35;state <=w0;
        elsif (flag = 35   ) then flag:=36;state <=w01;wireout<='0';
      
        --第二次写完,跳到s7,直接开始读数据
        elsif (flag = 36   ) then flag:=40;state <=s7;
        end if;
      
     when s6 =>  
        reset<='0';
        if (i = 750000 or wireout='1' ) then     --延时750ms!!!!
         state <= s0;
         reset<='1';    --跳回s0,再次初始化
        end if;
   
     when s7 =>          --读数据
        if     (flag = 40 ) then flag:=41;state <=read0;light:=0; wireout<='0';
        elsif (flag = 41 ) then flag:=42;state <=read0;light:=1; wireout<='0';
        elsif (flag = 42 ) then flag:=43;state <=read0;light:=2; wireout<='0';
        elsif (flag = 43 ) then flag:=44;state <=read0;light:=3; wireout<='0';
        elsif (flag = 44 ) then flag:=45;state <=read0;light:=4; wireout<='0';
        elsif (flag = 45 ) then flag:=46;state <=read0;light:=5; wireout<='0';
        elsif (flag = 46 ) then flag:=47;state <=read0;light:=6; wireout<='0';
        elsif (flag = 47 ) then flag:=48;state <=read0;light:=7; wireout<='0';
        elsif (flag = 48 ) then flag:=49;state <=read0;light:=8; wireout<='0';
        elsif (flag = 49 ) then flag:=50;state <=read0;light:=9; wireout<='0';
        elsif (flag = 50 ) then flag:=51;state <=read0;light:=10;wireout<='0';
        elsif (flag = 51 ) then flag:=52;state <=read0;light:=11;wireout<='0';

        elsif (flag = 52 ) then flag:=53;state <=read0;light:=12;wireout<='0';
        elsif (flag = 53 ) then flag:=54;state <=read0;light:=13;wireout<='0';
        elsif (flag = 54 ) then flag:=55;state <=read0;light:=14;wireout<='0';
        elsif (flag = 55 ) then flag:=60;state <=read0;light:=15;wireout<='0';
      
        elsif (flag = 60 ) then flag:=0;state<=s0;
        end if;
      
   
   
     ----------------------------------写状态机-----------------------------------
     -----------------------------------------------------------------------------
     when w0 =>   wireout<='0';     --输出0
        reset<='0';
        if (i = 80) then     --延时80us
         wireout<='Z';    --释放总线,自动拉高
         reset<='1';
         state<=w00;
        end if;
     when w00 => state<=s5;             --空状态
      
   
     when w01=>   state<=w1;             --空状态
     when w1 =>   wireout<='Z';     --输出1   释放总线,自动拉高
        reset<='0';
        if (i = 80) then     --延时80us
         reset<='1';
         state<=s5;
        end if;
   
   
     ----------------------------------读状态机------------------------------------
     ------------------------------------------------------------------------------
     when read0=> state <= read1;           --空延时状态
   
     when read1=>   wireout <= 'Z';    --释放总线
         reset<='0';
         if (i = 10) then    --再延时10us
          reset<='1';
          state <= read2;
         end if;
            
     when read2=> led(light)<=wireout;   --读到的数据给LED
         state <= read3;
   
     when read3=> reset<='0';
         if (i = 55) then    --再延时55us
          reset<='1';
          state <= s7;
         end if;
   
     ------------------------------------------------------------------------------
   
     when others =>         
        state <=s00;   
    end case;
   end if;
end process;


process(clk,reset)
begin
   if (reset='1')then
    i<=0;
   elsif rising_edge(clk) then i<=i+1;
   end if;
  
end process;  
end architecture init;

出0入0汤圆

发表于 2008-5-16 08:59:27 | 显示全部楼层
说句实在的,FPGA写通信协议,那代码不单写的人痛苦,我作为看的人一样痛苦……

实在很不理解,为什么放着三五块钱最多十来块钱一片集成了NNN多通信协议的单片机不用,非要用FPGA搞通信协议?钱多烧的?炫耀能力?

如果真的想炫耀的话,直接用FPGA仿个ARM核,或至少是51/AVR核出来啊——当然前提是不许【借鉴】别人的代码……

出0入0汤圆

发表于 2008-5-16 09:27:18 | 显示全部楼层
可以并行处理吧
用单片机只能同时测一路

出0入0汤圆

发表于 2008-5-16 09:29:06 | 显示全部楼层
watercat,你这就不客观了,难道你没有写过Hello,World?

出0入0汤圆

发表于 2008-5-16 09:31:18 | 显示全部楼层
还有的就是,不是每份资料都要电路图的,麻烦站长稍微了解一下,否则会被人笑话的,知识是用来尊重的。

出0入0汤圆

发表于 2008-5-16 09:44:11 | 显示全部楼层
【13楼】 foxgrey
        watercat,你这就不客观了,难道你没有写过Hello,World?

===========================

【Hello,World】和【FPGA控制18B20】的代码量,不在一个数量级上吧?

CPLD最适合一入一出的逻辑代换,FPGA则还可以加上一些相对复杂的数值演算,但无论如何,单周期或少数几个周期就能执行完毕的定制化操作才是CPLD/FPGA最适合的

强行要FPGA实现复杂的通信协议,不但需要太多的资源,而且也直接把FPGA扯到了一个根本不适合的应用领域中来

最简单地说,当你用FPGA实现需要几百上千个状态机、数百微秒甚至数百毫秒才能做到的工作时,也就自然而然会遇到MCU程序相同的情况——干扰敏感性,以及跑飞,那么这时候,谁给你当看门狗?谁给你保证抗干扰性?一个I2C协议,MCU内部硬件实现的时候,每个周期都要采样8~16次,并以特定算法判断有效值,你FPGA也来实现一把?又是几十个状态机出去了……但如果不用的话,随便一个脉冲干扰,你这状态机就不知道状态到哪里去了……

相比之下,MCU因为从诞生之日起就必须面临这些问题,因此许多年的发展下来,已经有无数成熟的解决和应对方案了,难道你认为,一个初学FPGA的人,会对这些方案从理论高度就深刻的了然于胸?如果不是的话,又怎么指望做出来的东西是能用的、安全的呢?

更何况,FPGA天生就是昂贵的,几百上千个状态机,折算下来就是千多乃至数千逻辑单元,一个5K逻辑单元的FPGA多钱?会比一片mega48便宜?可你用5K逻辑单元的FPGA实现mega48的全逻辑功能试试看?再给你一百倍的数量你都未必做的出来……这还是完全不考虑稳定性的情况下……

总而言之,用FPGA搞通信协议,在我看来,就是纯粹的【大学生论文】风格,好大喜功,却显然没用

出0入0汤圆

发表于 2008-5-16 13:02:01 | 显示全部楼层
首先,非常感谢watercat在忙碌的工作中认真地写了那么多来回复。

但是,有些观点我觉得有必要进行商榷。

首先,我不知道watercat对FPGA/CPLD的了解有多深刻,因此也不会胡乱猜测,但是,我个人对于FPGA/CPLD的了解来说,FPGA不只是您说的单周期或者几个周期就完成的定制化才是最合适的。

很多领域都是MCU所不能胜任的,简单地说,像高速数据采集如逻辑分析仪,复杂通信协议如Profibus,12M的UART,多达7个精确的定时器,MCU可以胜任吗?

相对于FPGA灵活的资源来说,而且一旦选型确定,MCU所使用的资源就被限定了,你不可能在这里或者那里增加或者减少些什么。而FPGA的软核,可以根据需要,定制外设。

再谈谈稳定性,就如您说的,这个就是需要时间来逐步改进的,而且现在有很多经过严格验证的IP Core可供选择,包括您说的I2C协议。

MCU是怎么设计实现的呢?应该是使用FPGA/CPLD的设计方法吧,5K逻辑单元是否能够实现Mega8全部功能我不是很了解,因为您所说的逻辑单元这个概念很模糊,但是EP2C5已经可以运行NIOS了。至于“100倍的数量都未必做的出来。。。“云云,这个就已经脱离了作为专业人员所应有的素养,毕竟井口和天相比还是比较小的。

昨天还跟朋友在网上聊,国内的电子技术基本上都是你抄我,我抄国外的。为什么呢,现成的东西用惯了,不愿意做些基础的东西。材料科学?哦,这个已经有稳定而且好用的国外产品,何必自己费劲,I2C的具体实现?这个已经基本上所有MCU都有实现,何必深究?浮点数的算法,加法器,乘法器?研究那个才傻。如果这样,那就只能在抄袭中度过一生了。

千里之行,属于足下,没有一次一次的尝试,包括用FPGA实现18B20的通讯,我才真不相信,一次性就可以做出什么“惊世骇俗“的产品。至少我不行,不知道watercat是否可以?

其实,watercat真的用MCU来实现过别人没有实现过的东西吗?很多东西都是别人做过N多次的东西了,有价值吗?再推一步说,即便今天你却是用MCU作了些别人没有实现过的东西,难道之前,没有做过与18B20通信这种N多人实现过N遍的事情吗?

FPGA/CPLD早就没有想象的那么贵了,而且会更便宜的。

出0入0汤圆

发表于 2008-5-16 13:28:04 | 显示全部楼层
to 【16楼】 foxgrey

好吧,既然这么说,那我承认我可能真的有所谓的“坐井观天”的情况

大体上,我用ATMEL的FPSLIC(AVR+FPGA)做过若干商业项目,专用的FPGA倒是只有自己玩玩,没有拿来做过商业项目的

使用FPSLIC后个人得到的结论就是

1、同样的逻辑功能,只要MCU部分能够提供或能够实现,那就总比FPGA部分做出来的好用、稳定

2、低速的数据处理,直接使用MCU部分处理比用FPGA方便得多

3、MCU有MCU做不到的事情,但只要MCU能做到的事,MCU总比FPGA便宜得多

至于您提到的【千里之行,属于足下】前后那段,我个人有一些很简单的说法

至少在中国,【抄袭】以外的东西绝大部分是属于那些事业有成生活无忧者的奢侈品,而不是一些初学者所能享受的,让中国的学生钻研诸如【FPGA控制18B20】之类的东西,并不是在帮他们,而是在害他们,因为除非他们未来有本事跟国内少数几家垄断企业挂上钩,否则不会有任何一家公司允许研发部门的员工把本来能用MCU做的工作改用FPGA来完成的

当然,如果纯粹的只是出于一种爱好,那么也是无所谓的,只要自己有闲有钱又不妨碍别人,玩什么都可以

不过,希望不要把爱好当成工作习惯就好了……

出0入0汤圆

发表于 2008-5-16 18:31:17 | 显示全部楼层
LZ人呢?

出0入0汤圆

 楼主| 发表于 2008-5-16 22:53:04 | 显示全部楼层
终于有这么多朋友来顶,谢谢了,至于电路图对FPGA来说确实是可有可无的
我在XILINX 3S200上实现了,占用了大约100个SLICES,应该不是很多

出0入0汤圆

 楼主| 发表于 2008-5-16 23:10:39 | 显示全部楼层
个人不太同意watercat大虾的看法,做流程控制确实不是FPGA的长处,同样的功能用MCU来实现确实要简单得多,但是在一个采用FPGA的项目里,如果要用到DS18B20,总不可能就为了测温再加一块MCU吧
至于通信协议我觉得用FGPA来做有它自身的优点,比如灵活性大之类的
在FPGA里也是可以内嵌MCU的,比如XILINX的8位的PICOBLAZE,32位的MICROBLAZE软核,用来控制DS18B20就比较方便了,用PICOBLAZE控制DS18B20的代码我也写过,但是占用资源要大些,所以不得以只好用纯VHDL来写了
没有任何炫耀的意思,小弟来OURAVR好久了,虽然这里FPGA版块的人气不旺,但是非常喜欢这里的开源气氛,所以就斗胆发出来了,让各位兄台见笑了

出0入0汤圆

 楼主| 发表于 2008-5-16 23:12:20 | 显示全部楼层
点击此处下载 ourdev_282882.pdf(文件大小:2.50M) (原文件名:S3BOARD-rm.pdf)
这是我用的XILINX SPARTAN3 STARTER KIT的资料,至于DS18B20的接口,只要接上+3.3V,地,数据线用4.7K上拉然后随便接到FPGA的一个空闲管脚就可以了

出0入0汤圆

 楼主| 发表于 2008-5-16 23:14:34 | 显示全部楼层
是针对单个DS18B20的

出0入0汤圆

发表于 2008-5-16 23:19:29 | 显示全部楼层
非常高兴看到watercat的认真回复。

我觉得还是技术回归技术,也对上贴的口不择言表示歉意。

对于watercat的观点,有部分观点完全同意,

没错,能用FPGA完成的,不要用NIOS;能用MCU完成的,不要用FPGA,这个主要是考虑到复用经过严格验证部分会保证项目的稳定,而且低廉。

但是个人认为,将来会有越来越多的项目MCU不能胜任,因此有必要学习了解FPGA如何解决指定问题,无疑用FPGA实现18B20也可以看作一个很好的学习。另外,考虑到功耗,体积或者一些特殊的要求,在只有FPGA的情况下,未必没有实际的意义。

FPGA真的是那么遥不可及吗,将来真的用的机会很少吗?我觉得眼光放长远些,应该没有坏处。

出0入0汤圆

发表于 2008-5-16 23:59:40 | 显示全部楼层
呃,我斗胆来插几句,希望不要被打。楼上的兄台不知道工作了多久,可能呆在一个让人比较羡慕的公司吧,有点不知民间疾苦啊,呵呵。

从技术上来说FPGA的确不是什么遥不可及的东西,但是,很不幸的,我们活在中国。

可能你没有见过,5块2毛钱的MCU已经完工的且卖出去不少了的东西,老板听说某台湾MCU便宜,便硬要工程师换用4块6毛钱的,工程师没办法实现(便宜6毛钱的代价就是资源少的可怜),就被请滚蛋的。

可能你没有想过,在大多数中国老板的眼里,最不值钱的是什么?恰恰就是技术人员,踢走了再招就是了。

出0入0汤圆

发表于 2008-5-19 00:07:52 | 显示全部楼层
【20楼】 zkf0100007
        个人不太同意watercat大虾的看法,做流程控制确实不是FPGA的长处,同样的功能用MCU来实现确实要简单得多,但是在一个采用FPGA的项目里,如果要用到DS18B20,总不可能就为了测温再加一块MCU吧
至于通信协议我觉得用FGPA来做有它自身的优点,比如灵活性大之类的
在FPGA里也是可以内嵌MCU的,比如XILINX的8位的PICOBLAZE,32位的MICROBLAZE软核,用来控制DS18B20就比较方便了,用PICOBLAZE控制DS18B20的代码我也写过,但是占用资源要大些,所以不得以只好用纯VHDL来写了
没有任何炫耀的意思,小弟来OURAVR好久了,虽然这里FPGA版块的人气不旺,但是非常喜欢这里的开源气氛,所以就斗胆发出来了,让各位兄台见笑了

========================

1、不提FPSLIC这类典型的情况,就单以A记或X记的标准FPGA来说,你认为不值得增加一个MCU用于流程控制?大多数8位MCU的价格都在人民币5元以下,付出5元的代价,能够让FPGA省却无数繁琐的工作,节约资源也就意味着能用更便宜的FPGA实现必须用FPGA实现的功能,而任何标准FPGA,其规模下降一个档次后,那价格下降,不止10块钱吧?再加上规模下降后,封装也会变得更简单,那么生产流程中的工艺成本也会明显下降……不考虑成本,至少在中国,是不可能成为一个受欢迎的设计师的

2、同样不提FPSLIC这类典型的情况,你认为增加一个MCU需要多少东西?ATtiny85,8脚芯片,6条IO线(与外设功能复用),提供8KFlash/512BSRAM/512BEEPROM,两路带死区控制250KPWM,4路单端/差分AD,内置温度传感器,单一引脚双向驱动能力达到最大40mA,内置的通用串行接口可实现UART/IIC/SPI等多种协议(相对于与FPGA通信来说,SPI应该是最有效的),在如此的封装下实现如此多的功能,你觉得有几种FPGA能做到?MCU,不止是指令集译码器那么简单……

3、其实个人认为,认为【一切都可以用FPGA完成】的想法,也就是一种误区,同样的误区,我也陷入过,不过既然你把你的东西放出来【欢迎拍砖】了,我也就没必要把我曾经的经验和教训继续藏私

个人认为,FPGA,最适合用于如下的目的

1、对项目体系中的数字逻辑部分,以精确效率实现具有精确时间定义的原子化操作

2、对只有功能要求,但缺乏明确逻辑定义的数字逻辑模块,在批量生产前进行样机模拟调测

3、对电路保密性有明确要求的项目

4、定制化程度高、产量极小而成本要求较宽泛的项目

但是,那种说【一切交由FPGA来完成,会更简单】的想法,就只是A记或X记这类FPGA厂家的促销策略罢了,作为一个合格的设计人员,如果还要信了厂家的这点话术,就实在有点说不过去了……

出0入0汤圆

 楼主| 发表于 2008-5-19 00:56:37 | 显示全部楼层
呵呵,仁者见仁,智者见智了,楼上的说的也许对,但我们的项目是不可能为了测温单独加一块MCU的了,电路板空间不允许

出0入0汤圆

发表于 2008-5-19 01:15:14 | 显示全部楼层
没啥好讨论的,和用啥mcu,c还是asm,os和裸奔道理一样

出0入0汤圆

 楼主| 发表于 2008-10-5 23:14:25 | 显示全部楼层
frmngil

有什么能帮上忙的?

出0入0汤圆

发表于 2008-10-5 21:48:43 | 显示全部楼层
你们这些大虾,有时间就多应该解决一下小弟们的实际困难。在这里打什么嘴仗啊?!



我想请教一个比较经典的用VHDL写的串口程序模块



zkf0100007&nbsp;同学,帮帮忙?!

出0入0汤圆

发表于 2008-10-5 10:36:58 | 显示全部楼层
记号,等有时间慢慢看

出0入0汤圆

发表于 2008-10-2 17:04:32 | 显示全部楼层
如果是IC设计公司,那么用FPGA实现这些东东是非常有必要的,在流片之前可以验证一下设计是否合格,而且很有必要。但是如果如楼上各位的那些情况,当然是能用MCU就不用FPGA,毕竟开发周期和成本还有可靠性都可以控制在满意的范围内。

出0入46汤圆

发表于 2008-10-1 10:07:36 | 显示全部楼层
千里之行始于足下啊!

FPGA的醉倒优点是他的并行处理,特别是做计算的时候,以前做过一个CORDIC算法,计算速度比P4电脑上快N倍。

出0入0汤圆

 楼主| 发表于 2008-10-1 09:19:02 | 显示全部楼层
呵呵,目前我接触过的项目,用的规模最大的FPGA是V4FX100,内嵌两个PPC405

子非鱼兄这么复杂的项目还没接触过,长见识了

出0入0汤圆

发表于 2008-10-1 02:05:28 | 显示全部楼层
我赞同watercat的看法。FPGA控制DS18B20仅仅作为一个练习还可以,但用到工程上就不太合适了。



FPGA只适合用于在一定的成本限制下MCU/DSP无法完成相应功能的场合上。

用FPGA来实现MCU/DSP就能实现的通讯协议绝对是自讨苦吃,无论是成本、灵活性、可扩展性、可维护性等等FPGA实现都是无法和MCU实现比拟的。当然也有MCU/DSP不能实现只能采用FPGA实现的通讯协议,例如OBSAI、CPRI等等Gbps级的通讯协议。





至于FPGA内嵌CPU软核,在我现在任职的公司还真没见过有哪个项目用上了或者用得上的(或许我孤陋寡闻吧),因为用得上FPGA的项目一般都挂一个或多个PowerPC或者DSP的。



另外不知楼主做过多大规模的FPGA设计呢?本人做过一个项目光逻辑综合就得花近1个小时的,加上后面的map、par合起来一天差不多就完了。开发调试时间就决定了能不让FPGA干的活就绝对不让它干。



最后“国内的电子技术”并不是“基本上都是你抄我,我抄国外的”,有很多核心的东西并不是你想抄就能抄到的。FPGA器件我们是没能力自主研发,但FPGA里面的程序我们还是有能力自主研发的。

本贴被 at90s 编辑过,最后修改时间:2008-10-01,02:06:44.

出0入0汤圆

 楼主| 发表于 2008-9-30 23:16:49 | 显示全部楼层
BIT0好像读出来总是‘1’,所以不取BIT0,可能是一个小BUG吧

这样取,读出来的结果是对的

temp_h&lt;='0'&TMP(11&nbsp;downto&nbsp;5);&nbsp;&nbsp;&nbsp;

temp_l&lt;="0000"&TMP(4&nbsp;downto&nbsp;1);&nbsp;&nbsp;

出0入0汤圆

发表于 2008-9-27 21:09:11 | 显示全部楼层
想知道temp_h&lt;='0'&TMP(11&nbsp;downto&nbsp;5);&nbsp;&nbsp;

temp_l&lt;="0000"&TMP(4&nbsp;downto&nbsp;1);&nbsp;&nbsp;是什么意思?&nbsp;



为什么不是temp_h&lt;='0'&TMP(10&nbsp;downto&nbsp;4);&nbsp;&nbsp;

temp_l&lt;="0000"&TMP(3&nbsp;downto&nbsp;0);???&nbsp;

出0入0汤圆

发表于 2008-9-17 21:22:02 | 显示全部楼层
想想你中学做的那些"数学难题"到了大学发现用高等数学一下就解决了,为啥那些"BC"中学老师会要你做?他们不懂微积分不懂高数?

人家只是用来学习的,练手,培养基本功.如果连这种变态训练都能完成,还有啥做不了的呢?基本功最重要.

现在的人太浮躁,以为做几个实例就能成为熟手高手,其实连个屁都不是.缺的就是这种基础训练,没有扎实的基本功,谈何高手?

出0入0汤圆

发表于 2009-10-14 11:01:33 | 显示全部楼层
有其他人测试这个程序成功的吗?

出0入0汤圆

发表于 2009-10-14 11:30:10 | 显示全部楼层
由于自己对于FPGA入行不久,没有相关的开发经验,只有一些对于FPGA优势介绍的理论,跟大家分享一下:

MCU以程序来执行控制,首先取出指令,然后按照一定的时序执行指令,每次只能执行一个操作,所以并行处理能力较差。
只对一两个端口采集数据的时候,通过中断处理或者是端口扫描的方法可以实现,但如果采集的通道多的话,基于中断的任务调度耗费就相当大,而且还会导致采集的延迟。
而FPGA正好解决了这个缺点,它相当于几个MCU并行处理,对于大量的数据采集来说,FPGA是相当有优势的。
目前看得FPGA比较多的例子是应用在数据通讯的接口控制器上,用来连接MCU和其它外设,只需要单芯片就可以实现几个通讯控制器,虽然实现通讯协议对于FPGA来说是相当困难,但还是有其积极的意义……

出0入0汤圆

发表于 2009-10-14 11:53:58 | 显示全部楼层
个人想法 用FPGA写写简单的通讯协议为了更好的熟悉FPGA

出0入0汤圆

发表于 2009-10-27 09:31:06 | 显示全部楼层
见仁见智了。

出0入0汤圆

发表于 2009-10-27 09:45:22 | 显示全部楼层
马克思主义哲学里面提过这样一句名言:“存在即合理”。

出0入0汤圆

发表于 2009-10-27 09:48:12 | 显示全部楼层
恩, 用fpga硬处理i2c确实有点那个, 处理处理简单的SPI还蛮好的, 比如  http://www.fpga4u.com/bbs/thread-229-1-1.html


不过作为练习, 很不错了。

出0入0汤圆

发表于 2009-10-27 14:12:45 | 显示全部楼层
学习VHDL以及状态机思想的很好的例子

出0入0汤圆

发表于 2009-10-29 11:11:54 | 显示全部楼层
我在Quartus上直接复制粘贴,然后分配引脚后,调试不通。不过添加了复位按键input后就可以了,不过显示的数据还有点问题。继续努力调~

出0入0汤圆

 楼主| 发表于 2009-10-29 16:16:01 | 显示全部楼层
楼上正解,我在XILINX平台上试过是没问题的,但是移植到ACTEL平台上确实是要加一个复位信号才可以

出0入0汤圆

发表于 2009-10-29 16:23:33 | 显示全部楼层
我赞同watercat的看法。

出0入0汤圆

 楼主| 发表于 2009-10-29 21:22:38 | 显示全部楼层
在这个帖子里讨论FPGA到底适不适合写通信协议没有任何意义,不可否认用单片机读写DS18B20是非常方便的,在一个FPGA系统里,难道就为了测个温非要加一片单片机吗,特别是对PCB面积有较高要求的情况下。发这个帖,没有任何炫耀的意思,再说我也不觉得这有什么值得炫耀的,不过是大家交流一下,共同进步而已。
另外,举一个例子,在一个需要10路RS485接口的系统里,实在想不出除了FPGA还有什么更好的选择,就算有,我想FPGA系统的并行,高速也不是单片机可比的

不要对自己没有尝试过的东西说没意义,你觉得没意义可能是你没有遇到这种需求而已,不要过早下结论

出0入0汤圆

发表于 2009-10-30 10:07:36 | 显示全部楼层
刚发现楼主的程序中独到TMP的数据有问题,稍加改动就能使TMP读取到正确的数据。
修改如下:
            when GET_TMP=>
                                 case GET_TMP_CNT is
                                        when 0 =>                                --添加了这一个状态,先读取一位数据
                                                STATE<=READ_BIT;
                                                GET_TMP_CNT<=GET_TMP_CNT+1;
                                    when 1 to 12=>
                                       STATE<=READ_BIT;
                                       TMP(GET_TMP_CNT-1)<=TMP_BIT;
                                       GET_TMP_CNT<=GET_TMP_CNT+1;
                                    when 13=>
                                       GET_TMP_CNT<=0;
                                       STATE<=WAIT4MS;
                                 end case;
原程序:
            when GET_TMP=>
                                 case GET_TMP_CNT is
                                    when 0 to 11=>                   --这里错误是,在还未读取数据的时候已经做了一次存储,所以TMP(0)这个位是多余的。如果用这个程序测试0度一下环境时候,应该会显示是正温度。呵呵
                                       STATE<=READ_BIT;
                                       TMP(GET_TMP_CNT-1)<=TMP_BIT;
                                       GET_TMP_CNT<=GET_TMP_CNT+1;
                                    when 12=>
                                       GET_TMP_CNT<=0;
                                       STATE<=WAIT4MS;
                                 end case;

出0入0汤圆

发表于 2009-10-30 10:10:20 | 显示全部楼层
我修改后的程序:
------------------------------------------
-----使用前必须先复位
--显示使用数码管,显示的数据未经处理,直接显示
--可以用PC上的计算器换算进制
--如果有谁能做一个FPGA的进制转换,那么不胜感激
--我自己做了,但是很不成功,于是放弃了

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;   --原程序可能为50MHz
               dq  : inout std_logic;
                        --    temp_h : out std_logic_vector(7 downto 0);
                        --    temp_l : out std_logic_vector(7 downto 0);
                                LED : out std_logic;
                                LED2 : out std_logic;
                                LED3 : out std_logic;
                                rst: in std_logic;
                        ----------------
                                dataout : out std_logic_vector(7 downto 0);
                                seg : out std_logic_vector(5 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,CMD_BE,WAIT800MS,GET_TMP,WAIT4MS);
signal STATE: STATE_TYPE:=RESET;

signal clk_temp : std_logic:='0';
signal clk1m : std_logic; --分频后得到的1M时钟

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 13:=0;

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

----------******************************
signal cnt2 : integer range 0 to 4000001:=0;
signal seg_temp : std_logic_vector(5 downto 0);
--signal temp_h : std_logic_vector(7 downto 0);
--signal temp_l : std_logic_vector(7 downto 0);

signal temp : std_logic;
signal data_temp0 : std_logic_vector(15 downto 0);
signal decimal0 : std_logic_vector(15 downto 0);
signal decimal1 : std_logic_vector(15 downto 0);
signal decimal2 : std_logic_vector(15 downto 0);
signal decimal3 : std_logic_vector(15 downto 0);
signal data_temp1 : std_logic_vector(7 downto 0);
signal integer0 : std_logic_vector(7 downto 0);
signal integer1 : std_logic_vector(7 downto 0);
signal integer2 : std_logic_vector(7 downto 0);
signal integer3 : std_logic_vector(7 downto 0);
signal integer4 : std_logic_vector(7 downto 0);
signal integer5 : std_logic_vector(7 downto 0);
signal integer6 : std_logic_vector(7 downto 0);

signal sign : std_logic_vector(7 downto 0);
-----------****************

signal count : integer range 0 to 51:=0;

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

begin

ClkDivider:process (clk,clk_temp)
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
if(rst='0') then
STATE<=RESET;
else
        case STATE is
            when RESET=>
                        --**********
                        LED2<='0';--*************-
                        LED3<='0';
                        --*********
            if (cnt>=0 and cnt<500) then
               dq<='0';
                            cnt<=cnt+1;
                                   STATE<=RESET;
                        elsif (cnt>=500 and cnt<510) then
                                dq<='Z';
                                cnt<=cnt+1;
                                STATE<=RESET;
                   elsif (cnt>=510 and cnt<750) then
                                temp<=dq;
                                if(cnt=580) then
                                        temp<=dq;
                                        if(temp='1') then
                                                LED<='0';
                                        else LED<='1';
                                        end if;
                                end if;
                            cnt<=cnt+1;
                            STATE<=RESET;
                                elsif (cnt>=750) then
                                    cnt<=0;
                                    STATE<=CMD_CC;
                                end if;
                when CMD_CC=>
                        LED2<='1';
                        LED3<='0';
                        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;
                                                LED3<='1';                                    
                                        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;
                                when others=>STATE<=RESET;
                        end case;
                when WRITE_LOW=>
                        LED3<='1';
                                case WRITE_LOW_CNT is
                                   when 0=>
                                              dq<='0';
                                      if (cnt=70) then
                                         cnt<=0;
                                         WRITE_LOW_CNT<=1;
                                      else
                                         cnt<=cnt+1;
                                      end if;
                                   when 1=>
                                      dq<='Z';
                                      if (cnt=5) 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 CMD_44=>
                        write_temp<="01000100";
                        STATE<=WRITE_BYTE;                
                when CMD_BE=>
                                write_temp<="10111110";
                                STATE<=WRITE_BYTE;
            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=>
                                   dq<='Z';
                               TMP_BIT<=dq;
                               if (cnt=1) then
                                  READ_BIT_CNT<=3;
                                  cnt<=0;
                               else
                                  cnt<=cnt+1;
                               end if;
                            when 3=>
                                ---------------------
                                   dq<='Z';
                                ---------------------
                               if (cnt=55) 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 WAIT800MS=>
                        if (cnt>=100000) then
                        STATE<=RESET;
                        cnt<=0;
                        else
                                cnt<=cnt+1;
                                STATE<=WAIT800MS;
                        end if;

            when GET_TMP=>
                                 case GET_TMP_CNT is
                                        when 0 =>
                                                STATE<=READ_BIT;
                                                GET_TMP_CNT<=GET_TMP_CNT+1;
                                    when 1 to 12=>
                                       STATE<=READ_BIT;
                                       TMP(GET_TMP_CNT-1)<=TMP_BIT;
                                       GET_TMP_CNT<=GET_TMP_CNT+1;
                                    when 13=>
                                       GET_TMP_CNT<=0;
                                       STATE<=WAIT4MS;
                                 end case;
                 when WAIT4MS=>
                                 if (cnt>=4000) then
                                        --STATE<=WAIT4MS;
                                    STATE<=RESET;
                                    cnt<=0;
                                 else
                                    cnt<=cnt+1;
                                    STATE<=WAIT4MS;
                                 end if;
                when others=>STATE<=RESET;
                        LED<='0';
                        LED2<='0';
                        LED3<='0';
        end case;

end if;
end if;
end process;

--temp_h<=TMP(11 downto 8);
--temp_h(7 downto 4) <= "1111";
--temp_l<=TMP(7 downto 0);

-----------**************************
--temp_h<='0'&TMP(11 downto 5);
--temp_l<="0000"&TMP(4 downto 1);
--------------------------------------------       
----------------------------------------------
process(seg_temp,clk)--,temp_l,temp_h)
begin
        if rising_edge( clk ) then
                if(seg_temp="111110") then--"1110") then--"11110") then
                        case TMP(3 downto 0) is--temp_l(3 downto 0) is
                        WHEN "0000" =>  dataout <= "11000000" ; --0
                        WHEN "0001" =>  dataout <= "11111001" ; --1
                        WHEN "0010" =>  dataout <= "10100100" ; --2
                        WHEN "0011" =>  dataout <= "10110000" ; --3
                        WHEN "0100" =>  dataout <= "10011001" ; --4
                        WHEN "0101" =>  dataout <= "10010010" ; --5
                        WHEN "0110" =>  dataout <= "10000010" ; --6
                        WHEN "0111" =>  dataout <= "11111000" ; --7
                                WHEN "1000" =>  dataout <= "10000000" ; --8
                                WHEN "1001" =>  dataout <= "10010000" ; --9
                                WHEN "1010" =>  dataout <= "10001000" ; --a
                                WHEN "1011" =>  dataout <= "10000011" ; --b
                                WHEN "1100" =>  dataout <= "11000110" ; --c
                                WHEN "1101" =>  dataout <= "10100001" ; --d
                                WHEN "1110" =>  dataout <= "10000110" ; --e
                                WHEN "1111" =>  dataout <= "10001110" ; --f
                                WHEN others=>   dataout <= "11000000";--0       
                        end case;
                elsif(seg_temp="111101") then--"1101") then--"11101") then
                        case TMP(7 downto 4) is--temp_l(7 downto 4) is
                        WHEN "0000" =>  dataout <= "11000000" ; --0
                        WHEN "0001" =>  dataout <= "11111001" ; --1
                        WHEN "0010" =>  dataout <= "10100100" ; --2
                        WHEN "0011" =>  dataout <= "10110000" ; --3
                        WHEN "0100" =>  dataout <= "10011001" ; --4
                        WHEN "0101" =>  dataout <= "10010010" ; --5
                        WHEN "0110" =>  dataout <= "10000010" ; --6
                        WHEN "0111" =>  dataout <= "11111000" ; --7
                                WHEN "1000" =>  dataout <= "10000000" ; --8
                                WHEN "1001" =>  dataout <= "10010000" ; --9
                                WHEN "1010" =>  dataout <= "10001000" ; --a
                                WHEN "1011" =>  dataout <= "10000011" ; --b
                                WHEN "1100" =>  dataout <= "11000110" ; --c
                                WHEN "1101" =>  dataout <= "10100001" ; --d
                                WHEN "1110" =>  dataout <= "10000110" ; --e
                                WHEN "1111" =>  dataout <= "10001110" ; --f       
                                WHEN others=>   dataout <= "11000000";--0               
                        end case;
                elsif(seg_temp="111011") then--"1011") then--"11011") then
                        case TMP(11 downto 8) is--temp_h(3 downto 0) is
                        WHEN "0000" =>  dataout <= "11000000" ; --0
                        WHEN "0001" =>  dataout <= "11111001" ; --1
                        WHEN "0010" =>  dataout <= "10100100" ; --2
                        WHEN "0011" =>  dataout <= "10110000" ; --3
                        WHEN "0100" =>  dataout <= "10011001" ; --4
                        WHEN "0101" =>  dataout <= "10010010" ; --5
                        WHEN "0110" =>  dataout <= "10000010" ; --6
                        WHEN "0111" =>  dataout <= "11111000" ; --7
                                WHEN "1000" =>  dataout <= "10000000" ; --8
                                WHEN "1001" =>  dataout <= "10010000" ; --9
                                WHEN "1010" =>  dataout <= "10001000" ; --a
                                WHEN "1011" =>  dataout <= "10000011" ; --b
                                WHEN "1100" =>  dataout <= "11000110" ; --c
                                WHEN "1101" =>  dataout <= "10100001" ; --d
                                WHEN "1110" =>  dataout <= "10000110" ; --e
                                WHEN "1111" =>  dataout <= "10001110" ; --f
                                WHEN others=>   dataout <= "11000000" ;--0
                        end case;                       
                end if;       
        end if;
end process;

seg<=seg_temp;

process(clk1m)
begin
        if rising_edge(clk1m) then
                if(cnt2<20) then
                        cnt2<=cnt2+1;
                        seg_temp<="111110";--"1110";--"11110";
                elsif(cnt2<40 AND cnt2>=20) then
                        cnt2<=cnt2+1;
                        seg_temp<="111101";--"1101";--"11101";
                elsif(cnt2<60 AND cnt2>=40) then
                        cnt2<=cnt2+1;
                        seg_temp<="111011";--"1011";--"11011";
                else
                        cnt2<=0;
                        seg_temp<="111110";--"1110";--"11110";
                end if;
        end if;
end process;
end Behavioral;

出0入0汤圆

 楼主| 发表于 2009-10-30 10:51:17 | 显示全部楼层
顶楼上的,支持一下

出0入0汤圆

发表于 2009-11-4 11:01:03 | 显示全部楼层
哇,太多牛人了啊

出0入0汤圆

发表于 2009-11-4 11:25:30 | 显示全部楼层
必须要mark一下的! 嘿嘿

出0入0汤圆

发表于 2009-11-12 21:44:47 | 显示全部楼层
我想问下楼主你的ds18b20和fpga怎么连接的,
我用的是de2开发板,他提供了很多GPIO,
但是18B20是一根线通信的,还需要上拉电阻,就是这个上拉电阻我不知道怎么整。。。。
请指教啊。
还是直接可以把这个ds18b20直接用杜邦线接到那个gpio上面去?通过控制管脚的高低电平实现通信?
还有那个18b20的接地是怎么处理的,连接到哪里的?
帮帮我啊,楼主大人。

出0入0汤圆

 楼主| 发表于 2009-11-13 00:01:42 | 显示全部楼层
DS18B20电源接3.3V,GND接地,数据线直接接到FPGA的任意IO口,再用4.7K 电阻上拉到3.3V即可

出0入0汤圆

发表于 2009-11-13 13:04:15 | 显示全部楼层
果然,还是需要外接上拉电阻。。。
我是这样考虑的,3.3V的电源我用io口输出1,当做电源;如果接地的脚的话,我再用一个IO口输出0,表示是接地,再用一个IO口输出高,接上拉电压加电阻,请问这样行不行啊。。。

接电阻的话是不是还要用到面包板啊。

出0入0汤圆

 楼主| 发表于 2009-11-13 19:37:08 | 显示全部楼层
奇怪了,干嘛不接到电源端呢?

出0入0汤圆

 楼主| 发表于 2009-11-13 19:38:16 | 显示全部楼层
就一个DS18B20的话,用不着面包板,飞几根线就可以了,很简单的

出0入0汤圆

发表于 2009-11-14 04:44:38 | 显示全部楼层
在UCF文件里让FPGA的对应管脚使用上拉模式是不是就能省了那个上拉电阻了?

出0入0汤圆

 楼主| 发表于 2009-11-14 12:45:17 | 显示全部楼层
内部上拉可能是10K吧,你可以试一下看

出0入0汤圆

发表于 2009-11-14 12:58:26 | 显示全部楼层
嗯,因为我比较BC。。。。
找不到那个电源端和接地端在哪里。。。我试试看吧。

出0入0汤圆

发表于 2009-11-14 13:20:20 | 显示全部楼层
找到个设置上拉电阻的方法。。。呵呵。
点击此处下载 ourdev_503095.pdf(文件大小:702K) (原文件名:上拉电阻的设置.pdf)

出5入8汤圆

发表于 2009-11-15 13:35:26 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-11-19 10:49:30 | 显示全部楼层
都是高手!

出0入0汤圆

发表于 2009-11-19 16:55:59 | 显示全部楼层
现在都有电路了。阿莫是不是应该至酷了啊?呵呵

出0入0汤圆

发表于 2009-12-7 19:47:52 | 显示全部楼层
在xilinx spartan-3a XC3S400A 上面综合的结果 :


(原文件名:Capture.jpg)

出0入0汤圆

发表于 2009-12-10 16:48:55 | 显示全部楼层
牛啊!我什么时候也能这样呢?加油!

出0入0汤圆

发表于 2009-12-10 23:57:29 | 显示全部楼层
对于FPGA来说,这个可以不用给出电路图,很COOL的啊,内容非常精彩,论坛麻,就是非常须要多一些这类的讨论!

出0入0汤圆

发表于 2009-12-17 11:20:11 | 显示全部楼层
Mark

出0入0汤圆

发表于 2010-2-20 00:42:07 | 显示全部楼层
必须mark。

出0入0汤圆

发表于 2010-2-28 19:18:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-3 08:58:34 | 显示全部楼层
OO═══∩═══OO  
    ╭╬╮          ◢  
-▁╭▅▇□□█▇▆▅▄▃▂▁(╳)█╮  
  ╰═▃_专机来访▁∠════▔▔▔   
  ╙O ╙O!↓

出0入0汤圆

发表于 2010-3-4 12:41:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-5 22:45:21 | 显示全部楼层
记号,以后学习

出0入0汤圆

发表于 2010-3-6 01:38:14 | 显示全部楼层
【12楼】 wswh2o 水之影

  MCU也可以同时处理多个,我干过同时8个的,很简单,就是把一个位扩张成一个字节,读写一个完整的端口就行

出0入0汤圆

发表于 2010-3-6 22:29:33 | 显示全部楼层
不错,我喜欢!

出0入112汤圆

发表于 2010-3-7 16:17:05 | 显示全部楼层
请问你的测量结果准吗?
我的结果比实际高出约2度,不知为何?

出0入0汤圆

发表于 2010-3-12 09:40:31 | 显示全部楼层
回复【78楼】xunke 科
请问你的测量结果准吗?  
我的结果比实际高出约2度,不知为何?
-----------------------------------------------------------------------

me too.

出0入0汤圆

发表于 2010-4-7 17:18:22 | 显示全部楼层
要肯定!
必须的!

出0入0汤圆

发表于 2010-4-7 21:01:52 | 显示全部楼层
记一下,以后学习。

出0入0汤圆

发表于 2010-4-14 16:58:24 | 显示全部楼层
论坛就应该讨论,讨论才能发现问题的根本,mark,我什么时候才能加入到讨论的行列

出0入0汤圆

发表于 2010-4-14 21:05:58 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-4-24 10:22:18 | 显示全部楼层
回楼主:
这个必定是酷贴,非常感谢你。
另外我有两个问题,我感觉楼主的代码确实存在一点问题:如果没有异步的reset(signal 的 reset加上也好吧),上电后如何才能进入reset呢?我想应该是要状态机轮转一圈吧。这样稳定性就不好了。
                                                    我知道对端口赋初值是没有意义的,另外问一下对信号赋初值有用吗?谢谢。
------------------------
------------------------
回复flashman911 :
下面的代码:
STATE_TRANSITION:process(STATE,clk1m)
begin
if rising_edge(clk1m) then  
if(rst='0') then  
STATE<=RESET;
else
case STATE is  
     when RESET=>  
--------------------------
当rst是1怎么办,那STATE是什么状态,如果不确定外面的端口的电平也就不知道了?还是要转一圈才能reset,这也不合规范吧。另外如果rst一直是0呢?一直处于reset,但reset状态却没有执行。

我个人还是认为写两个进程比较好吧。用PRE-STATE和NEXT_STATE.
----------------------------------------
谢谢两位回答。

出0入0汤圆

 楼主| 发表于 2010-4-24 17:14:14 | 显示全部楼层
虽然很多书上说对信号赋初值没有意义,只能用于仿真
但是,我可以很负责任的告诉你,在XILINX平台上赋初值是有意义的,FPGA上电后的默认值就是赋的初值
这可能跟每个公司的器件有关,其他公司的具体情况我不太清楚

另外,状态机一般也是推荐使用两个进程的,我这里偷了一下懒,呵呵

出0入0汤圆

发表于 2010-4-24 19:10:26 | 显示全部楼层
非常感谢楼主的解答,我下次做个实验就好啦。
另外我在做PCI的接口,请问XILINX平台8.2(我的FPGA是Sparten ii的)的pci core为什么不让调用,不知道是权限问题,还是版本问题,有完整的破解版本吗?真的非常需要,感谢回答啊。

出0入0汤圆

 楼主| 发表于 2010-4-25 01:49:57 | 显示全部楼层
呵呵,不谢
PCI CORE我没用过,你的情况可能有两种情况
1.PCI CORE需要付费
2.SPARTAN II属于比较老的器件,是否支持PCI CORE?

出0入0汤圆

发表于 2010-5-3 20:16:55 | 显示全部楼层
。。。

出0入0汤圆

发表于 2010-5-5 23:46:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-6 07:42:22 | 显示全部楼层
留个影,以后学习。

出0入0汤圆

发表于 2010-10-5 18:34:41 | 显示全部楼层
mark,正在学习

出0入0汤圆

发表于 2010-10-14 12:46:02 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-10-14 12:46:14 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-10-16 19:45:29 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-27 17:08:07 | 显示全部楼层
其实对于FPGA,我是又爱又恨...

出0入0汤圆

发表于 2010-10-29 10:44:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-29 11:12:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-10 10:32:09 | 显示全部楼层
m

出0入0汤圆

发表于 2010-12-10 21:01:11 | 显示全部楼层
mark

出50入0汤圆

发表于 2010-12-15 14:38:32 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-11 10:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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