找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2917|回复: 0
打印 上一主题 下一主题
收起左侧

Spartan-6 FPGA驱动ds18B20的源程序

[复制链接]
跳转到指定楼层
楼主
spartan-6芯片外挂一颗ds18B20来读取温度,根据此温度来进行加热控制

  1. module DS18B20_drive
  2. (
  3. input clk,rst_n,
  4. inout  temp_dq,
  5. output reg [15:0] temp
  6. );

  7. reg ds,flag;

  8.         //延时参数
  9. parameter TIME_1us   = 32'd50,
  10.                   TIME_2us   = 32'd100,
  11.                   TIME_4us   = 32'd200,
  12.                   TIME_8us   = 32'd400,
  13.                   TIME_550us = 32'd27500,
  14.                   TIME_500us = 32'd25000,
  15.                   TIME_66us  = 32'd3300,
  16.                   TIME_20us  = 32'd1000,
  17.                   TIME_1s    = 32'd50_000_000;

  18. parameter RESET1 = 3'd0,
  19.                   DELAY1 = 3'd1,
  20.                   WRITE1 = 3'd2,
  21.                   DELAY2 = 3'd3,
  22.                   RESET2 = 3'd4,
  23.                   DELAY3 = 3'd5,
  24.                   WRITE2 = 3'd6,
  25.                   READ   = 3'd7;

  26. `define        delay_1us                cnt_clk_r        == TIME_1us
  27. `define        delay_2us                cnt_clk_r        == TIME_2us
  28. `define        delay_4us                cnt_clk_r        == TIME_4us
  29. `define        delay_8us                cnt_clk_r        == TIME_8us
  30. `define        delay_20us                cnt_clk_r        == TIME_20us
  31. `define        delay_550us                cnt_clk_r        == TIME_550us
  32. `define        delay_500us                cnt_clk_r        == TIME_500us
  33. `define        delay_66us                cnt_clk_r        == TIME_66us
  34. `define        delay_1s                        cnt_clk_r        == TIME_1s
  35. //状态变重
  36. reg [2:0]         work_state,
  37.                         state_rest1,
  38.                         state_write1,
  39.                         state_rest2,
  40.                         state_write2,
  41.                         state_read;

  42. reg [4:0] i;
  43. reg [4:0] j;
  44. reg [15:0] value;
  45. //reg flag;

  46. /*
  47. parameter val1   = 16'h44CC,
  48.                   val2   = 16'hBECC;
  49. */
  50. reg [15:0] vala;
  51. reg [15:0] val2;


  52. always @(posedge clk or negedge rst_n)
  53. begin
  54.         if(!rst_n)begin
  55.                 ds <= 1'b1;
  56.                 work_state  <= 3'd0;
  57.                 state_rest1 <= 3'd0;
  58.                 state_write1<= 3'd0;
  59.                 state_rest2 <= 3'd0;
  60.                 state_write2<= 3'd0;
  61.                 state_read  <= 3'd0;
  62.                 vala   <= 16'h44CC;
  63.                 val2   <= 16'hBECC;
  64.                 i <= 5'd0;
  65.                 j <= 5'd0;
  66.                 flag <= 1'b1;
  67.         end
  68.         else begin
  69.                 case(work_state)
  70.                 //复位1
  71.                 RESET1:
  72.                         case(state_rest1)
  73.                                 3'd0:        //ds=1 延时1us
  74.                                         begin
  75.                                                 state_rest1 <= (`delay_1us) ? 3'd1:3'd0;
  76.                                                 ds <= 1'b1;
  77.                                         end                       
  78.                                 3'd1:        //ds=0 延时550us 要求480~960us
  79.                                         begin
  80.                                                 state_rest1 <= (`delay_550us) ? 3'd2:3'd1;
  81.                                                 ds <= 1'b0;
  82.                                         end
  83.                                 3'd2:        //ds=z 延时66us 释放总线等待15-60us使ds18B20发出低脉再
  84.                                         begin
  85.                                                 state_rest1 <= (`delay_66us) ? 3'd3:3'd2;
  86.                                                 ds <= 1'bz;
  87.                                         end
  88.                                 3'd3://获取低脉再
  89.                                         begin
  90.                                                 state_rest1 <= 3'd4;
  91.                                                 flag <= ds;
  92.                                         end
  93.                                 3'd4:
  94.                                         begin
  95.                                                 if(flag==1'b0)
  96.                                                         begin
  97.                                                                 ds <= 1'bz;
  98.                                                                 work_state <= DELAY1;
  99.                                                         end
  100.                                                 else
  101.                                                         begin
  102.                                                                 state_rest1 <= 3'd0;
  103.                                                                 ds <= 1'b1;
  104.                                                                 work_state <= work_state;
  105.                                                         end
  106.                                         end
  107.                                 default:state_rest1 <= 3'd0;
  108.                         endcase
  109.                 DELAY1://等待18B20发出的低脉冲信号完全结束60~240us
  110.                         begin
  111.                                 work_state <= (`delay_500us) ? WRITE1 : DELAY1;
  112.                                 //flag <= 1'b1;
  113.                         end
  114.                 //写数捠写入数据16'hcc 16'h44
  115.                 WRITE1:
  116.                         case(state_write1)
  117.                                 3'd0:        //        ds=1 延时1us 连续写两位间隔大仵s
  118.                                         begin
  119.                                                 state_write1 <= (`delay_2us) ? 3'd1:3'd0;
  120.                                                 ds <= 1'b1;
  121.                                         end
  122.                                 3'd1:        //ds=0 延时4us 将FPGA引脚从高拉至低电平时,就产生写时间隙
  123.                                         begin
  124.                                                 state_write1 <= (`delay_4us) ? 3'd2:3'd1;
  125.                                                 ds <= 1'b0;
  126.                                         end
  127.                                 3'd2:        //写一侥۶时66us
  128.                                         begin
  129.                                                 state_write1 <= (`delay_66us) ? 3'd3:3'd2;
  130.                                                 ds <= vala[0];
  131.                                         end
  132.                                 3'd3:  
  133.                                         begin
  134.                                                 if(i <= 14)
  135.                                                         begin
  136.                                                                 vala <= {1'b0,vala[15:1]};
  137.                                                                 i <= i+1'b1;
  138.                                                                 state_write1 <= 3'd0;
  139.                                                         end
  140.                                                 else if(i==15)
  141.                                                         begin
  142.                                                                 state_write1 <= 3'd4;
  143.                                                                 vala <= {1'b0,vala[15:1]};
  144.                                                         end
  145.                                         end
  146.                                 3'd4:        //ds=1 延时1us
  147.                                         begin
  148.                                                 ds <= 1'bz;
  149.                                                 i <= 5'd0;
  150.                                                 state_write1 <= (`delay_1us) ? 3'd5:3'd4;
  151.                                         end
  152.                                 3'd5:
  153.                                         begin
  154.                                                 work_state <= DELAY2;
  155.                                         end
  156.                                 default:state_write1 <= 3'd0;
  157.                         endcase
  158.                         //延时1s,使得芯片完成温度转化(datasheet要求最尿00ms_
  159.                 DELAY2:
  160.                         begin
  161.                                 work_state <= (`delay_1s) ? RESET2:DELAY2;
  162.                                 ds <= 1'bz;
  163.                         end
  164.                 //复位2
  165.                 RESET2:
  166.                         case(state_rest2)
  167.                                 3'd0:        //ds=1 延时1us
  168.                                         begin
  169.                                                 state_rest2 <= (`delay_1us) ? 3'd1:3'd0;
  170.                                                 ds <= 1'b1;
  171.                                         end                       
  172.                                 3'd1:        //ds=0 延时550us 要求480~960us
  173.                                         begin
  174.                                                 state_rest2 <= (`delay_550us) ? 3'd2:3'd1;
  175.                                                 ds <= 1'b0;
  176.                                         end
  177.                                 3'd2:        //ds=z 延时66us 释放总线等待15-60us使ds18B20发出低脉再
  178.                                         begin
  179.                                                 state_rest2 <= (`delay_66us) ? 3'd3:3'd2;
  180.                                                 ds <= 1'bz;
  181.                                         end
  182.                                 3'd3://获取低脉再
  183.                                         begin
  184.                                                 state_rest2 <= 3'd4;
  185.                                                 flag <= ds;
  186.                                         end
  187.                                 3'd4:
  188.                                         begin
  189.                                                 if(flag==1'b0)
  190.                                                         begin
  191.                                                                 ds <= 1'bz;
  192.                                                                 work_state <= DELAY3;
  193.                                                         end
  194.                                                 else
  195.                                                         begin
  196.                                                                 state_rest2 <= 3'd0;
  197.                                                                 ds <= 1'b1;
  198.                                                                 work_state <= work_state;
  199.                                                         end
  200.                                         end
  201.                                 default:state_rest2 <= 3'd0;
  202.                         endcase
  203.                 DELAY3:
  204.                         begin
  205.                                 work_state <= (`delay_500us) ? WRITE2:DELAY3;
  206.                         end
  207.                 //写操你写入16'hcc 16'hBE
  208.                 WRITE2:
  209.                         case(state_write2)
  210.                                 3'd0:        //                ds=1 延时1us 连续写两位间隔大仵s
  211.                                         begin
  212.                                                 state_write2 <= (`delay_2us) ? 3'd1:3'd0;
  213.                                                 ds <= 1'b1;
  214.                                         end
  215.                                 3'd1:        //ds=0 延时4us
  216.                                         begin
  217.                                                 state_write2 <= (`delay_4us) ? 3'd2:3'd1;
  218.                                                 ds <= 1'b0;
  219.                                         end
  220.                                 3'd2:        //写一侥۶时66us
  221.                                         begin
  222.                                                 state_write2 <= (`delay_66us) ? 3'd3:3'd2;
  223.                                                 ds <= val2[0];
  224.                                         end
  225.                                 3'd3:  
  226.                                         begin
  227.                                                 if(i <= 14)
  228.                                                         begin
  229.                                                                 val2 <= {1'b0,val2[15:1]};
  230.                                                                 i <= i+1'b1;
  231.                                                                 state_write2 <= 3'd0;
  232.                                                         end
  233.                                                 else if(i==15)
  234.                                                         begin
  235.                                                                 state_write2 <= 3'd4;
  236.                                                                 val2 <= {1'b0,val2[15:1]};
  237.                                                         end
  238.                                         end
  239.                                 3'd4:        //ds=z 延时1us
  240.                                         begin
  241.                                                 ds <= 1'bz;
  242.                                                 i <= 5'd0;
  243.                                                 state_write2 <= (`delay_1us) ? 3'd5:3'd4;
  244.                                         end
  245.                                 3'd5:
  246.                                         begin
  247.                                                 work_state <= READ;
  248.                                         end
  249.                                 default:state_write2 <= 3'd0;
  250.                         endcase
  251.                 //读操位
  252.                 READ:
  253.                         case(state_read)
  254.                                 3'd0:        //        ds=1 延时2us 读两个位之间应大仵s
  255.                                         begin
  256.                                                 ds <= 1'b1;
  257.                                                 state_read <= (`delay_2us) ? 3'd1:3'd0;
  258.                                         end
  259.                                 3'd1:        //ds=0 延时4us  从高拉至低电平时,总线只须保持低电庵s
  260.                                         begin
  261.                                                 state_read <= (`delay_4us) ? 3'd2:3'd1;
  262.                                                 ds <= 1'b0;
  263.                                         end
  264.                                 3'd2:        //ds=1 延时4us  将总线拉高,产生读时间隍
  265.                                         begin
  266.                                                 state_read <= (`delay_4us) ? 3'd3:3'd2;
  267.                                                 ds <= 1'b1;
  268.                                                
  269.                                         end
  270.                                 3'd3:
  271.                                         begin
  272.                                                 value[0] <= ds;
  273.                                                 state_read <= 3'd4;
  274.                                         end
  275.                                 3'd4:
  276.                                         begin
  277.                                                 if(j<=15)
  278.                                                         begin
  279.                                                                 value <= {value[0], value[15:1]};
  280.                                                                 j <= j+1'b1;
  281.                                                                 state_read <= 3'd5;
  282.                                                         end
  283.                                                 else
  284.                                                         begin
  285.                                                                 state_read <= 3'd6;
  286.                                                                 temp <= value;
  287.                                                                 j <= 5'd0;
  288.                                                         end
  289.                                         end
  290.                                 3'd5://60us~120us内释放总线
  291.                                         begin
  292.                                                         state_read <= (`delay_66us) ? 3'd0:3'd5;
  293.                                         end                               
  294.                                 3'd6:
  295.                                         begin
  296.                                                 ds <= 1'b1;
  297.                                                 work_state <= RESET1;
  298.                                                 state_rest1 <= 3'd0;
  299.                                                 state_write1<= 3'd0;
  300.                                                 state_rest2 <= 3'd0;
  301.                                                 state_write2<= 3'd0;
  302.                                                 state_read  <= 3'd0;
  303.                                                 vala   <= 16'h44CC;
  304.                                                 val2   <= 16'hBECC;
  305.                                                 flag <= 1'b1;
  306.                                         end
  307.                                 default:state_read <= 3'd0;
  308.                         endcase
  309.                         default:work_state <= RESET1;
  310.                 endcase
  311.         end
  312. end

  313. //------------------------------------------------------------------------------
  314. //产生18b20时序操作的延旍
  315. //------------------------------------------------------------------------------
  316. reg[31:0] cnt_clk_r;        //时钟计数
  317. reg cnt_rst_n;                //时钟计数复位信号       

  318. always @ (posedge clk or negedge rst_n)
  319.         if(!rst_n) cnt_clk_r <= 32'd0;                        //计数寄存器复位
  320.         else if(!cnt_rst_n) cnt_clk_r <= 32'd0;        //计数寄存器清雍
  321.         else cnt_clk_r <= cnt_clk_r+1'b1;                //启动计数延时

  322. always @(*)begin
  323.                 case(work_state)
  324.                         RESET1:
  325.                                 begin
  326.                                 case(state_rest1)
  327.                                         3'd0:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
  328.                                         3'd1:cnt_rst_n <= (`delay_550us) ? 1'b0:1'b1;
  329.                                         3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
  330.                                         default:cnt_rst_n <= 1'b0;
  331.                                 endcase
  332.                                 end
  333.                         DELAY1:
  334.                                 begin
  335.                                         cnt_rst_n <= (`delay_500us) ? 1'b0:1'b1;
  336.                                 end
  337.                         WRITE1:
  338.                                 begin
  339.                                 case(state_write1)
  340.                                         3'd0:cnt_rst_n <= (`delay_2us) ? 1'b0:1'b1;
  341.                                         3'd1:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
  342.                                         3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
  343.                                         3'd4:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
  344.                                         default:cnt_rst_n <= 1'b0;
  345.                                 endcase
  346.                                 end
  347.                         DELAY2:
  348.                                 begin
  349.                                         cnt_rst_n <= (`delay_1s) ? 1'b0:1'b1;
  350.                                 end
  351.                         RESET2:
  352.                                 begin
  353.                                 case(state_rest2)
  354.                                         3'd0:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
  355.                                         3'd1:cnt_rst_n <= (`delay_550us) ? 1'b0:1'b1;
  356.                                         3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
  357.                                         default:cnt_rst_n <= 1'b0;
  358.                                 endcase
  359.                                 end
  360.                         WRITE2:
  361.                                 begin
  362.                                 case(state_write2)
  363.                                         3'd0:cnt_rst_n <= (`delay_2us) ? 1'b0:1'b1;
  364.                                         3'd1:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
  365.                                         3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
  366.                                         3'd4:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
  367.                                         default:cnt_rst_n <= 1'b0;
  368.                                 endcase
  369.                                 end
  370.                         DELAY3:
  371.                                 begin
  372.                                         cnt_rst_n <= (`delay_500us) ? 1'b0:1'b1;
  373.                                 end
  374.                         READ:
  375.                                 begin
  376.                                 case(state_read)
  377.                                         3'd0:cnt_rst_n <= (`delay_2us) ? 1'b0:1'b1;
  378.                                         3'd1:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
  379.                                         3'd2:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
  380.                                         3'd5:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
  381.                                         default:cnt_rst_n <= 1'b0;
  382.                                 endcase
  383.                                 end               
  384.                         default:cnt_rst_n <= 1'b0;
  385.                 endcase
  386. end

  387. assign temp_dq = ds;

  388. /*
  389. //chipscope观察输出和输入的数据,检查数据是否正硿
  390. wire [35:0]   CONTROL0;
  391. wire [255:0]  TRIG0;
  392. chipscope_icon icon_debug (
  393.     .CONTROL0(CONTROL0) // INOUT BUS [35:0]
  394. );

  395. chipscope_ila ila_filter_debug (
  396.     .CONTROL(CONTROL0), // INOUT BUS [35:0]
  397.    // .CLK(dma_clk),      // IN
  398.     .CLK(clk),      // IN
  399.     .TRIG0(TRIG0)      // IN BUS [255:0]

  400.    //.TRIG_OUT(TRIG_OUT0)
  401. );      
  402.                                           
  403. assign  TRIG0[15:0] =  temp;
  404. assign  TRIG0[31:16] =  ~temp;
  405. */
  406. endmodule
复制代码

全部资料51hei下载地址:
DS18B20_drive.zip (2.36 KB, 下载次数: 31)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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