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

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

基于FPGA的DS18B20控制程序设计及其Verilog实现一,总体介绍DS18B20是一个1-wire总线,12bit的数字温度传感器,其详细的参数这里不做具体的介绍,只讨论其基于Verilog的控制程序的设计。实际上,对DS18B20的控制,主要是实现1-wire总线的初始化,读,写等操作,然后再根据DS18B20的控制要求,实现对其控制的verilog逻辑。在1-Wire总线上,有一个master,可以有1个或者多个slave。而对于FPGA+DS18B20的温度测试设计来讲,需要在FPGA上实现一个1-Wire总线的master。DS18B20作为1-wire总线的slave设备存在,可以有一个或者多个,不过为了简化程序,例程里假定只存在一个DS18B2020。1-Wire总线的操作形式上相对简单,但操作本身相对却又比较复杂。用Verilog做控制程序设计时,可以采用多层次嵌套的状态机来实现。二,FPGA+DS18B20的硬件设计硬件的设计非常简单,只需要将DS18B20的DQ与FPGA的一个IO连接,并加4.7K左右的上拉电阻就可以了。VDD和VPU可以为3.0~5.0V。这里我们参照FPGA本身的IO电压,选择3.3V。另外要注意的一点是,由于DQ的数据是双向的,所以FPGA的该IO要设定为inout类型。三,1-Wire总线的基本操作及Verilog实现。根据1-Wire总线的特点,可以把1-Wire总线的操作归结为初始化,单bit读操作,单bit写操作等最基础的几种。下面分别是几种基本操作的介绍和verilog实现。由于DS18B20的时序操作的最小单位基本上是1us,所以在该设计中,全部采用1MHz的时钟。1.初始化初始化实际上就是1-wire总线上的Reset操作。由master发出一定长度的初始化信号。Slave看到该初始化信号后,在一定时间内发出规定长度的响应信号,然后初始化操作就结束了。下图是DS18B20的datasheet上给出的初始化的时序要求图示。我们用一个简单的状态机来实现对DS18B20初始化的操作。根据初始化的时序要求,设计一个有3个状态的简单的状态机,这三个状态分别是RST_IDLE,RST_MINIT和RST_SINIT。系统初始化时,处于RST_IDLE状态,当RST_EN信号有效时,进入RST_MINIT状态,由master发出初始化信号。当master的初始化信号发出一定时间以后,直接进入RST_SINIT状态。在RST_SINIT状态时,master去观察slave是否输出了正确的状态:如果slave没有输出正确的状态,则状态机重新回到RST_MINIT状态,由master重新发出初始化信号;如果slave输出了正确的状态,则意味着初始化正确完成,状态机回到RST_IDLE状态,整个初始化过程完成(这个文章里涉及到比较多的状态机,但状态机的转换都很简单,所以不会给出状态机的状态转换图,仅仅会用文字做简单叙述,有疑问的地方,可以仔细阅读相关代码)。wireRST_EN;wireRST_OVER;parameterRST_IDLE=3'b001,//IDLE状态RST_MINIT=3'b010,//master初始化操作RST_SINIT=3'b100;//slave初始化应答reg[2:0]RSTSM,RSTSMNXT;wirePHASE_RST_IDLE=RSTSM[0];wirePHASE_RST_MINIT=RSTSM[1];wirePHASE_RST_SINIT=RSTSM[2];wirePHASENXT_RST_IDLE=RSTSMNXT[0];always@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)RSTSM=RST_IDLE;elseRSTSM=RSTSMNXT;endreg[9:0]MASTER_CNT;//用来控制master发出初始化信号的长度always@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)MASTER_CNT=10'b0;elseif(~PHASE_RST_MINIT)MASTER_CNT=10'b0;elseMASTER_CNT=MASTER_CNT+10'b1;endreg[9:0]SLAVE_CNT;//用来判断slave是否在恰当时间返回初始化结束的信号always@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)SLAVE_CNT=10'b0;elseif(~PHASE_RST_SINIT)SLAVE_CNT=10'b0;elseSLAVE_CNT=SLAVE_CNT+10'b1;endregSLAVE_IS_INIT;//采集并保存slave发出的初始化结束信号always@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)SLAVE_IS_INIT=1'b1;elseif(SLAVE_CNT==10'd70)SLAVE_IS_INIT=DQ_IN;elseif(PHASE_RST_MINIT)SLAVE_IS_INIT=1'b1;elseSLAVE_IS_INIT=SLAVE_IS_INIT;endalways@(RSTSMorRST_ENorMASTER_CNTorSLAVE_CNTorSLAVE_IS_INIT)begincase(RSTSM)RST_IDLE:if(RST_EN)RSTSMNXT=RST_MINIT;elseRSTSMNXT=RST_IDLE;RST_MINIT:if(MASTER_CNT==10'd500)RSTSMNXT=RST_SINIT;elseRSTSMNXT=RST_MINIT;RST_SINIT:if((SLAVE_CNT==10'd500)&~SLAVE_IS_INIT)RSTSMNXT=RST_IDLE;elseif((SLAVE_CNT==10'd500)&SLAVE_IS_INIT)RSTSMNXT=RST_MINIT;elseRSTSMNXT=RST_SINIT;default:RSTSMNXT=RST_IDLE;endcaseendassignRST_OVER=PHASE_RST_SINIT&PHASENXT_RST_IDLE;//初始化完成标志信号下图是用示波器抓出的初始化过程DQ信号的波形(红色)。2.单bit读操作在1-wire总线上,读数据的操作实际上是按bit来完成的。每次master可以从slave读回一个bit的数据。读回的数据可能是1或者0。下图是DS18B20的datasheet上给出的单bit读操作的时序要求图示。需要注意的是,对于master来讲,无论读回来的数据是1还是0,其本身的操作及时序都是一样的,没有差异。仍然用一个简单的状态机来实现对DS18B20的单bit读操作。设计一个有5个状态的简单的状态机,这五个状态分别是RD_IDLE,RD_MPL,RD_MSAP,RD_WAIT和RD_OVER。系统初始化时,处于RD_IDLE状态,当RDBEGIN信号有效时,进入RD_MPL状态,由master发出读信号。3us以后,进入RD_MSAP状态(master在该状态结束的前一个us读取DQ上的值作为读bit的结果),在11us以后,进入RD_WAIT状态,而在读bit开始后的59us,系统进入RD_OVER状态,意味着读bit操作结束。RD_OVER状态是为了符合1-Wire总线的操作规范(在每个操作之间至少有1us的总线空闲时间)而存在的。wireRDBEGIN;parameterRD_IDLE=5'b00001,//resisterpullup,largerthan1usRD_MPL=5'b00010,//masterpulllow,largerthan1usRD_MSAP=5'b00100,//ds18b20pulllow(read0)orresisterpullup(read1),mastersampledata,near15usRD_WAIT=5'b01000,//ds18b20pulllow(read0)orresisterpullup(read1)RD_OVER=5'b10000;//resisterpullup,largerthan1usreg[4:0]RDSM,RDSMNXT;wirePHASE_RD_IDLE=RDSM[0];wirePHASE_RD_MPL=RDSM[1];wirePHASE_RD_MSAP=RDSM[2];wirePHASE_RD_OVER=RDSM[4];reg[5:0]RD_CNT;always@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)RD_CNT=6'b0;elseif(~PHASE_RD_IDLE)RD_CNT=RD_CNT+6'b1;elseRD_CNT=6'b0;endalways@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)RDSM=RD_IDLE;elseRDSM=RDSMNXT;endalways@(RDSMorRDBEGINorRD_CNT)begincase(RDSM)RD_IDLE:if(RDBEGIN)RDSMNXT=RD_MPL;elseRDSMNXT=RD_IDLE;RD_MPL:if(RD_CNT==6'd3)RDSMNXT=RD_MSAP;elseRDSMNXT=RD_MPL;RD_MSAP:if(RD_CNT==6'd14)RDSMNXT=RD_WAIT;elseRDSMNXT=RD_MSAP;RD_WAIT:if(RD_CNT==6'd59)RDSMNXT=RD_OVER;elseRDSMNXT=RD_WAIT;RD_OVER:if(RD_CNT==6'd61)RDSMNXT=RD_IDLE;elseRDSMNXT=RD_OVER;default:RDSMNXT=RD_IDLE;endcaseendregRD_BIT_DATA;//读bit操作获得的数据always@(posedgeCLK1MHZornegedgeRESET)beginif(~RESET)RD_BIT_DATA=1'b0;elseif(PHASE_RD_MSAP&(RD_CNT==6'd13))RD_BIT_DATA=DQ;elseif(PHASE_RD_IDLE)RD_BIT_DATA=1'b0;elseRD_BIT_DATA=RD_BIT_DATA;end3.单bit写操作在1-Wire总线上,写数据的操作也是按bit来完成的。每次master可以向slave写入一个bit的数据。写数据可能是1或者0。下图是DS18B20的datasheet上给出的单bit写操作的时序要求图示:需要注意的是,对于master来讲,写数据不同的时候(1或者0),其本身的操作及时序是有差别的。对DS18B20的单bit写操作可以用一个有4个状态的简单的状态机来实现。这三个状态分别是WD_IDLE,WD_MPL,WD_OUT,和RD_OVER。系统初始化时,处于WD_IDLE状态,当WDBEGIN信号有效时,进入WD_MPL状态,由master发出写信号。9us以后,进入WD_MOUT状态(master将要写到slave的数据放到DQ上),而在写bit开始后的59us,系统进入RD_OVER状态,意味着写bit操作结束。WD_OVER状态是为了符合1-Wire总线的操作规范(在每个操作之间至少有1us的总线空闲时间)而存在的。wireWDBEGIN;//单bit写操作开始信号wireWD_DATA_OUT;//要写入到slave的值parameterWD_IDLE=4'b0001,//resisterpull

1 / 9
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功