会员登录 - 用户注册 - 设为首页 - 加入收藏 - 网站地图 根据FPGA的串口UART规划!
当前位置:首页 > 新闻 > 根据FPGA的串口UART规划 正文

根据FPGA的串口UART规划

时间:2025-05-23 00:47:48 来源:锐评时讯 作者:女性 阅读:993次

大侠好,欢迎来到。FPGA。技能江湖,江湖偌大,相见便是缘分。大侠能够重视FPGA技能江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或许一同煮酒言欢。

今日给大侠带来依据FPGA的。UART。规划,附源码,获取源码,请在“FPGA技能江湖”大众号内回复“UART规划源码”,可获取源码文件。话不多说,上货。

规划布景。

串口的呈现是在1980年前后,数据传输率是115kbps~230kbps。串口呈现的初期是为了完成衔接核算机外设的意图,初期串口一般用来衔接鼠标和外置Modem以及旧式摄像头和写字板等设备。串口也能够应用于两台核算机(或设备)之间的互联及数据传输。由于串口(COM)不支持热插拔及传输速率较低,部分新主板和大部分便携。电脑。已开端撤销该。接口。。串口多用于工控和丈量设备以及部分。通讯。设备中。

串口是串行接口的简称,也称串行。通讯接口。或串行通讯接口(一般指COM接口),是选用串行通讯方法的扩展接口。串行接口(Serial Interface)是指数据一位一位地次序传送。其特点是通讯线路简略,只需一对传输线就能够完成双向通讯(能够直接运用电话线作为传输线),然后大大降低了本钱,特别适用于远距离通讯,但传送速度较慢。

通讯协议是指通讯两边的一种约好。约好包括对数据格式、同步方法、传送速度、传送过程、检纠错方法以及操控字符界说等问题做出一致规则,通讯两边有必要一起恪守。串口通讯的两种最基本的方法为:同步串行通讯方法和异步串行通讯方法。

同步串行通讯是指SPI(Serial Peripheral interface)的缩写,望文生义便是串行外围设备接口。SPI是一种高速的全双工通讯总线。封装。芯片。上总共有四根线,PCB。布局布线也简略,所以现在许多芯片集成了这个协议。首要用于。CPU。和各种外围器材进行通讯,TRM450是SPI接口。

异步串行通讯是指UART(Universal Asynchronous Receiver/Transmit。te。r),通用异步接纳/发送。UART是一个并行输入成为串行输出的芯片,一般集成在主板上。UART包括TTL电平的串口和。RS232。电平的串口。RS。232也称规范串口,也是最常用的一种串行通讯接口。RS-232-C 规范对两个方面作了规则,即。信号。电平规范和操控信号线的界说。RS-232-C 选用负逻辑规则逻辑电平,信号电平与一般的TTL电平也不兼容,RS-232-C 将-5V~-15V 规则为“1”,+5V~+15V 规则为“0”。

规划原理。

uart的示意图如下:

其。端口。对应的功能表如下:

在规划过程中只需求关怀RS232_TXD和RS232_RXD两个信号, RS232_TXD是数据发送端口,RS232_RXD是数据接纳端口。

本规划将经过串口建立起核算机和试验板(ZX_1)之间的通讯和操控联系,也便是一般所说的上下位机通讯。要完成这样的通讯,首要需求用到一个外部的电平转化芯片MAX232,其详细装备。电路原理。图如下:

解析:

MAX232芯片是。美信。(。MAXIM。)。公司。专为RS-232规范串口规划的单电源电平转化芯片,运用+5v单电源。供电。

首要特点:。

1、契合一切的RS-232C技能规范;

2、只需求单一+5V。电源。供电;

3、片载。电荷泵。具有升压、电压极性回转才能,能够发生+10V和-10V电压V+、V-;

4、功耗低,典型供电。电流。5mA;

5、内部集成2个RS-232C。驱动器。

6、高集成度,片外最低只需4个。电容。即可作业。

本规划还需求剖析在通讯过程中,UART所对应的数据格式如下:

开始位:线路闲暇时为高电平,当截获第一个低电平比特时,则为开始位;

信息。位:在开始位之后,依照低位首发准则,次序发送信息位的最低位到最高位,信息位的宽度可所以4、5、6、7、8中的一个;

奇偶校验位:信息位之后则是一个可选的奇偶校验位,它可所以无校验(NONE)、奇校验(ODD)、偶校验(EVEN)中的恣意一个,无校验时,信息位之后便是中止位。奇偶校验是,使得信息位和校验位的一切1的个数坚持奇数或许偶数位;

中止位:中止位的长度可所以1、1.5或2中的恣意一个,它为高电平;

闲暇位:继续的高电平。

波特率:每秒传输的数据位(bit)数为波特率。RS-232-C的波特率可所以50、75、100、150、300、600、1200、2400、4800、9600、19200波特。

经过剖析上述的数据格式,在本规划中,将波特率设置为9600,开始位设置为1比特,信息位设置为8比特,奇偶校验位设置为0比特,中止位设置为2比特,闲暇位设置为1比特。

由于在规划中只需求重视RS232_TXD和RS232_RXD这两个信号,已然只要两条线,所以只需求重视其数据收发时序即可,时序图如下:

规划架构。

规划总架构图如下:

uart_pll模块是一个锁相环,经过50M的外部。时钟。(ref_clk),倍频得到100M的上游接口的100M体系时钟(sys_clk);divider模块为UART的分频模块,经过用100M的sys_clk作为输入,分频得到波特率为9600的uart_clk时钟。

transmitter模块为串口发送模块,并合作与其对应的trans_fifo发送数据缓存FIFO进行运用,将储存在FIFO中的数据经过RS232-C协议发送出去;

receiver模块为串口接纳模块,并合作与其对应的rec_fifo接纳数据缓存FIFO进行运用,将储存在FIFO中的数据经过RS232-C协议接纳进来;

UART发送器(transmitter)规划。

UART发送器的时序如下图:

UART。接纳器。(receiver)规划。

依据对UART时序的剖析能够得到如下的状况搬运表(SMF):

规划代码。

顶层uart_lsm模块代码:

`include "uart_lsm_he。ad。.v"module uart_lsm(ref_clk, global_reset,tdata, twrreq,       tf。ull, rdata, rrdreq, rempty, uart_txd, uart_rxd);  input ref_clk, global_reset;  //大局时钟复位  input [7:0] tdata;  //发送fifo输入数据  input twrreq;  //发送fifo写恳求   output tfull;   //发送fifo输出写满  output [7:0] rdata;  //接纳fifo输出数据  input rrdreq;   //接纳fifo的输入读恳求  output rempty;   //接纳fifo的输收支空   output uart_txd;  //输出发送线信号  input uart_rxd;  //输入接纳线信号  wire trxd;  wire [7:0] tf_data, rf。_data;  wire tf_rdreq, tf_empty, rf_wrreq;  wire sys_clk, uart_clk, rst_n;  assign rst_n = ~global_reset;  trans_fifo t_fifo(    //发送fifo    .data(tdata),    .r。dc。lk(uart_clk),    .rdreq(tf_rdreq),    .wrclk(sys_clk),    .wrreq(twrreq),    .q(tf_data),    .rdempty(tf_empty),    .wrfull(tfull)  );  transmitter trans(   //发送模块    .clk(uart_clk),     .rst_n(rst_n),     .empty(tf_empty),     .data(tf_data),     .rdreq(tf_rdreq),     .txd(trxd)  );  rec_fifo r_fifo(     //接纳fifo    .data(rf_data),    .rdclk(sys_clk),    .rdreq(rrdreq),    .wrclk(uart_clk),    .wrreq(rf_wrreq),    .q(rdata),    .rdempty(rempty)  );  receiver rece(     //接纳模块    .clk(uart_clk),     .rst_n(rst_n),     .data(rf_data),     .wrreq(rfwrreq),     .rxd(trxd)  );  uart_pll u_pll(         //锁相环发生体系时钟,作用于fifo、divider    .areset(global_reset),    .inclk0(ref_clk),    .c0(sys_clk)  );  divider_ebd_1s_mealy   //分频模块分频uart_clk,作用于receiver transmitter  #(.HW(`DW), .LW(`DW))  div(    .clk_in(sys_clk),     .rst_n(rst_n),     .clk_out(uart_clk)  );endmodule。

transmitter模块代码:

//uart发送模块LSM(线性序列机)module transmitter(clk, rst_n, empty, data, rdreq, txd);  input clk, rst_n;  //输入时钟复位  input empty;       //来自fifo的输入空标志信号  input [7:0] data;  //来自fifo的输入数据  output reg rdreq;  //输出到fifo的读恳求  output reg txd;    //输出发送线信号  reg [7:0] temp;      //中心。寄存器。reg [7:0] count;    //8位计数  `define EP 192   //终止符  always  (posedge clk。 or。negedge rst_n)  begin  : lsm_2s1   //线性序列机一段闭节点    if (!rst_n)   //复位      count。 <= `EP;    else if ((count >= `EP) && !empty)  //计数大于终止符和非空(empty=0)      count <= 0;    else if (count < `EP) //计数小于终止符      count <= count + 1;  end   always  (posedge clk or negedge rst_n)  begin  : lsm_2s2  //线性序列机一段闭节点    if (!rst_n)  //复位      begin        txd <= 1;   //发送线为高        rdreq <= 0;  //读恳求为0        temp <= 0;  //中心寄存器为0      end     else if ((count >= `EP) && !empty) //计数大于终止符fifo为非空,读恳求拉高        rdreq。 <= 0;    else if (count < `EP) //计数小于终止符      count <= count + 1;  end   always @ (posedge clk or negedge rst_n)  begin  : lsm_2s2  //线性序列机一段闭节点    if (!rst_n)  //复位      begin        txd <= 1;   //发送线为高        rdreq <= 0;  //读请求为0        temp <= 0;  //中间寄存器为0      end     else if ((count ><= 1;    else       case (count)        0  :  begin              rdreq <= 0;  //读请求拉低              txd <= 0;            end         1  :  temp[7:0] <= data[7:0];  //输入数据给中间寄存器        1*16  :  txd <= temp[0];   //中间寄存器按位给发送线发送        2*16  :  txd <= temp[1];        3*16  :  txd <= temp[2];        4*16  :  txd <= temp[3];        5*16  :  txd <= temp[4];        6*16  :  txd <= temp[5];        7*16  :  txd <= temp[6];        8*16  :  txd <= temp[7];        9*16  :  txd <= 1;    //拉高      endcase       end   endmodule

接纳模块receiver。代码:

`include "uart_lsm_head.v"module receiver(clk, rst_n, data, wrreq, rxd); //uart接纳模块LSM(线性序列机) input clk, rst_n; //输入时钟复位 output reg [7:0] data; //输出数据 output reg wrreq; //输出写恳求 input rxd; //输入接纳线信号 reg [7:0] count; //宏界说 `define EP 184 //终止符 `define GET0 24 `define GET1 `GET0+16 `define GET2 `GET1+16 `define GET3 `GET2+16 `define GET4 `GET3+16 `define GET5 `GET4+16 `define GET6 `GET5+16 `define GET7 `GET6+16 `define GETW `GET7+16 //wrreq=1 `define GLRW `GETW+1 //wrreq=0 always (posedge clk or negedge rst_n) begin : lsm_2s1 //线性序列机一段闭节点 if(!rst_n) count。
= `EP) && !rxd) //rxd=0      count <= 0;    else if (count < `EP)      count <= count + 1;  end  always  (posedge clk or negedge rst_n)    begin  : lsm_2s2   //线性序列机二段闭节点           if(!rst_n)        begin                data <= 0;          wrreq <= 0;      //写恳求为0        end       else        case(count)          `GET0  :  data[0] <= rxd;   //将接纳的数据经过data输出          `GET1  :  data[1] <= rxd;          `GET2 :   data[2] <= rxd;          `GET3 :   data[3] <= rxd;          `GET4 :   data[4] <= rxd;          `GET5 :   data[5] <= rxd;          `GET6 :   data[6] <= rxd;          `GET7 :   data[7] <= rxd;          `GETW :   wrreq <= 1;   //写恳求拉高一拍,写进fifo          `GLRW :   wrreq <= 0;   //一拍后写恳求为0        endcase    endendmodule。 <= `EP;    else if((count ><= 0;    else if (count < `EP)      count <= count + 1;  end  always @ (posedge clk or negedge rst_n)    begin  : lsm_2s2   //线性序列机二段闭节点           if(!rst_n)        begin                data <= 0;          wrreq <= 0;      //写请求为0        end       else        case(count)          `GET0  :  data[0] <= rxd;   //将接收的数据通过data输出          `GET1  :  data[1] <= rxd;          `GET2 :   data[2] <= rxd;          `GET3 :   data[3] <= rxd;          `GET4 :   data[4] <= rxd;          `GET5 :   data[5] <= rxd;          `GET6 :   data[6] <= rxd;          `GET7 :   data[7] <= rxd;          `GETW :   wrreq <= 1;   //写请求拉高一拍,写进fifo          `GLRW :   wrreq <= 0;   //一拍后写请求为0        endcase    endendmodule

参数。宏的头文件代码。

/////uart_lsm_head.v//////////界说时标////////////`。
ti。mescale 1us/1ns/////////界说规划参数/////////`define BAUD_RATE 9600   //波特率=9600`define SYS_CLK 100000000 //体系时钟sys_clk 频率=100M`define REF_CLK 50000000 //体系时钟ref_clk频率=50M//////////运用宏主动核算的诸参数////////////`define TBAUD_RATE (1000000.0/`BAUD_RATE)//波特率周期`define UART_CLK (16*`BAUD_RATE)        //uart_clk 等于16倍波特率`define TUART_CLK (1000000.0/`UART_CLK) //uart_clk周期`define TEN_TUART_CLK (10.0*`TUART_CLK) //10倍uart_clk周期`define TUART_CLK100 (100.0*`TUART_CLK) //100倍uart_clk周期`define TUART_CLK_HALF (`TUART_CLK/2.0) //uart_clk半周期`define TREF_CLK (1000000.0/`REF_CLK)  //参阅时钟周期`define TREF_CLK_HALF (`TREF_CLK/2.0)  //参阅时钟半周期//////////运用宏主动核算的分频数(占空比50%)////////////`define DW (`SYS_CLK/(2*`UART_CLK))
仿真。

测验。

transmitter(发送)模块的测验代码:`include "uart_lsm_head.v"module transmitter_tb; reg clk, rst_n; reg empty; reg [7:0] data; wire rdreq; wire txd; reg [7:0] temp; transmitter transmitter_dut( .clk(clk), .rst_n(rst_n), .empty(empty), .data(data), .rdreq(rdreq), .txd(txd) ); initial begin clk = 1; rst_n = 0; data = 0; empty = 1; temp = 0; #200.1 rst_n = 1; #200.1 empty=1;temp=8'h55; #`TBAUD_RATE data[0] = temp[0]; //发送第一个信息位(LSB) #`TBAUD_RATE data[1] = temp[1]; #`TBAUD_RATE data[2] = temp[2]; #`TBAUD_RATE data[3] = temp[3]; #`TBAUD_RATE data[4] = temp[4]; #`TBAUD_RATE data[5] = temp[5]; #`TBAUD_RATE data[6] = temp[6]; #`TBAUD_RATE data[7] = temp[7]; #`TBAUD_RATE empty = 0; #2000 $stop; end always #`TUART_CLK_HALF clk = ~clk; endmodule。

receiver(接纳)模块的测验代码:`include "uart_lsm_head.v"module receiver_tb; reg clk, rst_n; reg rxd; wire [7:0] data; wire wrreq; reg [7:0] temp; //8位的中心寄存器,发生鼓励 receiver receiver_dut( .clk(clk), .rst_n(rst_n), .data(data), .wrreq(wrreq), .rxd(rxd) ); initial begin clk = 1; rst_n = 0; temp = 0; rxd = 1; #`TEN_TUART_CLK //*代表异步 //10倍uart_clk周期 rst_n = 1; #`TEN_TUART_CLK //发动一个中止位 rxd = 0; temp = 8'h55; #`TBAUD_RATE //数据运用波特率的周期 rxd = temp[0]; //发送一个信息位(LSB) #`TBAUD_RATE rxd = temp[1]; #`TBAUD_RATE rxd = temp[2]; #`TBAUD_RATE rxd = temp[3]; #`TBAUD_RATE rxd = temp[4]; #`TBAUD_RATE rxd = temp[5]; #`TBAUD_RATE rxd = temp[6]; #`TBAUD_RATE rxd = temp[7]; //发送最终一个信息位(HSB) #`TBAUD_RATE rxd = 1; #`TUART_CLK100 $stop; //100倍uart_clk周期 end always #`TUART_CLK_HALF clk = ~clk; // uart_clk 的时钟,运用uart_clk的半周期endmodule。

仿真图:

分别为发送和接纳做仿真测验。发送的仿真波形如下:

接纳的仿真波形如下:

依据以上两个仿真波形,能够发现规划是正确的,之后则可运用串口猎人的。

上位机。

软件,完成自发自收。

内容来源:https://artdesignphuong.com/app-1/tai k8vin fun,http://chatbotjud.saude.mg.gov.br/app-1/aplicativo-do-tigre-para-ganhar-dinheiro

(责任编辑:女性)

    系统发生错误

    系统发生错误

    您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

    [ 错误信息 ]

    页面发生异常错误,系统设置开启调试模式后,刷新本页查看具体错误!