一、说明书摘要
驱动时序说明:
串口模式的时序很简单,向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