4. 使用串口发送5个数据到电脑——基于FPGA的串口发送数据实验
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个状态实现发送的功能,并且易于修改为发送任意字节的数据。
- 征集不适用状态机的思想来实现本任务的方案。
分类:
Verilog学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix