集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
楼主: lcytms

FPGA初级课程第二十讲 UART

[复制链接]
 楼主| lcytms 发表于 2016-11-24 17:40:56 | 显示全部楼层
Uart_rx模块

模块功能说明:Uart_rx模块为串口串行数据的接收模块,数据从端口rs232_rx输入,在采集控制信号sel_data和有效位计数器num的控制下,进行串并转换,从端口rx_d[7:0]输出。tx_en为发送控制模块的使能信号,当Uart_rx模块接收数据完毕以后,置高信号tx_en启动数据发送,将采集到的数据rx_d[7:0]发送到上位机。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:42:20 | 显示全部楼层
bps_tx模块

模块功能说明:bps_tx模块为串口发送数据的速率控制模块,当使能信号tx_en为高电平时,bps_tx模块内部计数器开始计数,按照设定好的波特率,输出控制数据发送的尖峰脉冲信号sel_data和有效数据位的计数值num。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:43:34 | 显示全部楼层
Uart_tx模块

模块功能说明:Uart_tx模块为串口串行数据的发送模块,并行数据从端口rx_d[7:0]输入,在采集控制信号sel_data和有效位计数器num的控制下,进行并串转换,从端口rs232_tx输出。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:45:01 | 显示全部楼层
我们将以上四个模块一起放到uart.v顶层模块中,并将接收模块接收到的数据直接通过发送模块发送出去。
uart.v顶层模块的总体架构图如下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:47:14 | 显示全部楼层
查看实际效果。
至芯科技ZX_1开发板外部连接上位PC机,PC机通过串口工具发送数据,并检查从开发板返回的数据是否与发送数据一致。
实现效果图如下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:48:25 | 显示全部楼层
新建工程文件夹uart。
打开Quartus II软件,打开新工程向导。
新建逻辑模块uart.v。
搭建逻辑框架。
module uart (clk, rst_n, rs232_rx, rs232_tx);

        input clk, rst_n;
        input rs232_rx;
       
        output rs232_tx;


endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:52:51 | 显示全部楼层
新建接收端口速率控制逻辑bps_rx.v模块。
编写bps_rx模块代码如下。
module bps_rx (clk, rst_n, rx_en, rx_sel_data, rx_num);

        input clk, rst_n;
        input rx_en;
       
        output reg rx_sel_data;
        output reg [3:0] rx_num;

        parameter bps_div = 13'd5208;
        parameter bps_div_2 = 13'd2604;
       
        reg flag;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        flag <= 0;
                                end
                        else
                                begin
                                        if (rx_en)
                                                begin
                                                        flag <= 1;
                                                end
                                        else
                                                begin
                                                        if (rx_num == 4'd10)
                                                                flag <= 0;
                                                end
                                end
                end

               
        reg [12:0] cnt;
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        cnt <= 13'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        cnt <= 13'd0;
                                                end
                                        else
                                                begin
                                                        if (cnt < bps_div - 1)
                                                                begin
                                                                        cnt <= cnt + 13'd1;
                                                                end
                                                        else
                                                                begin
                                                                        cnt <= 13'd0;
                                                                end
                                                end
                                end
                end
               
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rx_sel_data <= 1'b0;
                                end
                        else
                                begin
                                        if (cnt == bps_div_2)
                                                begin
                                                        rx_sel_data <= 1'b1;
                                                end
                                        else
                                                begin
                                                        rx_sel_data <= 1'b0;
                                                end
                                end
                end
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rx_num <= 4'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        rx_num <= 4'd0;
                                                end
                                        else
                                                begin
                                                        if (rx_num == 4'd10)
                                                                begin
                                                                        rx_num <= 4'd0;
                                                                end
                                                        else
                                                                begin
                                                                        if (rx_sel_data)
                                                                                rx_num <= rx_num + 4'd1;
                                                                end
                                                end
                                end
                end

endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 17:57:09 | 显示全部楼层
新建接收逻辑uart_rx.v模块。
编写uart_rx模块代码如下。
module uart_rx (clk, rst_n, rs232_rx, rx_sel_data, rx_num, rx_en, tx_en, rx_d);

        input clk, rst_n;
        input rs232_rx;
        input rx_sel_data;
        input [3:0] rx_num;
       
        output rx_en;
        output reg tx_en;
        output reg [7:0] rx_d;

       
        reg d, dd;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        d <= 1'b1;
                                        dd <= 1'b1;
                                end
                        else
                                begin
                                        d <= rs232_rx;
                                        dd <= d;
                                end
                end
       
        assign rx_en = dd & (~d);

       
        reg [7:0] rx_data;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rx_data <= 8'd0;
                                        rx_d <= 8'd0;
                                end
                        else
                                begin
                                        if (rx_sel_data)
                                                begin
                                                        case (rx_num)
                                                        0        :        ;
                                                        1        :        rx_data[0] <= rs232_rx;
                                                        2        :        rx_data[1] <= rs232_rx;
                                                        3        :        rx_data[2] <= rs232_rx;
                                                        4        :        rx_data[3] <= rs232_rx;
                                                        5        :        rx_data[4] <= rs232_rx;
                                                        6        :        rx_data[5] <= rs232_rx;
                                                        7        :        rx_data[6] <= rs232_rx;
                                                        8        :        rx_data[7] <= rs232_rx;
                                                        9        :        rx_d <= rx_data;
                                                        default        :        ;
                                                        endcase
                                                end
                                end
                end

        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        tx_en <= 0;
                                end
                        else
                                begin
                                        if (rx_sel_data && (rx_num == 4'd9))
                                                tx_en <= 1;
                                        else
                                                tx_en <= 0;
                                end
                end
               
endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 18:01:21 | 显示全部楼层
新建发送端口速率控制逻辑bps_tx.v模块。
编写bps_tx模块代码如下。
module bps_tx (clk, rst_n, tx_en, tx_sel_data, tx_num);

        input clk, rst_n;
        input tx_en;
       
        output reg tx_sel_data;
        output reg [3:0] tx_num;

        parameter bps_div = 13'd5208;
        parameter bps_div_2 = 13'd2604;
       
        reg flag;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        flag <= 0;
                                end
                        else
                                begin
                                        if (tx_en)
                                                begin
                                                        flag <= 1;
                                                end
                                        else
                                                begin
                                                        if (tx_num == 4'd10)
                                                                flag <= 0;
                                                end
                                end
                end

               
        reg [12:0] cnt;
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        cnt <= 13'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        cnt <= 13'd0;
                                                end
                                        else
                                                begin
                                                        if (cnt < bps_div - 1)
                                                                begin
                                                                        cnt <= cnt + 13'd1;
                                                                end
                                                        else
                                                                begin
                                                                        cnt <= 13'd0;
                                                                end
                                                end
                                end
                end
               
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        tx_sel_data <= 1'b0;
                                end
                        else
                                begin
                                        if (cnt == bps_div_2 - 1)
                                                begin
                                                        tx_sel_data <= 1'b1;
                                                end
                                        else
                                                begin
                                                        tx_sel_data <= 1'b0;
                                                end
                                end
                end
               
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        tx_num <= 4'd0;
                                end
                        else
                                begin
                                        if (!flag)
                                                begin
                                                        tx_num <= 4'd0;
                                                end
                                        else
                                                begin
                                                        if (tx_num == 4'd10)
                                                                begin
                                                                        tx_num <= 4'd0;
                                                                end
                                                        else
                                                                begin
                                                                        if (tx_sel_data)
                                                                                tx_num <= tx_num + 4'd1;
                                                                end
                                                end
                                end
                end

endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2016-11-24 18:04:55 | 显示全部楼层
新建发送逻辑uart_tx.v模块。
编写uart_tx模块代码如下。
module uart_tx (clk, rst_n, tx_sel_data, tx_num, tx_d, rs232_tx);

        input clk, rst_n;
        input tx_sel_data;
        input [3:0] tx_num;
        input [7:0] tx_d;
       
        output reg rs232_tx;

        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        rs232_tx <= 1'b1;
                                end
                        else
                                begin
                                        if (tx_sel_data)
                                                begin
                                                        case (tx_num)
                                                        0        :        rs232_tx <= 1'b0;
                                                        1        :        rs232_tx <= tx_d[0];
                                                        2        :        rs232_tx <= tx_d[1];
                                                        3        :        rs232_tx <= tx_d[2];
                                                        4        :        rs232_tx <= tx_d[3];
                                                        5        :        rs232_tx <= tx_d[4];
                                                        6        :        rs232_tx <= tx_d[5];
                                                        7        :        rs232_tx <= tx_d[6];
                                                        8        :        rs232_tx <= tx_d[7];
                                                        9        :        rs232_tx <= 1'b1;
                                                        default        :        rs232_tx <= 1'b1;
                                                        endcase
                                                end
                                end
                end
       
endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-12-23 23:33 , Processed in 0.069226 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表