US100超声波测距模块的FPGA驱动

一、说明书摘要

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

驱动时序说明:

串口模式的时序很简单,向US100发送一帧0x55的数据即为测距,发送0x50即为测温,测距US100会返回2帧8位数据,分两次发送回来,第一帧为距离高8位,第二帧是距离低8位。测温US100只返回一帧数据。

Verilog代码

串口发送模块

//作者:杨成煜
//日期:2020/4/7
//`define SIM
module	uart_tx(
	//system signals
	input			sclk,
	input			s_rst_n,
	//Uart_Interface
	output	reg		rs232_tx,
	//others
	input			tx_trig,
	input	[7:0]	tx_data,
	output			tx_byte_done
);
//=================================================
//**********define parameters and internal signals*
//=================================================
`ifndef SIM
localparam	BAUD_END=5207;
`else
localparam	BAUD_END=56;
`endif
localparam	BAUD_M=BAUD_END/2-1;
localparam	BIT_END=8;

reg	[7:0]	tx_data_r;
reg			tx_flag;
reg	[12:0]	baud_cnt;
reg			bit_flag;
reg	[3:0]	bit_cnt;
//=================================================
//**********main code*******************
//=================================================
//tx_byte_done
assign tx_byte_done = (bit_cnt==BIT_END&&bit_flag==1'b1)?1'b1:1'b0;
//tx_data_r
always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		tx_data_r <= 'd0;
	else if(tx_trig==1'b1 && tx_flag==1'b0)
		tx_data_r <= tx_data;		
end
//tx_flag
always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		tx_flag <= 1'b0;
	else if(tx_trig==1'b1)
		tx_flag <= 1'b1;
	else if(bit_cnt==BIT_END && bit_flag==1'b1)
		tx_flag <= 1'b0;
end

//baud_cnt
always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		baud_cnt <= 'd0;
	else if(baud_cnt==BAUD_END)
		baud_cnt <= 'd0;
	else if(tx_flag==1'b1)
		baud_cnt <= baud_cnt + 1'b1;
	else
		baud_cnt <= 'd0;
end

//bit_flag
always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		bit_flag <= 1'b0;
	else if(baud_cnt==BAUD_END)
		bit_flag <= 1'b1;
	else
		bit_flag <= 1'b0;
end

//bit_cnt
always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		bit_cnt <= 'd0;
	else if(bit_flag==1'b1 && bit_cnt==BIT_END)
		bit_cnt <= 'd0;
	else if(bit_flag==1'b1)
		bit_cnt <= bit_cnt + 1'b1;
end

//rs232_tx
always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		rs232_tx <= 1'b1;
	else if(tx_flag==1'b1)
		case(bit_cnt)
			0:rs232_tx <= 1'b0;//start_bit
			1:rs232_tx <= tx_data_r[0];
			2:rs232_tx <= tx_data_r[1];
			3:rs232_tx <= tx_data_r[2];
			4:rs232_tx <= tx_data_r[3];
			5:rs232_tx <= tx_data_r[4];
			6:rs232_tx <= tx_data_r[5];
			7:rs232_tx <= tx_data_r[6];
			8:rs232_tx <= tx_data_r[7];
			default:rs232_tx <= 1'b1;
		endcase
	else
		rs232_tx <= 1'b1;
end
endmodule

串口接收模块

//作者:杨成煜
//日期:2020/4/7
//`define SIM
module uart_rx(
	//system signals
	input				sclk,
	input				s_rst_n,
	//uart interface
	input				rs232_rx,
	//others
	output	reg	[7:0]	rx_data,
	output	reg			po_flag
);

//=================================================
//**********define parameters and internal signals*
//=================================================
`ifndef SIM
localparam	BAUD_END=5207;
`else
localparam	BAUD_END=56;
`endif
localparam	BAUD_M=BAUD_END/2-1;
localparam	BIT_END=8;

reg			rx_r1;
reg 		rx_r2;
reg 		rx_r3;
reg			rx_flag;
reg[12:0]	baud_cnt;
reg			bit_flag;
reg[3:0]	bit_cnt;

wire		rx_neg;
//=================================================
//**********main code*******************
//=================================================
assign		rx_neg = (rx_r3)&(~rx_r2);

always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n == 1'b0)
		baud_cnt <= 'd0;
	else if(baud_cnt == BAUD_END)
		baud_cnt <= 'd0;
	else if(rx_flag == 1'b1)
		baud_cnt <= baud_cnt + 1'b1;
	else
		baud_cnt <= 'd0;
end

always	@(posedge sclk)begin
	rx_r1 <= rs232_rx;
	rx_r2 <= rx_r1;
	rx_r3 <= rx_r2;
end

always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		rx_flag <= 1'b0;
	else if(rx_neg==1'b1)
		rx_flag <= 1'b1;
	else if(bit_cnt=='d0 && baud_cnt==BAUD_END)
		rx_flag <= 1'b0;
end

always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		bit_flag <= 1'b0;
	else if(baud_cnt==BAUD_M)
		bit_flag <= 1'b1;
	else
		bit_flag <= 1'b0;
end

always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		bit_cnt <= 'd0;
	else if(bit_cnt == BIT_END && bit_flag == 1'b1)
		bit_cnt <= 'd0;
	else if(bit_flag == 1'b1)
		bit_cnt <= bit_cnt + 1'b1;
end

always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		rx_data <= 'd0;
	else if(bit_flag==1'b1 && bit_cnt>='d1)
		rx_data <= {rx_r2,rx_data[7:1]};
end

always	@(posedge sclk or negedge s_rst_n)begin
	if(s_rst_n==1'b0)
		po_flag <= 1'b0;
	else if(bit_cnt == BIT_END && bit_flag == 1'b1)
		po_flag <= 1'b1;
	else
		po_flag <= 1'b0;
end
endmodule

命令裁决模块

//作者:杨成煜
//日期:2020/4/7
//==================defines=====================
`define SIM
module	arbit(
	//================System Signal================
	input	clk,
	input	rst_n,
	//================Interface====================
	input	get_dis_req,
	input	get_temp_req,
	output reg[7:0]	cmd,
	output	trig_get_dis_req,
	output	trig_get_temp_req
);
	//================parameters===================
	`ifndef SIM
	
	`else
	
	`endif
	//================System regs==================
	reg get_dis_req_t0;
	reg get_dis_req_t1;
	reg get_temp_req_t0;
	reg get_temp_req_t1;
	
	//================Main Codes===================
	always	@(posedge clk)begin
		get_dis_req_t0 <= get_dis_req;
		get_dis_req_t1 <= get_dis_req_t0;
		get_temp_req_t0 <= get_temp_req;
		get_temp_req_t1 <= get_dis_req_t0;
	end
	assign trig_get_dis_req = get_dis_req_t0&(~get_dis_req_t1);
	assign trig_get_temp_req = get_temp_req_t0&(~get_dis_req_t1);
	
	always	@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)
			cmd <= 'd0;
		else if(trig_get_dis_req==1'b1)
			cmd <= 8'h55;
		else if(trig_get_temp_req==1'b1)
			cmd <= 8'h50;
	end	
endmodule

顶层模块

//作者:杨成煜
//日期:2020/4/7
//==================defines=====================
`define SIM
`define UART_MOD
module	US100(
	//================System Signal================
	input				clk,
	input				rst_n,
	//================Interface====================
	input				rx,//link to us100 tx
	output				tx,//link to us100 rx
	input				get_dis_req,
	input				get_temp_req,
	output reg[15:0]	distance,
	output reg[7:0]		temprature
);
	//================parameters===================
	`ifndef SIM
	
	`else
	
	`endif
	localparam			S_IDLE			=5'b00001;
	localparam			S_GET_DIS		=5'b00010;
	localparam			S_GET_TEMP		=5'b00100;

	//================System reg===================


	reg[4:0]			state;
	wire[7:0]			cmd;
	wire				trig_get_dis_req;
	wire				trig_get_temp_req;
	wire[7:0]			rx_data;
	wire				flag_data_get;
	reg					cnt_dis_byte;
	wire				tx_req;


	//================Main code====================
	
	//cnt_dis_byte
	always	@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)
			cnt_dis_byte <= 1'b0;
		else if(state==S_GET_DIS&&cnt_dis_byte==1'b1&&flag_data_get==1'b1)
			cnt_dis_byte <= 1'b0;
		else if(state==S_GET_DIS&&flag_data_get==1'b1)
			cnt_dis_byte <= 1'b1;
		else
			cnt_dis_byte <= 1'b0;
	end
	
	assign		tx_req = trig_get_dis_req|trig_get_temp_req;
	always	@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)
			state <= S_IDLE;
		else case(state)
			S_IDLE:begin
				if(trig_get_dis_req==1'b1)
					state <= S_GET_DIS;
				else if(trig_get_temp_req==1'b1)
					state <= S_GET_TEMP;
				else
					state <= S_IDLE;
			end
			S_GET_DIS:begin
				if(flag_data_get==1'b1&&cnt_dis_byte==1'b1)
					state <= S_IDLE;
				else
					state <= S_GET_DIS;
			end
			S_GET_TEMP:begin
				if(flag_data_get==1'b1)
					state <= S_IDLE;
				else
					state <= S_GET_TEMP;
			end
			default:state <= S_IDLE;
		endcase
	end
	//distance
	always	@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)
			distance <= 'd0;
		else if(state==S_GET_DIS&&flag_data_get==1'b1)
			distance <= {distance[7:0],rx_data};
	end
	//temprature
	always	@(posedge clk or negedge rst_n)begin
		if(rst_n==1'b0)
			temprature <= 'd0;
		else if(state==S_GET_TEMP&&flag_data_get==1'b1)
			temprature <= rx_data;
	end
		
arbit arbit_inst(
	//================System Signal================
	.clk				(clk),
	.rst_n				(rst_n),
	//================Interface====================
	.get_dis_req		(get_dis_req),
	.get_temp_req		(get_temp_req),
	.cmd				(cmd),
	.trig_get_dis_req	(trig_get_dis_req),
	.trig_get_temp_req	(trig_get_temp_req)
);

uart_rx us100_uart_rx_inst(
	//system signals
	.sclk			(clk),
	.s_rst_n		(rst_n),
	//uart interface
	.rs232_rx		(rx),
	//others
	.rx_data		(rx_data),
	.po_flag		(flag_data_get)
);

uart_tx us100_uart_tx_inst(
	//system signals
	.sclk			(clk),
	.s_rst_n		(rst_n),
	//Uart_Interface
	.rs232_tx		(tx),
	//others
	.tx_trig		(tx_req),
	.tx_data		(cmd),
	.tx_byte_done	()
);
endmodule

发布了18 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43650722/article/details/105373237
今日推荐