英特尔FPGA实训 day 11

学习内容:

通过串口发送字符串。同时还了解了WIFI相关的发展以及协议。

疑惑的产生:

        暂时未想到方法,让程序只对字符串内容发送一次。

相关代码:

参数定义

`define SYS_FRQ 50_000_000
`define BAUD_115200

`ifdef BAUD_9600
    `define BAUD_MAX 9600
`elsif BAUD_19200
   `define BAUD_MAX 19200
`elsif BAUD_38400
    `define BAUD_MAX 38400
`elsif BAUD_57600
   `define BAUD_MAX 57600
`elsif BAUD_115200
    `define BAUD_MAX 115200
`else
   `define BAUD_MAX 9600
`endif 


串口发送模块tx

`include "param.v"
module uart_tx(
    input clk,
    input rst_n,
    input tx_req,
    input [7:0] tx_din,//输入的并行数据(真正需要发送的数据串)(数据不够这么多位,自动补零?)

    output reg tx_dout,//输出的串行数据
    output dout_vld,     //发送完成的标志
    output arr_dout_vld  //字符串全部发送完毕标志
);//开始的标志是 tx_req为1,结束的标志是 数据发送完,tx_flag随即置0

reg [12:0] cnt_bps;//波特率计数寄存器 
wire add_cnt_bps;   //波特率计数开始标志 
wire end_cnt_bps;   //波特率计数结束 


reg [3:0] cnt_bit;//比特计数寄存器
wire   add_cnt_bit;//比特计数开始标志
wire   end_cnt_bit;//比特计数结束
reg tx_flag;
reg [9:0] tx_data;//需要发送的数据  (实际发送的数据串,即:包括包头包尾)

//


//波特率计数器(发送1bit需要的时间)
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt_bps <= 0;
    end 
    else if(add_cnt_bps)begin 
        if (end_cnt_bps) begin
            cnt_bps <= 0;
        end
        else begin
            cnt_bps <= cnt_bps +1;
        end
    end 
    else begin 
        cnt_bps <= cnt_bps ;
    end 
end
assign add_cnt_bps = tx_flag;
assign end_cnt_bps = add_cnt_bps && cnt_bps == (`SYS_FRQ/`BAUD_MAX)-1'd1 ;


//计数已经发送了多少位数据(确定当前应该发送第几位了)
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt_bit <= 0;
    end 
    else if(add_cnt_bit)begin 
        if (end_cnt_bit) begin
            cnt_bit <= 0;
        end  
        else begin 
            cnt_bit <= cnt_bit + 1;
        end 
    end 
    else begin
        cnt_bit <= cnt_bit;
    end
    
end
assign add_cnt_bit = end_cnt_bps;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 4'd9;//达到条件后,结束发送

//发送开始,结束的判断
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        tx_flag <= 0;
    end 
    else if (end_cnt_bit) begin 
        tx_flag <= 1'b0; 
    end
    else if(tx_req)begin //收到发送请求,则 将发送位(即tx_flag)置1
        tx_flag <= 1'b1;
    end 
    
    else begin 
        tx_flag <= tx_flag;  
    end 
end 
/*
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        flag_r0 <= 0;
        flag_r1 <= 0;
    end  
    else begin 
        flag_r0 <= tx_flag;
        flag_r1 <= flag_r0;
    end 
end
assign negedge_flag = flag_r1 && ~flag_r0;
//获取第n个字符
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt_arr <= 0;
    end 
    else if(cnt_arr <= arr_length)begin 
        if (negedge_flag) begin//tx_flag由1变成0
            cnt_arr <= cnt_arr + 1;
        end
        else if (cnt_arr == arr_length) begin
            arr_dout_vld <= 1'd1;// 数据真正发送完毕
        end
        else begin
            cnt_arr <= cnt_arr;
            arr_dout_vld <= 1'd0;
        end
    end 
    else begin 
        cnt_arr <= 0;
    end 
end
*/

//拼接(打包)需要发送的数据
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin 
        tx_data <= 10'b0; 
    end 
    else if(tx_req)begin 
        tx_data <= {1'b1,tx_din,1'b0};//注意:传送的时候 tx_data[0]=0  而不是1。  这里最后一位是1,是因为 要让接收端的默认信号变回高电平,便于下次低电平到来的时候,下降沿的产生
    end 
    else begin 
        tx_data <= tx_data;
    end 
end
//开始发送数据
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        tx_dout <= 1'b1;
    end 
    //发送端为什么不考虑0.1衔接不理想的问题?
    //,因为发送端是发送,而不是读取,读取要判断该电平表示1还是0,而发送端不用读取、所以不用考虑0.1电平理想的问题
    else if(tx_flag && cnt_bps == 1)begin 
        tx_dout <= tx_data[cnt_bit];
    end 
    else begin 
        tx_dout <= tx_dout;
    end 
end
assign dout_vld = ~tx_flag;

endmodule

字符串定义模块

module send_data(
    input clk,
    input rst_n,
    input dout_vld,

    output reg [7:0] rx_byte,
    output reg next_cnt_flag,
    output reg send_vld
);

reg [7:0] data[5:0] ;

reg[2:0] cnt;
wire add_cnt;
wire end_cnt;

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt <= 3'd0;
    end 
    else if(add_cnt)begin 
        if (end_cnt) begin
            cnt <= 3'd0;
            next_cnt_flag <= 1;
        end
        else begin
            cnt <= cnt + 1'd1;
        end
    end 
    else begin 
        cnt <= cnt;
    end 
end

assign add_cnt = dout_vld;
assign end_cnt = add_cnt && cnt ==5;


always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        rx_byte <= 0;
        data[0] <= "H";
        data[1] <= "E";
        data[2] <= "L";
        data[3] <= "L";
        data[4] <= "O";
        data[5] <= "!";
    end 
    else begin 
        rx_byte <= data[cnt];
    end 
end
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        send_vld <= 1;
    end 
    else if(end_cnt)begin 
        send_vld <= 1'b0;
    end 
    else begin 
        send_vld <= 1'b1;
    end 
end

endmodule

顶层文件

module uart_send(
    input clk,
    input rst_n,
    
    output tx
);
wire [7:0] tx_byte;
wire dout_vld;
wire next_cnt_flag;


send_data u_send_data(
.clk(clk),
.rst_n(rst_n),
.dout_vld(dout_vld),

.next_cnt_flag(next_cnt_flag),
.rx_byte(tx_byte)
);

uart_tx u_uart_tx(
.clk(clk),
.rst_n(rst_n),
.tx_din(tx_byte),
.tx_req(next_cnt_flag),

.dout_vld(dout_vld),
.tx_dout(tx)
);


endmodule

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值