基于FPGA的DS18B20控制程序设计及其Verilog实现(三)


三,DS18B20的温度测量控制

在该系统中,1-Wire总线上只存在1个DS18B20,在控制DS18B20进行温度测量的时候,根据1-Wire总线的特性和DS18B20的控制要求,可以采用相对简单的控制流程。下面是控制流程图:

基于FPGA的DS18B20控制程序设计及其Verilog实现(三)_第1张图片

我们用状态机来实现这个控制流程。从控制流程图可以看到,系统从空闲状态到读出温度数据,总共有8个大的步骤。而其中2和6,3和7是相同的,用状态机实现的时候,可以用同一个状态表示2和6,用同一个状态表示3和7。这样整个状态机就只需要6个状态。下面表格是状态机所有状态的定义:

状态名称

含义

TTST_IDLE

系统空闲状态

TTST_RST

总线初始化

TTST_SKPROM

SKIP ROM 命令

TTST_CONVERT

温度转换命令

TTST_WOVER

等待温度转换结束

TTST_GETDATA

读取温度数据

为了区分2和6以及3和7。用IS_CONVERT信号表示总线初始化和SKIP ROM命令是用来执行CONVERT命令的。用~IS_CONVERT信号表示总线初始化和SKIP ROM命令是用来读取温度数据的。在状态机进入TTST_IDLE状态时,令IS_CONVERT为1并保持,当状态机进入TTST_WOVER状态时,令IS_CONVERT为0并保持。

用TEST_EN信号作为温度测量的开始信号,这个信号至少保持1个时钟周期(CLK1MHZ),如果TEST_EN的长度超过了一次测试所需要的总的时间,则在一次测试完成以后,就直接开始进行第二次测量。

用RST_OVER信号作为总线初始化的结束和下一个状态的开始的标志信号。

用WBD_OVER信号作为命令(SKIPROM,CONVERT)结束和下一个状态开始的标志信号。

用RD_BIT_DATA & PHASE_RD_OVER 表示等待温度转换结束和下一个状态开始的信号(详细的原因可参照DS18B20 datasheet的相关部分)。

用BYTE_READ_OVER & PHASENXT_RDSPAD_IDLE表示读取温度数据结束的信号(该两个信号的与表示读DS18B20 9Byte ROM数据状态机完成工作并进入IDLE状态)。

下面是状态机的状态转换图:

基于FPGA的DS18B20控制程序设计及其Verilog实现(三)_第2张图片

下面是verilog的实现:

reg IS_CONVERT;

parameter TTST_IDLE = 6'b00_0001,

TTST_RST = 6'b00_0010,

TTST_SKPROM = 6'b00_0100,

TTST_CONVERT = 6'b00_1000,

TTST_WOVER = 6'b01_0000,

TTST_GETDATA = 6'b10_0000;

reg [5:0] TTSTSM, TTSTSMNXT;

wire PHASE_TTST_IDLE = TTSTSM[0];

wire PHASE_TTST_RST = TTSTSM[1];

wire PHASE_TTST_SKPROM = TTSTSM[2];

wire PHASE_TTST_CONVERT = TTSTSM[3];

wire PHASE_TTST_WOVER = TTSTSM[4];

wire PHASE_TTST_GETDATA = TTSTSM[5];

wire PHASENXT_TTST_IDLE = TTSTSMNXT[0];

always @(posedge CLK1MHZ or negedge RESET)

begin

if(~RESET)

TTSTSM <= TTST_IDLE;

else

TTSTSM <= TTSTSMNXT;

end

always @(posedge CLK1MHZ or negedge RESET)

begin

if(~RESET)

IS_CONVERT <= 1'b1;

else if(PHASE_TTST_IDLE)

IS_CONVERT <= 1'b1;

else if(PHASE_TTST_WOVER)

IS_CONVERT <= 1'b0;

else

IS_CONVERT <= IS_CONVERT;

end

always @(TTSTSM or TEST_EN or RST_OVER or IS_CONVERT or WBD_OVER or RD_BIT_DATA or PHASE_RD_OVER or PHASE_RD_OVER or BYTE_READ_OVER or PHASENXT_RDSPAD_IDLE ) begin

case(TTSTSM)

TTST_IDLE:

if(TEST_EN)

TTSTSMNXT = TTST_RST;

else

TTSTSMNXT = TTST_IDLE;

TTST_RST:

if(RST_OVER)

TTSTSMNXT = TTST_SKPROM;

else

TTSTSMNXT = TTST_RST;

TTST_SKPROM:

if(WBD_OVER)

if(IS_CONVERT)

TTSTSMNXT = TTST_CONVERT;

else

TTSTSMNXT = TTST_GETDATA;

else

TTSTSMNXT = TTST_SKPROM;

TTST_CONVERT:

if(WBD_OVER)

TTSTSMNXT = TTST_WOVER;

else

TTSTSMNXT = TTST_CONVERT;

TTST_WOVER:

if(RD_BIT_DATA & PHASE_RD_OVER)

TTSTSMNXT = TTST_RST;

else

TTSTSMNXT = TTST_WOVER;

TTST_GETDATA:

if(BYTE_READ_OVER & PHASENXT_RDSPAD_IDLE )

TTSTSMNXT = TTST_IDLE;

else

TTSTSMNXT = TTST_GETDATA;

default:

TTSTSMNXT = TTST_IDLE;

endcase

end

assign WD_DATA_OUT = PHASE_TTST_SKPROM ? 8'hcc : (PHASE_TTST_CONVERT ? 8'h44 : ( PHASE_RDSPAD_CMD ? 8'hbe : 8'h00) );

四,DQ总线的控制

1-Wire总线只有一根信号线,是双向的,带上拉电阻的。在FPGA中做DQ的逻辑如下,至于这么做的原因,不再做叙述。当弄懂了1-Wire总线的规范和DS18B20的基本操作的话,很容易就理解了。

wire DQ, DQ_OUT, DQ_IN, DQ_OUT_EN;

assign DQ = DQ_OUT_EN ? DQ_OUT : 1'bz;

assign DQ_IN = DQ;

wire RD_DQ_OUT = ~PHASE_RD_MPL;

wire RD_DQ_OUT_EN = PHASE_RD_MPL ;

wire WD_DQ_OUT = 1’b0;

wire WD_DQ_OUT_EN = PHASE_WD_MPL | (~WD_BIT_DATA & PHASE_WD_MOUT);

wire DQ_RST_OUT = ~ PHASE_RST_MINIT;

wire DQ_RST_EN = PHASE_RST_MINIT;

assign DQ_OUT = RD_DQ_OUT & RD_DQ_OUT_EN | WD_DQ_OUT & WD_DQ_OUT_EN | DQ_RST_OUT & DQ_RST_EN;

assign DQ_OUT_EN = RD_DQ_OUT_EN | WD_DQ_OUT_EN | DQ_RST_EN;

1

0

阅读 (1128)   评论  (3) 收藏 (2)  转载 (5)   喜欢   打印 举报
已投稿到:
 排行榜
前一篇: 基于FPGA的DS18B20控制程序设计及其Verilog实现(二)
后一篇: 一种简单的频率测试方法及Verilog实现
评论  重要提示:警惕虚假中奖信息
[ 发评论]
  • 2532930441

    谢谢博主,如果既要用到Verilog,又要用到基于NIOS II的DS18B20开发,请问该如何做呢?

    2012-6-20  00:42回复(1)

  • 2210167493

    楼主你好,我也是FPGA设计爱好者,最近我也在做DS18B20的相关控制,同时也参考你的程序,写了我的程序,但是通过示波器看到不能正常初始化,请您帮我看看程序,指出我的错误,程序如下,麻烦您了

    module temp(clk,reset,rs_en,dq,led);
     input clk,reset,rs_en;
     inout dq;
     output led;
     wire dq_in

    2012-12-27  21:06

你可能感兴趣的:(fpga)