新手入门
- 积分
- 7
- 金钱
- 7
- 注册时间
- 2020-10-19
- 在线时间
- 4 小时
|
请教下大佬们,我根据正点的例子把8位的串口发送程序改成了32位的串口发送程序,虽然可以发送出正确的数,但是如果我将标志位uart_en延时发送到某块后,他并不能延时发送,而是按照原有速度发送数据。修改的串口程序如下:
module uart_send(
input sys_clk, //系统时钟
input sys_rst_n, //系统复位,低电平有效
input uart_en, //发送使能信号
input signed [31:0] uart_din, //待发送数据
output reg signed uart_txd //UART发送端口
);
//parameter define
parameter CLK_FREQ = 50000000; //系统时钟频率
parameter UART_BPS = 115200; //串口波特率
localparam BPS_CNT = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数BPS_CNT次
//reg define
reg uart_en_d0;
reg uart_en_d1;
reg [15:0] clk_cnt; //系统时钟计数器
reg [ 3:0] tx_cnt; //发送数据计数器
reg tx_flag; //发送过程标志信号
reg signed [ 31:0] tx_data; //寄存发送数据
reg [3:0] data_flag; //发送完数据的标志位
reg finsh_flag; //完成一次16位传输操作标志
//wire define
wire en_flag;
//*****************************************************
//** main code
//*****************************************************
//捕获uart_en上升沿,得到一个时钟周期的脉冲信号
assign en_flag = (~uart_en_d1) & uart_en_d0;
//对发送使能信号uart_en延迟两个时钟周期
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
uart_en_d0 <= 1'b0;
uart_en_d1 <= 1'b0;
end
else begin
uart_en_d0 <= uart_en;
uart_en_d1 <= uart_en_d0;
end
end
//当脉冲信号en_flag到达时,寄存待发送的数据,并进入发送过程
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
tx_flag <= 1'b0;
tx_data <= 8'd0;
end
else if (en_flag) begin //检测到发送使能上升沿
tx_flag <= 1'b1; //进入发送过程,标志位tx_flag拉高
tx_data <= uart_din; //寄存待发送的数据
end
else
//if ((clk_cnt == BPS_CNT/2)&&(finsh_flag==1'd1))
if ((clk_cnt == BPS_CNT/2)&&(finsh_flag==1'd1))
begin //计数到停止位中间时,停止发送过程
tx_flag <= 1'b0; //发送过程结束,标志位tx_flag拉低
tx_data <= 16'd0;
end
else begin
tx_flag <= tx_flag;
tx_data <= tx_data;
end
end
//进入发送过程后,启动系统时钟计数器与发送数据计数器
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
clk_cnt <= 16'd0;
tx_cnt <= 4'd0;
data_flag<=1'b0;
end
else if (tx_flag) begin //处于发送过程
if (clk_cnt < BPS_CNT - 1) begin
clk_cnt <= clk_cnt + 1'b1;
tx_cnt <= tx_cnt;
end
else begin
clk_cnt <= 16'd0; //对系统时钟计数达一个波特率周期后清零
if(tx_cnt == 4'd9)begin
tx_cnt<=4'd0;
if(data_flag<3'd3)
data_flag<=data_flag+1'd1;
else
data_flag<=1'd0;
end
else
tx_cnt <= tx_cnt + 1'b1; //此时发送数据计数器加1
end
end
else begin //发送过程结束
clk_cnt <= 16'd0;
tx_cnt <= 4'd0;
end
end
//根据发送数据计数器来给uart发送端口赋值
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
uart_txd <= 1'b1;
finsh_flag<=1'd0;
end
else begin
if (tx_flag) begin
case(data_flag)
4'd0:case(tx_cnt)
4'd0: uart_txd <= 1'b0; //起始位
4'd1: uart_txd <= tx_data[24]; //数据位最低位
4'd2: uart_txd <= tx_data[25];
4'd3: uart_txd <= tx_data[26];
4'd4: uart_txd <= tx_data[27];
4'd5: uart_txd <= tx_data[28];
4'd6: uart_txd <= tx_data[29];
4'd7: uart_txd <= tx_data[30];
4'd8: uart_txd <= tx_data[31]; //数据位最高位
4'd9: begin
uart_txd <= 1'b1; //停止位
end
default: ;
endcase
4'd1:
case(tx_cnt)
4'd0: uart_txd <= 1'b0; //起始位
4'd1: uart_txd <= tx_data[16]; //数据位最低位
4'd2: uart_txd <= tx_data[17];
4'd3: uart_txd <= tx_data[18];
4'd4: uart_txd <= tx_data[19];
4'd5: uart_txd <= tx_data[20];
4'd6: uart_txd <= tx_data[21];
4'd7: uart_txd <= tx_data[22];
4'd8: uart_txd <= tx_data[23]; //数据位最高位
4'd9: begin
uart_txd <= 1'b1; //停止位
end
default: ;
endcase
4'd2:
case(tx_cnt)
4'd0: uart_txd <= 1'b0; //起始位
4'd1: uart_txd <= tx_data[8]; //数据位最低位
4'd2: uart_txd <= tx_data[9];
4'd3: uart_txd <= tx_data[10];
4'd4: uart_txd <= tx_data[11];
4'd5: uart_txd <= tx_data[12];
4'd6: uart_txd <= tx_data[13];
4'd7: uart_txd <= tx_data[14];
4'd8: uart_txd <= tx_data[15]; //数据位最高位
4'd9: uart_txd <= 1'b1; //停止位
default: ;
endcase
4'd3:case(tx_cnt)
4'd0: uart_txd <= 1'b0; //起始位
4'd1: uart_txd <= tx_data[0]; //数据位最低位
4'd2: uart_txd <= tx_data[1];
4'd3: uart_txd <= tx_data[2];
4'd4: uart_txd <= tx_data[3];
4'd5: uart_txd <= tx_data[4];
4'd6: uart_txd <= tx_data[5];
4'd7: uart_txd <= tx_data[6];
4'd8: uart_txd <= tx_data[7]; //数据位最高位
4'd9: begin
uart_txd <= 1'b1; //停止位
finsh_flag<=1'd1; //停止位
end
default: ;
endcase
default: ;
endcase
finsh_flag<=1'd0;
end
else
uart_txd <= 1'b1; //空闲时发送端口为高电平
end
end
endmodule
希望有大佬可以解答
|
|