1. 使用串口发送5个数据到电脑
- 对于变化的位数(原8)位进行的设计,5个数据即40位。
- UART规定发送的数据位只能是6、7、8。
1.1 设计思路
- 对于12位的数据,发送两个字节,高四位变0即可。例如12'h123,按照8'h23和8'h01发送。
- 两种可能出现的情况:1. 空闲状态,还没有开始发送(上一次的发送已经完成,新的请求
Trans_Go
还没有出现);2.Trans_Go
信号到来;3. 发送数据中。
1.2 设计方案
-
情况1时,等待传输信号的到来
Trans_Go
。 -
情况2时,
Data40
给到模块Uart_Byte_Tx
的Data
,同时产生Send_Go
信号,发送第一个8字节数据。 -
情况3时,需要等待
Tx_Done
信号发送下一个8位的数据。- 此时分为两种情况,根据40位发完了没有进行判断:1. 发完,回到情况1;2. 没发完,发送下一个8位。
-
变量设置
Clk
时钟输入Reset_N
复位Data40
外部输入的40位数据Trans_Go
发送信号Uart_Tx
输出信号state
状态信号(0的情况对应第一个字节)Trans_Done
全部40位数据传输完毕信号
-
通过对状态的控制来分阶段传输5次
-
状态机思维代码
module Uart_Tx_Data(
Clk,
Reset_N,
Data40,
Trans_Go,
Trans_Done,
Uart_Tx
);
input Clk;
input Reset_N;
input [39:0]Data40;
input Trans_Go;
output reg Trans_Done;
output Uart_Tx;
reg [7:0]Data;
reg Send_Go;
wire Tx_Done;
Uart_Byte_Tx Uart_Byte_Tx(
.Clk(Clk),
.Reset_N(Reset_N),
.Data(Data),
.Send_Go(Send_Go),
.Baud_Set(3'd4),
.Uart_Tx(Uart_Tx),
.Tx_Done(Tx_Done)
);
reg [3:0]state;
always@(posedge Clk or negedge Reset_N)
if(!Reset_N)begin
Data <= 0;
Send_Go <= 0;
state <= 0;
end
else if(state == 0)begin
Trans_Done <= 0;
if(Trans_Go)begin
Data <= Data40[7:0];
Send_Go <= 1'b1;
state <= 1'b1;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 0;
end
end
else if(state == 1)begin
if(Tx_Done)begin
Data <= Data40[15:8];
Send_Go <= 1'b1;
state <= 2'd2;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 1'b1;
end
end
else if(state == 2)begin
if(Tx_Done)begin
Data <= Data40[23:16];
Send_Go <= 1'b1;
state <= 2'd3;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 2'd2;
end
end
else if(state == 3)begin
if(Tx_Done)begin
Data <= Data40[31:24];
Send_Go <= 1'b1;
state <= 3'd4;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 2'd3;
end
end
else if(state == 4)begin
if(Tx_Done)begin
Data <= Data40[39:32];
Send_Go <= 1'b1;
state <= 3'd5;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 3'd4;
end
end
else if(state == 5)begin
if(Tx_Done)begin
Send_Go <= 0;
state <= 0;
Trans_Done <= 1;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 3'd5;
end
end
endmodule
1.3 第二种设计(使用case)
代码
module Uart_Tx_Data2(
Clk,
Reset_N,
Data40,
Trans_Go,
Trans_Done,
Uart_Tx
);
input Clk;
input Reset_N;
input [39:0]Data40;
input Trans_Go;
output reg Trans_Done;
output Uart_Tx;
reg [7:0]Data;
reg Send_Go;
wire Tx_Done;
Uart_Byte_Tx Uart_Byte_Tx(
.Clk(Clk),
.Reset_N(Reset_N),
.Data(Data),
.Send_Go(Send_Go),
.Baud_Set(3'd4),
.Uart_Tx(Uart_Tx),
.Tx_Done(Tx_Done)
);
reg [3:0]state;
always@(posedge Clk or negedge Reset_N)
if(!Reset_N)begin
Data <= 0;
Send_Go <= 0;
state <= 0;
end
else
case(state)
0:begin
Trans_Done <= 0;
if(Trans_Go)begin
Data <= Data40[7:0];
Send_Go <= 1'b1;
state <= 1'b1;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 0;
end
end
1:begin
if(Tx_Done)begin
Data <= Data40[15:8];
Send_Go <= 1'b1;
state <= 2'd2;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 1'b1;
end
end
2:begin
if(Tx_Done)begin
Data <= Data40[23:16];
Send_Go <= 1'b1;
state <= 2'd3;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 2'd2;
end
end
3:begin
if(Tx_Done)begin
Data <= Data40[31:24];
Send_Go <= 1'b1;
state <= 3'd4;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 2'd3;
end
end
4:begin
if(Tx_Done)begin
Data <= Data40[39:32];
Send_Go <= 1'b1;
state <= 3'd5;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 3'd4;
end
end
5:begin
if(Tx_Done)begin
// Data <= Data40[39:32];
Send_Go <= 0;
state <= 0;
Trans_Done <= 1;
end
else begin
Data <= Data;
Send_Go <= 0;
state <= 3'd5;
end
end
default:begin
Data <= Data;
Send_Go <= 0;
state <= 0;
end
endcase
endmodule
1.4 后续任务
- 优化状态机,实现只要2个或3个状态实现发送的功能,并且易于修改为发送任意字节的数据。
- 征集不适用状态机的思想来实现本任务的方案。