首页 > 其他分享 >uart RS232通信

uart RS232通信

时间:2023-05-12 11:04:54浏览次数:32  
标签:clk uart 通信 send sys rst RS232 reg


波特率指的是异步时钟的频率。

source code

top module

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/04/28 15:48:05
// Design Name: 
// Module Name: uart
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module uart(
    input           sys_clk,            //外部50M时钟
    input           sys_rst_n,          //外部复位信号,低有效
    input           uart_rxd,           //UART接收端口
    output          uart_txd            //UART发送端口
    );
    reg [7:0] fifo[7:0];
    reg [2:0] read_ptr;
    reg [2:0] write_ptr;
    reg [7:0] send_data;
    wire [7:0] uart_data;
    wire send_busy;
    reg send_en;
    wire uart_doing;
    reg uart_doing_d1,uart_doing_d0;
    wire uart_doing_neg;
    assign uart_doing_neg = uart_doing_d0 &!uart_doing_d1;
    always @(posedge sys_clk or negedge sys_rst_n) begin
         if(!sys_rst_n)begin send_en<=0; read_ptr<=3'd0;end 
         else
            begin
                if(send_en)send_en<=0;
                else if(write_ptr!=read_ptr && !send_busy)
                    begin
                        send_en<=1;
                        send_data<=fifo[read_ptr];
                        read_ptr<=read_ptr+3'd1;
                    end
            end
    end
    always @(posedge sys_clk or negedge sys_rst_n)
    begin
        if(!sys_rst_n)
        begin
            uart_doing_d0<=0;
            uart_doing_d1<=0;
        end
        else
        begin
            uart_doing_d0<=uart_doing_d1;
            uart_doing_d1<=uart_doing;
        end
    end
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(!sys_rst_n)write_ptr<=3'd0;
        else if(uart_doing_neg &&(write_ptr+3'd1)!=read_ptr)
        begin
            fifo[write_ptr]<=uart_data;
            write_ptr<=write_ptr+3'd1;
        end
    end
    
    uart_send send1(.sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),
    .send_en(send_en),
    .send_data(send_data),
    .uart_txd(uart_txd),
    .send_busy(send_busy));

    uart_recv recv1 (.sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),
    .uart_rxd(uart_rxd),   
    .uart_doing(uart_doing), 
    .uart_data(uart_data));
endmodule

uart_send module

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/04/28 16:08:19
// Design Name: 
// Module Name: uart_send
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module uart_send(
    input sys_clk,
    input sys_rst_n,
    input send_en,
    input [7:0] send_data,
    output reg uart_txd,
    output reg send_busy
    );
    reg [7:0] tx_data;
    reg send_en_d0,send_en_d1;
    wire en_neg;
    parameter clk_fre=50000000;
    parameter fps=115200;
    parameter fps_count=clk_fre/fps;
    reg [15:0] clk_count;
    reg [4:0] num_count;
    assign en_neg = send_en_d0 & (!send_en_d1);
    always @(posedge sys_clk or negedge sys_rst_n)
    begin
        if(!sys_rst_n)
        begin
            send_en_d0<=0;
            send_en_d1<=0;
        end
        else
        begin
            send_en_d0<=send_en_d1;
            send_en_d1<=send_en;
        end
    end
    always @(posedge sys_clk or negedge sys_rst_n)
    begin
        if(!sys_rst_n)
        begin
            send_busy<=0;
            clk_count<=16'd0;
            num_count<=5'd0;
        end
        else if(en_neg)
        begin
            send_busy<=1;
            tx_data<=send_data;
            clk_count<=16'd0;
            num_count<=5'd0;
        end
        else if(send_busy)
        begin
            if(clk_count==fps_count-1) 
            begin 
                clk_count<=16'd0;
                if(num_count==5'd9)begin num_count<=5'd0;send_busy<=0; end
                else num_count<=num_count+1;
            end
            else clk_count<=clk_count+1; 
        end
    end
    always @(posedge sys_clk or negedge sys_rst_n) begin        
    if (!sys_rst_n)  
        uart_txd <= 1'b1;        
    else if (send_busy)
        case(num_count)
            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: uart_txd <= 1'b1;         //停止位
            default: ;
        endcase
    else 
        uart_txd <= 1'b1;                   //空闲时发送端口为高电平
    end
endmodule

uart_recv module

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/04/29 09:17:28
// Design Name: 
// Module Name: uart_recv
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module uart_recv(
    input			  sys_clk,                  //系统时钟
    input             sys_rst_n,                //系统复位,低电平有效
    input             uart_rxd,                 //UART接收端口
    output  reg       uart_doing,                //接收一帧数据完成标志
    output  reg [7:0] uart_data                 //接收的数据
    );
    reg uart_rxd_d0;
    reg uart_rxd_d1;
    parameter clk_fre=50000000;
    parameter fps=115200;
    parameter fps_count=clk_fre/fps;
    reg [15:0] clk_count;
    reg [4:0] num_count;
    wire uart_rxd_neg;
    assign uart_rxd_neg = uart_rxd_d0 & (!uart_rxd_d1);
    always @(posedge sys_clk or negedge sys_rst_n)
    begin
        if(!sys_rst_n)
        begin
            uart_rxd_d0<=0;
            uart_rxd_d1<=0;
        end
        else
        begin
            uart_rxd_d0<=uart_rxd_d1;
            uart_rxd_d1<=uart_rxd;
        end
    end
    always @(posedge sys_clk or negedge sys_rst_n)
    begin
        if(!sys_rst_n)
        begin
            clk_count<=16'd0;
            num_count<=5'd0;
            uart_doing<=0;
        end
        else if(uart_rxd_neg && !uart_doing)
        begin
            clk_count<=16'd1;
            num_count<=5'd0;
            uart_doing<=1;
        end
        else if(uart_doing)
        begin
            if(clk_count==fps_count-1) 
            begin 
                clk_count<=16'd0;
                if(num_count==5'd9)begin num_count<=5'd0;end
                else num_count<=num_count+1;
            end
            else clk_count=clk_count+1; 
            if(clk_count==fps_count/2)
            begin
                case(num_count)
                4'd1: uart_data[0] <= uart_rxd;   //数据位最低位
                4'd2: uart_data[1] <= uart_rxd;
                4'd3: uart_data[2] <= uart_rxd;
                4'd4: uart_data[3] <= uart_rxd;
                4'd5: uart_data[4] <= uart_rxd;
                4'd6: uart_data[5] <= uart_rxd;
                4'd7: uart_data[6] <= uart_rxd;
                4'd8: uart_data[7] <= uart_rxd;   //数据位最高位
                4'd9: begin uart_doing <= 0;clk_count<=16'd0;num_count<=5'd0;end 
                default: ;
                endcase
            end
        end
    end
endmodule

xdc

create_clock -period 20.000 -name clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVCMOS33} [get_ports uart_rxd]
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports uart_txd]

仿真文件

仿真参考意义不大,真正调试还得看开ILA。

uart_recv_test

module uart_recv_test;
reg sys_clk;
reg sys_rst_n;
reg uart_rxd;
wire uart_doing;
wire [7:0] uart_data;
initial begin
    sys_clk = 1'b0;
    #(2);
    forever
        #(2) sys_clk = ~sys_clk;
end
initial begin
    sys_rst_n = 1'b0;
    uart_rxd = 1'b1;
    #4;
    sys_rst_n = 1'b1;
    #4;
    uart_rxd = 1'b0;
    #40
    uart_rxd = 1'b1;
end

uart_recv recv1 (.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.uart_rxd(uart_rxd),   
.uart_doing(uart_doing), 
.uart_data(uart_data)   
);
endmodule

uart_send_test

module uart_test;
reg sys_clk;
reg sys_rst_n;
reg send_en;
reg [7:0] send_data;
wire uart_txd;
wire send_busy;
initial begin
      sys_clk= 1'b0;
      #(2);
      forever
         #(2) sys_clk = ~sys_clk;
end
initial
begin
    sys_rst_n=0;
    send_en=0;
    send_data=7'd60;
    #2 sys_rst_n=1;
    #10 send_en=1;
    #4 send_en=0;
end
uart_send send1(.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.send_en(send_en),
.send_data(send_data),
.uart_txd(uart_txd),
.send_busy(send_busy));
endmodule

标签:clk,uart,通信,send,sys,rst,RS232,reg
From: https://www.cnblogs.com/xzh-personal-issue/p/17393298.html

相关文章

  • Https通信的SSL证书工作流程原理(转)
    前言浏览器与服务器之间的https加密通信会包括以下一些概念:非对称加密、对称加密、RSA、证书申请、根证书。https证书加密,就是在传输层tcp和应用层http之间加了一层ssl层来对传输内容进行加密。用时序图简单记录一下大致过程吧。证书工作原理服务器向证书机构申请证书的流程如......
  • React笔记-组件通信(六)
    React笔记-组件通信(六)props概念props是组件之间通讯的纽带props也是组件中内置的一个属性通过父级组件传入在类组件里可以直接通过this.props获取注意:props是不可变的(只读)修改需要从传值的组件中修改props改变会使视图重新渲染组件传值父传子在父组件......
  • 父与子组件的通信方式
    vue中,父组件与子组件的通信方式VUE父子组件之间通信方式_vue父子组件通信_Johnson_9的博客-CSDN博客一、props通信方式在子组件里给props接收数据,父组件定义数据 二、$emit用法(用$emit方法,使用自定义的方法,获取到参数,父组件能获取到子组件操作,子组件向父组件传递数据)在父组......
  • 基于MATLAB的自适应调制解调通信系统的误码率仿真,对比BPSK,QPSK,16QAM,64QAM
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要BPSK:BinaryPhaseShiftKeying 二相相移键控,一个符号代表1bit QPSK:QuadraturePhaseShiftKeying  四相相移键控,一个符号代表2bit 8PSK:8PhaseShiftKeying  八相相移键控,一个符......
  • iframe通信
    目录1、contentWindow方式通信2、contentWindow方式通信1、contentWindow方式通信声明文件declareglobal{interfaceWindow{childDefineFunction:(message:string)=>voidfatherDefineFunction:(message:string)=>void}}export{}父窗口<t......
  • Linux网络编程:socket实现client/server通信
    一、问题引入阅读UNIX网络编程卷1:套接字联网API第3版的前4个章节,觉得有必要对书籍上的源码案例进行复现,并推敲TCP的C/S通信过程。二、解决过程2-1server#include<sys/types.h>#include<sys/socket.h>#include<stdio.h>#include<netinet/in.h>#include<arpa/inet.h......
  • 网络编程-通信协议-三要素
    1.概述:即通过无线网络或者有线网络可以把不同地理位置且相互独立的计算机连同其外部设备连接起来,组成计算机网络。这样就实现了计算机之间的资源共享和信息的传递。2.网络通信三要素2.1)ip地址网络中计算机的唯一标识;32bit(4字节),一般用“点分十进制”表示,如:192.168.1.158ip地......
  • IO通信机制
    1.IO通信模型IO指的是input和output网络通信的本质是网络间的数据IO。只要有IO,就会有阻塞或非阻塞的问题,无论这个IO是网络的,还是硬盘的。原因在于程序是运行在系统上的,任何形式的IO操作都需要系统支持。2.BIO(阻塞模式)BIO即BlockingIO,是一种阻塞式的IO。jdk1.4版本之前的......
  • 以太网通信控制板-扩展-多路客户端
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/CH579_DTU_PBX/index1.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 说明如果......
  • DSP+ARM+FPGA开发板 板载 双网口/2路RS485/2路RS232/ADC/DAC/CAN
    一、开发套件简介 XQ138AS-EVM是基于XQ138F核心板(OMAPL138+XilinxFPGA)开发的DSP+ARM+FPGA三核评估套件,用户可以采用该开发套件进行项目前期的验证和评估,也可以直接用来开发自己的产品。Ø 底板资源丰富,集成了SATA、SD卡、USBOTG、USBHOST、UART、双网络(1个千兆、1个百兆)、2......