//-------------------
//18B20驱动程序 by zmz
// 2008.4.19
//-------------------
//宏定义
`define ON 1'b1
`define OFF 1'b0
module ds1820(clk_48M,DQ,DATA,DATA_READY,cap_clk);
input cap_clk;//系统时钟和采样时钟
inout DQ;
output DATA_READY;//输出
output[15:0] DATA;
input clk_48M;
reg LinkBusSwitch;//总线开关
reg outbuf;
reg DATA_READY;
reg [15:0] DATA;
reg Mesure_Ready=1'b0,Convert_Over=1'b0,Init_Ready=1'b0,Read_Ready=1'b0,Read_OK=1'b0,Next=1'b0;//状态标识
integer i=0,i0=0,i1=0,i2=0,i3=0,i4=0,ii=0;
assign DQ=(LinkBusSwitch===`ON)?outbuf:1'bz;
assign inbuf=(LinkBusSwitch===`OFF)?DQ:1'bz;
always @(posedge cap_clk)
begin
if(clk_48M)
i=i+1;
else begin
i=0;
Mesure_Ready=1'b0;
Convert_Over=1'b0;
DATA_READY=1'b0;
Read_OK=1'b0;
Next=1'b0;
Init_Ready=1'b0;
Read_Ready=1'b0;
end
//--------------------------------------------
//初始化程序段
//--------------------------------------------
if((i>=10)&&(i<=24000))//40M晶振对应600us复位脉冲
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i>24000)&&(i<24005))//释放总线
LinkBusSwitch=`OFF;
if((i>=26400)&&(i<=36000))//240us检测存在脉冲
begin
if(inbuf===1'b0)//存在脉冲
Init_Ready=1'b1;
end
//--------------------------------------------
//初始化结束,发Skip_Rom命令CCH-1100——1100
//--------------------------------------------
if((Init_Ready===1'b1)&&(i>36000))
i0=i0+1;
else i0=0;
if((i0>=5)&&(i0<=400))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>400)&&(i0<3200))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i0>=3200)&&(i0<3400))//5us恢复时间
LinkBusSwitch=`OFF;
if((i0>=3400)&&(i0<=3800))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>3800)&&(i0<6600))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i0>=6600)&&(i0<6800))//5us恢复时间
LinkBusSwitch=`OFF;
if((i0>=6800)&&(i0<=7200))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>7200)&&(i0<10000))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=1;
end
if((i0>=10000)&&(i0<10200))//5us恢复时间
LinkBusSwitch=`OFF;
if((i0>=10200)&&(i0<=10600))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>10600)&&(i0<13400))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=1;
end
if((i0>=13400)&&(i0<13600))//5us恢复时间
LinkBusSwitch=`OFF;
if((i0>=13600)&&(i0<=14000))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>14000)&&(i0<16800))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i0>=16800)&&(i0<17000))//恢复时间
LinkBusSwitch=`OFF;
if((i0>=17000)&&(i0<=17400))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>17400)&&(i0<20200))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i0>=20200)&&(i0<20400))//5us恢复时间
LinkBusSwitch=`OFF;
if((i0>=20400)&&(i0<=20800))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>20800)&&(i0<23600))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=1;
end
if((i0>=23600)&&(i0<23800))//5us恢复时间
LinkBusSwitch=`OFF;
if((i0>=23800)&&(i0<=24200))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i0>24200)&&(i0<27000))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=1;
end
if(i0===27001)
LinkBusSwitch=`OFF;
if((i0>27050))
begin
Mesure_Ready=1'b1;
end
//--------------------------------------------
//Skip_Rom命令结束,测温开始
//--------------------------------------------
if((Mesure_Ready===1'b1))
i1=i1+1;
else i1=0;
//写Convert_T指令44h-0100_0100
if((i1>=5)&&(i1<=400))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>400)&&(i1<3200))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i1>=3200)&&(i1<3400))//5us恢复时间
LinkBusSwitch=`OFF;
if((i1>=3400)&&(i1<=3800))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>3800)&&(i1<6600))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i1>=6600)&&(i1<6800))//5us恢复时间
LinkBusSwitch=`OFF;
if((i1>=6800)&&(i1<=7200))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>7200)&&(i1<10000))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=1;
end
if((i1>=10000)&&(i1<10200))//5us恢复时间
LinkBusSwitch=`OFF;
if((i1>=10200)&&(i1<=10600))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>10600)&&(i1<13400))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i1>=13400)&&(i1<13600))//5us恢复时间
LinkBusSwitch=`OFF;
if((i1>=13600)&&(i1<=14000))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>14000)&&(i1<16800))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i1>=16800)&&(i1<17000))//恢复时间
LinkBusSwitch=`OFF;
if((i1>=17000)&&(i1<=17400))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>17400)&&(i1<20200))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i1>=20200)&&(i1<20400))//5us恢复时间
LinkBusSwitch=`OFF;
if((i1>=20400)&&(i1<=20800))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>20800)&&(i1<23600))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=1;
end
if((i1>=23600)&&(i1<23800))//5us恢复时间
LinkBusSwitch=`OFF;
if((i1>=23800)&&(i1<=24200))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i1>24200)&&(i1<27000))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i1>27000)&&(i1<27010))//释放总线
LinkBusSwitch=`OFF;
//Convert_T命令写完,等待1820工作
if((i1>=20027000))//500ms
begin
Convert_Over=1'b1;
end
if(Convert_Over===1'b1)//转换完成,复位
ii=ii+1;
else ii=0;
if((ii>=10)&&(ii<=24000))//40M晶振对应600us复位脉冲
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((ii>24000)&&(ii<24005))//释放总线
LinkBusSwitch=`OFF;
if((ii>=26400)&&(ii<=36000))//240us
begin
if(inbuf===1'b0)
Next=1'b1;
end
if((Next===1'b1)&&(ii>36000))
i4=i4+1;
else i4=0;
//--------------------------------------------
//复位结束,发Skip_Rom命令
//--------------------------------------------
if((i4>=5)&&(i4<=400))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i4>400)&&(i4<3200))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i4>=3200)&&(i4<3400))//5us恢复时间
LinkBusSwitch=`OFF;
if((i4>=3400)&&(i4<=3800))//10us写时间隙
begin
LinkBusSwitch=`ON;
outbuf=1'b0;
end
if((i4>3800)&&(i4<6600))//70us写数据
begin
LinkBusSwitch=`ON;
outbuf=0;
end
if((i4>=6600)&&(i4<6800))//5us恢复时间
&n