使用串口发送5个字节(40位)数据到电脑
- ADC采样的结果是12位的,怎么使用串口发送
- 16位数据,怎么通过串口发生
- 有多个字节的数据通过串口发送
UART就是规定了,发送的数据位 只能有6,7,8
12位的数据,就是4位+8位,比如想发生12位的数据
uart_tx_data.v
module uart_tx_data (
clk,
reset,
data40,
trans_go,
uart_tx,
trans_done
);
input clk;
input reset;
input [39:0]data40;
input trans_go;
ouput uart_tx;
uart_byte_tx_uart_byte_tx(
.clk(clk),
.reset(reset),
.data(data),
.send_en(send_go),
.baud_set(baud_set),
.uart_tx(uart_tx),
.tx_done(tx_done)
);
两种情况:
- 没有开始发送(上一次的发送以及完成,新的40位数据的发送的请求没有出现)
- 来了发送40位数据的请求信号
- 依次发送数据的状态
**第一个状态:**第一种情况的时候,我们干什么事情呢?等待传输请求(trans_go)的到来,
data40[7:0] 给到 uart_byte_tx 的data,并同时产生 send_go 信号,启动第一个字节的发送
接着应该等待,等待tx_done 信号的到来
1. 40位的数据是否发完了?发完了?回到第一个状态继续等待 trans_go ,没发完,启动下一个8位数据的发送
状态机的概念:
module uart_tx_data (
clk,
reset,
data40,
trans_go,
uart_tx,
trans_done
);
input clk;
input reset;
input [39:0]data40;
input trans_go;
ouput uart_tx;
ouput reg c;
reg [7:0]data;
reg send_go;
wire tx_done;
uart_byte_tx_uart_byte_tx(
.clk(clk),
.reset(reset),
.data(data),
.send_en(send_go),
.baud_set(baud_set),
.uart_tx(uart_tx),
.tx_done(tx_done)
);
reg [2:0]state;
always@(posedge clk or negedge reset)
if(!reset) begin
state <= 0;
data <= 0;
send_go <= 0;
trans_done <= 0;
end
else if (state == 0) begin
trans_done <= 0;
if(trans_go) begin
data <= data40[7:0];
send_go <= 1;
state <= 1;
end
else begin
data <= data;
send_go <= 0;
state <= 0;
end
end
else if(state == 1)begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[15:8];
send_go <= 1;
state <= 2;
end
else begin
data <= data;
send_go <= 0;
state <= 1;
end
end
else if(state == 2)begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[23:16];
send_go <= 1;
state <= 3;
end
else begin
data <= data;
send_go <= 0;
state <= 2;
end
end
else if(state == 3)begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[31:24];
send_go <= 1;
state <= 2;
end
else begin
data <= data;
send_go <= 0;
state <= 2;
end
end
else if(state == 4)begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[39:32];
send_go <= 1;
state <= 5;
end
else begin
data <= data;
send_go <= 0;
state <= 4;
end
end
else if(state == 5)begin
// data <= data;
if(tx_done) // 一位数据发送完成
send_go <= 0;
trans_down <= 1;
state <=0 ;
end
else begin
data <= data;
send_go <= 0;
state <= 5;
end
end
endmoudle
tb 文件
`timescale 1ns/1ns
module uart_tx_data_tb()
reg clk;
reg reset;
reg [39:0]data40;
reg trans_go;
wire uart_tx;
uart_tx_data uart_tx_data(
clk,
reset,
data40,
trans_go,
uart_tx
);
initial clk = 1;
always #10 clk = ~clk;
initial begin
reset = 0;
data40 = 0;
trans_go = 0;
#201
reset =1;
#200;
data40 = 40'h123456789a;
trans_go = 1;
#20;
trans_go = 0;
@(posedge trans_done);
#200000;
data40 = 40'ha987654321;
trans_go = 1;
#20;
trans_go = 0;
@(posedge trans_done);
#200000;
$stop
endmodule
换一种写法:
module uart_tx_data (
clk,
reset,
data40,
trans_go,
uart_tx,
trans_done
);
input clk;
input reset;
input [39:0]data40;
input trans_go;
ouput uart_tx;
ouput reg c;
reg [7:0]data;
reg send_go;
wire tx_done;
uart_byte_tx_uart_byte_tx(
.clk(clk),
.reset(reset),
.data(data),
.send_en(send_go),
.baud_set(baud_set),
.uart_tx(uart_tx),
.tx_done(tx_done)
);
reg [2:0]state;
always@(posedge clk or negedge reset)
if(!reset) begin
state <= 0;
data <= 0;
send_go <= 0;
trans_done <= 0;
end
else begin
case(state)
0:
begin
trans_done <= 0;
if(trans_go) begin
data <= data40[7:0];
send_go <= 1;
state <= 1;
end
else begin
data <= data;
send_go <= 0;
state <= 0;
end
end
1:
begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[15:8];
send_go <= 1;
state <= 2;
end
else begin
data <= data;
send_go <= 0;
state <= 1;
end
end
2:
begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[23:16];
send_go <= 1;
state <= 3;
end
else begin
data <= data;
send_go <= 0;
state <= 2;
end
end
3:
begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[31:24];
send_go <= 1;
state <= 2;
end
else begin
data <= data;
send_go <= 0;
state <= 2;
end
end
4:
begin
// data <= data;
if(tx_done) // 一位数据发送完成
data <= data40[39:32];
send_go <= 1;
state <= 5;
end
else begin
data <= data;
send_go <= 0;
state <= 4;
end
end
5:
begin
// data <= data;
if(tx_done) // 一位数据发送完成
send_go <= 0;
trans_down <= 1;
state <=0 ;
end
else begin
data <= data;
send_go <= 0;
state <= 5;
end
end
endmoudle
小结:通过这个实验 实现了状态机的设计(优化 可否通过3个状态实现发送的功能,并且有易于修改为发送任意个字节的数据)