【学习笔记】DS18B20

        DS18B20 是单总线数字温度传感器,其可直接将温度 转化成数字信号输出,具有体积小、低功耗、抗干扰能力强、精度高等优点。

        同红外遥控,时间有点远。不再给出数码管显示模块代码,只是给出DS18B20代码。

状态机:

 

 

 

 DS18B20模块:

 

 

 

 

 代码:

module DS18B20	(
	input	wire	clk_sys		,
	input	wire	rst_n_sys	,
	
	inout	wire	dq				,
	
	output	reg	[19:0]data	,
	output	reg	sign			
);

parameter	INIT			=6'B000_001		,
				WR_CMD		=6'B000_010		,
				WAIT			=6'B000_100		,
				INIT_AGAIN	=6'B001_000		,
				RD_CMD		=6'B010_000		,
				RD_TEMP		=6'B100_000		;

parameter	INIT_CNT		=20'D999			,
				WAIT_CNT		=20'D750_000	,
				CMD_CNT		=20'D64			,
				CMD_CNT_GET	=20'D30			,
				TEMP_CNT_GET=20'D13			;
				
parameter	CNT_BIT_CMD_MAX	=4'd15			,
				CNT_BIT_TEMP_MAX	=4'D15		;

parameter	WR_44_CC		=16'H44_CC	,
				RD_BE_CC		=16'HBE_CC	;


	reg	us_clk				;
	reg	[4:0]cnt_us			;

	reg	[5:0]state			;
	reg	[19:0]cnt_state	;
	reg	[3:0]cnt_bit		;
	reg	flag_init			;
	reg	[15:0]temp			;
	reg	[11:0]reg_date		;
	reg	dq_en					;
	reg	dq_out				;
	
assign	dq= (dq_en==1'b1)?dq_out:1'bz	;	
	
	

always@(posedge clk_sys or negedge rst_n_sys)
	if(!rst_n_sys)
		cnt_us<=5'b0			;
	else	if (cnt_us==5'd24)
		cnt_us<=5'b0			;
	else	
		cnt_us<=cnt_us+1'b1	;
	
always@(posedge clk_sys or negedge	rst_n_sys)
	if(!rst_n_sys)
		us_clk<=1'b0			;
	else	if(cnt_us==5'd24)
		us_clk<=~us_clk		;
	else
		us_clk<=us_clk			;
		
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		state	<=	INIT	;
	else	
		case(state)
			INIT:
				if (flag_init==1'b1  && cnt_state==INIT_CNT)
					state<=WR_CMD		;
				else
					state<=state		;
			WR_CMD:
				if (cnt_bit==CNT_BIT_CMD_MAX && cnt_state==CMD_CNT)
					state<=WAIT			;
				else		
					state<=state		;
			WAIT:
				if	(cnt_state==WAIT_CNT)
					state<=INIT_AGAIN	;
				else
					state<=state		;
			INIT_AGAIN:
				if (flag_init==1'b1  && cnt_state==INIT_CNT)
					state<=RD_CMD		;
				else
					state<=state		;
			RD_CMD:
				if (cnt_bit==CNT_BIT_CMD_MAX && cnt_state==CMD_CNT )
					state<=RD_TEMP		;
				else		
					state<=state		;
			RD_TEMP:
				if(cnt_bit==CNT_BIT_TEMP_MAX && cnt_state==CMD_CNT)
					state<=INIT			;
				else
					state<=state		;
			default:	state<=INIT		;
			endcase
			
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		begin
		dq_out<=1'b0	;
		dq_en	<=1'b0	;
		end
	else	
		case(state)
			INIT:
				if(cnt_state<=20'd500)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
				else 
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
			WR_CMD:
				if(WR_44_CC[cnt_bit]==1'b0)
					if(cnt_state>=20'd63)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
					else
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
				else if(WR_44_CC[cnt_bit]==1'b1)
					if(cnt_state>=20'd2)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
					else
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
			WAIT:
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b1		;
					end
			INIT_AGAIN:
					if(cnt_state<=20'd500)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
				else 
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
			RD_CMD:
				if(RD_BE_CC[cnt_bit]==1'b0)
					if(cnt_state>=20'd63)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
					else
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
				else if(WR_44_CC[cnt_bit]==1'b1)
					if(cnt_state>=20'd2)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
					else
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
			RD_TEMP:
				if(cnt_state<=1)
					begin
					dq_en	<=1'b1		;
					dq_out<=1'b0		;
					end
				else	
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
			default:	
					begin
					dq_en	<=1'b0		;
					dq_out<=1'b0		;
					end
		endcase
		
		
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		cnt_state<=20'd0				;
	else	if (((state==RD_TEMP || state==WR_CMD ||state==RD_CMD)&&cnt_state==CMD_CNT)||
			((state==INIT || state==INIT_AGAIN) && cnt_state==INIT_CNT)||
			(state==WAIT && cnt_state==WAIT_CNT))
		cnt_state<=20'd0				;
	else	
		cnt_state<=cnt_state+1'b1	;
		
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		flag_init<=1'b0					;
	else if(state==INIT_AGAIN || state==INIT )
		if(cnt_state==20'd600 && dq==1'b0)
			flag_init<=1'b1				;
		else
			flag_init<=flag_init			;
	else
		flag_init	<=1'b0				;
		
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		cnt_bit<=4'd0				;
	else if((((state==WR_CMD ||state==RD_CMD )&& cnt_bit==CNT_BIT_CMD_MAX ) ||
				(state==RD_TEMP && cnt_bit==CNT_BIT_TEMP_MAX))&& cnt_state==CMD_CNT)
		cnt_bit<=4'd0				;
	else	if(state==RD_TEMP || state==WR_CMD ||state==RD_CMD)
		cnt_bit<=cnt_bit+1'b1	;
	else	
		cnt_bit<=4'b0				;
		
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		temp<=1'b0				;
	else	if(state==RD_TEMP && cnt_state==TEMP_CNT_GET)
		temp[cnt_bit]<=dq		;
	else
		temp<=temp				;

always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		begin
		reg_date	<=12'd0					;
		sign		<=1'b0					;
		end
	else	if(state==RD_TEMP && cnt_bit==CNT_BIT_TEMP_MAX && cnt_state==20'd60)
		if (temp[15]==1'b0)
			begin
			reg_date	<=temp[11:0]		;
			sign		<=1'b0				;
			end
		else 
			begin
			reg_date	<=~temp[11:0]+1'b1	;
			sign		<=1'b1					;
			end
	else
		begin
		reg_date	<=reg_date					;
		sign		<=sign						;
		end
		
always@(posedge us_clk or negedge rst_n_sys)
	if(!rst_n_sys)
		data<=19'd0									;		
	else 
		data<=(temp[11:0]*10'd625)/4'd10		;
		

		
		
endmodule
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值