rs串口verilog代码
verilog 逻辑函数 串口发送
verilog 逻辑函数串口发送
摘要:
1.Verilog 逻辑函数概述
2.串口发送原理
3.Verilog 实现串口发送的逻辑函数
4.应用实例
正文:
【1.Verilog 逻辑函数概述】
Verilog 是一种硬件描述语言,主要用于数字电路和模拟混合信号电路的描述。它的语法简洁,易于理解和使用。在数字电路设计中,逻辑函数是基本的构建模块,通过组合这些模块可以实现复杂的数字电路。
【2.串口发送原理】
串口(Serial Port)是一种计算机硬件接口,可以通过串行通信传输数据。发送数据时,数据被逐个比特按顺序传送,这样可以减少线路的传输次数,提高通信效率。在电子设备中,如单片机、FPGA 等,通常会使用串口进行数据通信。
【3.Verilog 实现串口发送的逻辑函数】
要实现串口发送功能,首先需要设计一个状态机,控制数据的发送过程。下面是一个简单的Verilog 代码示例,实现一个8 位串口发送器:```verilog
module serial_port_sender(
input wire clk, // 时钟信号
input wire rst_n, // 低电平复位信号
input wire start, // 开始发送信号
input wire [7:0] data, // 发送数据
output wire busy // 忙碌信号
);
// 定义状态机
typedef enum logic [1:0] {IDLE, SENDING} state_t; state_t current_state, next_state;
基于FPGA Verilog RS232串口回环测试例程,附源程序仿真源码及测试图片
FPGA Verilog RS232串口回环测试
基于FPGA Verilog RS232串口回环测试例程,支持多byte数据传输,附源程序仿真源码及测试图片。
测试基于SSCOM/友善之臂上位机软件测试,测试结果如下图一图二所示。
图一SSCOM
图二
图三连续发送仿真截图
图四连续接收仿真截图
后附verilog源程序代码及testbech仿真例程,注释欠。
重点:多byte回环测试要点,上位机串口多位数据连续发送停止位和起始位之间无间隔,回环程序在接收和发送都需要具备在停止位后能立马跳转到下一个起始位的能力。重点关注cnt_bit的处理方式。
附录1 顶层例化
uart_txd uart_txd(
.clk_50m(sys_clk_50m),
.reset_n(sys_rst_n),
.tx_data(rx_data),
.baud_set(3'd4),
.send_en(rx_done),
.send_done(),
.send_busy(send_busy),
.uart_tx(uart_tx)
);
uart_rxd uart_rxd(
.clk_50m(sys_clk_50m),
.reset_n(sys_rst_n),
.rx_data(rx_data),
.baud_set(3'd4),
.rx_done(rx_done),
.rx_busy(rx_busy),
.uart_rx(uart_rx)
);
附录2 串口发送源程序
`timescale1ns/1ps
///////////////////////////////////////////////////////////////////// /////////////
基于verilog的很基础的RS232串口收发代码
基于verilog的很基础的RS232串口收发代码
写代码,记笔记,防忘记,须牢记。
写串口的Verilog代码关键是要搞明白RS232串口的通信协议,它并不像单片机,直接读写SBUF就可实现串口的收发功能,收发整个字节。而FPGA要一位一位的收发,因此必须了解RS232的数据格式。
起始位:RS232约定一位起始位“0”。
停止位:约定停止位为“1”。可选一位或两位停止位。
奇偶校验位:可选。
通过串口发送数据时,要严格遵守RS232的数据格式,先发送起始位,然后是数据,最后是停止位(无奇偶校验的情况)。
通过串口接收数据时,若接收端无数据输入,会一直处于高电平,若开始接收数据,会首先收到来自串口的起始位“0”,然后是要接收的数据,最后为停止位(无奇偶校验的情况)。所以对于接收模块,可如此设计,FPGA一直检测接收端是否有下降沿到来,直到检测到下降沿,才开始接收数据。
波特率设置的重要性不言而喻,毋庸赘述。
此设计为最基础的串口收发代码,控制逻辑简单,适合编写第一次编写串口代码的朋友。
此设计收发的数据格式为1位起始位,1位停止位,无奇偶校验位,8位数据位。波特率为19200,代码中可随意更改。
具体Verilog代码如下:
顶层模块
`timescale 1ns / 1ps
/////////////////////////////////////////////////////////////////// /////////////
// Company : 杭州电子科技大学
// Engineer : 晓晓川
Verilog_串口通信_1113
踏雪无痕的博客
串口通信是目前比较重要的一种通信方式,主要是用于计算机和外部的通信。首先简单的介绍一下串口通信的原理:
串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线(GND),(2)发送(TXD),(3)接收(RXD)。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其它线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验位。对于两个进行通信的端口,这些参数必须匹配:a,波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。当我们提到时钟周期时,我们就是指波特率例如如果协议需要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB 设备的通信。b,数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII 码是0~255(8位)。如果数据使用简单的文本(标准ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。c,停止位:用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。d,奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位位1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步
verilog设计一个串行数据检测器
v e r i l o g设计一个串行
数据检测器
Document serial number【NL89WT-NY98YT-NC8CB-NNUUT-NUT108】
题目:设计一个串行数据检测器。要求是:连续4个或4个以上为1时输出为1,其他输入情况下为0。
代码如下:
module four_one( x, z, clk, rst, state);
input x, clk, rst;
output z;
output[2:0] state;
reg[2:0] state;
wire z;
parameter
IDLE = 'd0,
A = 'd1,
B = 'd2,
C = 'd3,
D = 'd4;
assign z = (state == D) 1 : 0;
always @(posedge clk or negedge rst)
if (!rst)
begin
state <= IDLE;
end
else
casex (state)
IDLE: if (x == 1)
begin
state <= A;
end
else
begin
state <= IDLE;
end
A: if (x == 1)
begin
state <= B;
end
else
begin
state <= IDLE;
end
B: if (x == 1)
begin
state <= C;
end
else
begin
state <= IDLE;
end
C: if (x == 1)
begin
state <= D;
end
else
begin
state <= IDLE;
verilog RS232 串口通信 verilog
//=============================顶层模块=====================================module uart_top(clk,rs232_rx,rs232_tx);input clk; //时钟信号50Minput rs232_rx; //数据输入信号output rs232_tx; //数据输出信号wire clk_bps1,clk_bps2;wire bps_start1,bps_start2;wire [7:0] rx_data;reg [7:0] tx_data;reg [7:0] rx_data1; reg [7:0] rx_data2; reg [7:0] rx_data3; reg [7:0] rx_data4; //接收数据存储器,用来存储接收到的数据,直到下一个数据接收wire rx_int; //接收数据中断信号,接收过程中一直为高,reg [29:0] rst_cnt;reg rst_n;initial beginrst_cnt<=0; rst_n<=0;endalways @(posedge clk ) beginif(rst_cnt<20000000) rst_cnt<=rst_cnt+1'b1;if (rst_cnt>10000) beginrst_n<=1;endelsebegin rst_n<=0;endendspeed_select_rx speed_rx(//波特率选择模块.clk(clk), .rst_n(rst_n), .clk_bps(clk_bps1),.bps_start(bps_start1)); uart_rx uart_rx(//数据接收模块.clk(clk), .rst_n(rst_n), .bps_start(bps_start1), .clk_bps(clk_bps1), .rs232_rx(rs232_rx),.rx_data(rx_data), .rx_int(rx_int));reg [7:0] int_cnt;reg [1:0] addr;wire data_flg;always @(posedge clk or posedge rx_int)beginif(rx_int)int_cnt<=8'd0;else beginif(int_cnt<250) int_cnt<=int_cnt+1'b1;endendassign data_flg=(int_cnt==10)?1'b1:1'b0;always @(posedge data_flg or negedge rst_n)beginif(!rst_n)addr<=0;else begin addr<=addr+1'b1;endendalways @(negedge data_flg )beginif(addr==0)rx_data1<=rx_data;else if(addr==1)rx_data2<=rx_data;else if(addr==2)rx_data3<=rx_data;else if(addr==3)rx_data4<=rx_data;end reg [21:0] out_cnt;reg [1:0]addr_r;reg data_flg_r;always @(posedge clk or posedge rx_int)beginif(rx_int)out_cnt<=20'd0;else beginif(out_cnt<4194300) out_cnt<=out_cnt+1'b1;if((out_cnt<60000)||((out_cnt>1000000)&&(out_cnt<1060000))||((out_cnt>2000000)&&(out_cnt<2060000))||((out_cnt>3000000)&&(out_cnt<3060000)))begin data_flg_r<=1'b1;endelse begindata_flg_r<=1'b0;endendendalways @(posedge data_flg_r or negedge rst_n)beginif(!rst_n)addr_r<=8'd0;else beginaddr_r<=addr_r+1'b1;endendalways @(negedge data_flg_r )beginif(addr_r==0)tx_data<=rx_data4;else if(addr_r==1)tx_data<=rx_data3;else if(addr_r==2)tx_data<=rx_data2;else if(addr_r==3)tx_data<=rx_data1;endspeed_select_rx speed_tx( //波特率选择模块.clk(clk)
VerilogRS232串口模块实验报告范文
VerilogRS232串口模块实验报告范文
1设计概述
实验功能:实现RS232的双工通信。
实验环境:1)硬件环境:PC机一台、ml507PFGA开发套件;2)软件
环境:开发软件ISE14.5、代码编写软件Notepad++、仿真软件Modelim、调试软件chipcope、串口调试工具。
2设计原理
2.1串行接口RS232工作原理
串口用来连接FPGA和PC机,RS-232允许全双工通信,即计算机在
接收数据的同时可以发送数据。串口按位(bit)发送和接收字节。通常
以8位数据为1组,先发送最低有效位,最后发送最高有效位。尽管比按
字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时
用另一根线接收数据。
通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串
口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。数据的传输没有时钟信号,接收端
必须采取某种方式,使之与接收数据同步。
1)串行线缆的两端先约定好串行传输的参数(传输速度、传输格式等);
2)当没有数据传输的时候,发送端向数据线上发送"1";
3)每传输一个字节之前,发送端先发送一个"0"来表示传输已经开始,这样接收端便可以知道有数据到来了;
图1数据帧结构
4)开始传输后,数据以约定的速度和格式传输,所以接收端可以与之同步;
5)在串口总线上高电平是默认的状态,当一帧数据开始传输必须先拉低电平,这就是起始位,起始位之后是8位数据位,最后是校验位和停止位(可不加校验位)。传输完成一个字节之后,都在其后发送一个停止位("1")。(图1)
RS(10-8)分析及verilog代码
RS(10,8)分析及verilog代码
RS(10,8)原理图:
*dataout输入到加法器不用转换到GF域,输入以后的信号全是在GF域中运算。
GF(2^4)元素列表:
GF域的元素都由a^0,a^1,,,a^(m-1)及其组合构成。
GF(2^4)元素由a^0,a^1,a^2,a^3及其组合构成。
其它值是在元素a^m的基础上求得,a^m由本原多项式f(x)=x^4+x+1求得
因为a是本原多项式的一个解,所以
a^4+a+1=0
得元素a^4=a+1
其它元素a^i=a^(i-1)*a,结果中有等于a^4,由a+1代替计算。
如a^7=a^6*a=(a^3+a^2)a=a^4+a^3=a^3+a+1
GF域的加减法和乘法:
加减法:各对应位异或。如0010+1011=1001
乘法:权相加(十进制加法),对大于最大权值2^m-1的值求余。2^13*2^5=2^(13+5)=2^18=2^3 乘法器系数值获得:
生成多项式g(x)=(x+a)(x+a^2),,,,,,,,(x+a^(n-k))
GF(2^4)域的生成多项式为
g(x)=(x+a)(x+a^2)
=x^2+(a^2+a)x+a*a^2
=x^2+(a^5)x+a^3
所以g0=a^3,g1=a^5
设输入信息多项式为m和输出多项式为q
分别表示为
m=m[3]a^3+m[2]a^2+m[1]a^1+m[0]a^0
q=q[3]a^3+q[2]a^2+q[1]a^1+q[0]a^0
其中:m[n],q[n]表示输入信息第n位的值(0或1),a^n表示权
那么以g1所在的乘法器为例有:
串口RS232通信程序(Verilog)
串口RS232通信程序(Verilog)
串口有9个管脚,其中只有三个是最重要的,分别是
pin 2: RxD (receive data). 接收数据
pin 3: TxD (transmit data). 发送数据
pin 5: GND (ground). 地
串行通信时序
我们先来看看字节0x55的发送
0x55的二进制代码是01010101,但发送时由低字节开始的,因此发送次序依次为1-0-1-0-1-0-1-0.
串行通信电平
·"1" is sent using -10V (or between -5V and -15V).
·"0" is sent using +10V (or between 5V and 15V).
由于计算机RS232的电平与电路板(通常+5V)之间电平的不同所以要用到转换芯片
如果PCB板电源+-5V的话用MAX232
如果PCB板(FPGA)电源是+-3.3V的话用MAX3232
这个图的串口如果采用母头的话,要用交叉公母线,保证是PCB板上这边的RxD连计算机的TxD(3 Pin),PCB板这边的TxD连计算机的RxD(2 Pin).
串行通信波特率
这里要弄清楚波特率与比特率的差别:
比特率是数字信号的传输速率,它用单位时间内传输的二进制代码的有效位(bit)数来表示,其单位为每秒比特数bit/s(bps)、每秒千比特数(Kbps)或每秒兆比特数(Mbps)来表示(此处K和M分别为1000和1000000,而不是涉及计算机存储器容量时的1024和1048576)。
波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,其单位为波特(Baud)。
RS232设计报告和verilog代码,含testbench,可以直接运行
RS232接口数据转发协议实验报告1.设计要求
设计RS232接口数据转发协议,将8位并行数据转发为RS232协议的串口数据发送出去。
entity rs232
port ( clk: in std_logic; -- 16MHz输入时钟
rdy: in std_logic; --数据准备好信号, 1个时钟周期的正脉冲
data: in std_logic_vector(7 downto 0); --要发送的并行数据
bps: in std_logic_vector(1 downto 0); --波特率设置
-- 00:4800bps 01:9600 10:19200 11:38400
parity : in std_logic; --奇偶校验控制,0:奇校验 1:偶校验
d_out: out std_logic); --串行数据输出
end rs232;
协议要求:
(1)波特率:4800/ 9600/19200/38400可选
(2)8位数据位,1位停止位,偶校验可选
设计要求:
(1)采用VHDL或Verilog语言设计上述电路;
(2)写出测试激励文件,并仿真;
(3)分析仿真结果,并撰写设计报告.
(4)提交完整的纸质设计报告并附源代码.
2.接口协议要求
一个字符一个字符传输,每传一个字符总是以起始位开始,以停止位结束,字符之间没有固定时间间隔要求。波特率可在4800、9600、19200、38400中选择。
每一个字符前面都有一位起始位(低电平),字符本身有5-7位数据位,接着是一位校验位,最后是一位停止位。停止位和空闲位规定必须为高电平
串口通讯设计之Verilog实现
串口通讯设计之V e r i l o g实现
FPGA串口模块是将由RS-485发送过来的数据进行处理,提取出8位有效数据,并按异步串口通讯的格式要求输出到MAX3223的12脚;FPGA选用Xilinx公司的SpartanII系列xc2s50;此部分为该设计的主体;如上所述,输入数据的传输速率为700k波特率;为了使FPGA能够正确地对输入数据进行采样,提高分辨率能力和抗干扰能力,采样时钟必须选用比波特率更高的时钟,理论上至少是波特率时钟的2倍;
1 串口通信基本特点随着多微机系统的应用和微机网络的发展,通信功能越来越显得重要;串行通信是在一根传输线上一位一位地传送信息.这根线既作数据线又作联络线;串行通信作为一种主要的通信方式,由于所用的传输线少,并且可以借助现存的电话网进行信息传送,因此特别适合于远距离传送;在串行传输中,通信双方都按通信协议进行,所谓通信协议是指通信双方的一种约定;约定对数据格式、同步方式、传送速度、传送步骤、纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守;异步起止式的祯信息格式为:每祯信息由四部分组成:
位起始位;
~8位数据位;传送顺序是低位在前,高位在后.依次传送;c.一位校验位,也可以没有;d.最后是1位或是2位停止位;
FPGAField Pmgrammable Gate Array现场可编程门阵列在数字电路的设计中已经被广泛使用;这种设计方式可以将以前需要多块集成芯片的电路设计到一块大模块可编程逻辑器件中,大大减少了电路板的尺寸,增强了系统的可靠性和设计的灵活性;本文详细介绍了已在实际项目中应用的基于FPGA的串口通讯设计;
Verilog实现串口接收多帧数据
Verilog实现串⼝接收多帧数据`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 19:50:45 04/19/2015
// Design Name:
// Module Name: Serial_Decoder
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Serial_Decoder(
input wire clk_seri, //串⼝时钟,⽤于从串⼝发送命令给FPGA input wire rst,
input wire RxD,
output reg[1:0] modu_sel, //BPSK,QPSK,8PSK选择
output reg[13:0] ser_asf, //由串⼝发过来的asf
output reg[31:0] ser_ftw, //由串⼝发过来的ftw
Verilog之串口(UART)通信
Verilog之串口(UART)通信
0:起始位,低电平;1~8:数据位;9:校验位,高电平;10:停止位,高电平。
波特率“9600bps”表示每秒可以传输9600位。
波特率定时计数器由时钟频率除以波特率。
采集1~8位,忽略0、9、10位。
发送“0、8位数据、1、1”
串口传输数据,从最低位开始,到最高位结束。
串口发送:
module tx_bps_module
(
CLK, RSTn,
Count_Sig,
BPS_CLK
);
input CLK;
input RSTn;
input Count_Sig;
output BPS_CLK;
/***************************/
reg [12:0]Count_BPS;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
Count_BPS <= 13'd0;
else if( Count_BPS == 13'd5207 )
Count_BPS <= 13'd0;
else if( Count_Sig )
Count_BPS <= Count_BPS + 1'b1;
else
Count_BPS <= 13'd0;
/********************************/
assign BPS_CLK = ( Count_BPS == 13'd2604 ) ? 1'b1 : 1'b0; /*********************************/
endmodule
verilog串口通信程序
verilog串⼝通信程序
FPGA实现RS-232串⼝收发的仿真过程(Quartus+Synplify+ModelSim)(2007-09-11 12:17:37)
⽹上关于RS-232的异步收发介绍得很多,最近没事学着摸索⽤ModelSim来做时序仿真,就结合
⽹上的参考资料和⾃⼰的琢磨,做了这个东西。
针对我这个⼩程序结合FPGA的开发流程,主要⾛了以下⼏步:
1. ⽂本程序输⼊(Verilog HDL)
2. 功能仿真(ModelSim,查看逻辑功能是否正确,要写⼀个Test Bench)
3. 综合(Synplify Pro,程序综合成⽹表)
4. 布局布线(Quartus II,根据我选定的FPGA器件型号,将⽹表布到器件中,并估算出相应的时延)
5. 时序仿真(ModelSim,根据时延做进⼀步仿真)
这⾥贴出我的程序和各个详细步骤,能和各位正在学习的新⼿们⼀起分享。
0. 原理
略
⼀、⽂本程序输⼊(Verilog HDL)
发送端:
module trans(clk,
rst,
TxD_start,
TxD_data,
TxD,
TxD_busy
);
input clk,
rst,
TxD_start;
input[7:0] TxD_data; lk(clk),
.rst(rst),
.TxD_start(TxD_start),
.TxD_busy(TxD_busy),
.TxD_data(TxD_data),
.TxD(TxD)
);
rcv rcv(.clk(clk),
.rst(rst),
.RxD(TxD), xD_data(RxD_data),
串行器verilog代码
串行器verilog代码
串行器(Serializer)是一种电子设备,用于将并行数据转换为串行数据,以便在单个通道上进行传输。以下是一个简单的串行器的 Verilog 代码示例:
verilog
module Serializer (
input wire clk, // 时钟信号
input wire reset, // 复位信号
input wire [7:0] parallel_data, // 并行数据输入
output reg serial_data // 串行数据输出
);
reg [2:0] shift_reg; // 移位寄存器,用于存储并行数据的位
reg [2:0] count; // 计数器,用于控制移位寄存器的移位次数
always @(posedge clk or posedge reset) begin
if (reset) begin
// 当复位信号为高电平时,将计数器和移位寄存器清零
count <= 0;
shift_reg <= 0;
serial_data <= 0;
end else begin
if (count == 3'd7) begin
// 当计数器达到最大值时,将并行数据的最低位存入移位寄存器,并将计数器清零
shift_reg <= {parallel_data[0], shift_reg[2:1]};
count <= 0;
end else begin
// 否则,将移位寄存器向左移动一位,并将计数器加1
shift_reg <= {shift_reg[1:0], serial_data};
串口发送端verilog代码分析
串⼝发送端verilog代码分析
串⼝发送端verilog代码分析
1 `timescale 1ns / 1ps
2//////////////////////////////////////////////////////////////////////////////////
3// Company:
4// Engineer: chensimin
5//
6// Create Date: 2018/05/23 13:59:45
7// Design Name:
8// Module Name: uart_tx
9// Project Name:
10// Target Devices:
11// Tool Versions:
12// Description:
13//
14// Dependencies:
15//
16// Revision:
17// Revision 0.01 - File Created
18// Additional Comments:
19//
20//////////////////////////////////////////////////////////////////////////////////
21
22
23module uart_tx(
24
25input wire clk,
26input wire receive_ack,
27input wire [7:0]data_o,
28output reg txd
29
30 );
31
32localparam IDLE = 0,
33 SEND_START = 1,
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UART是通用异步收发器的简称,其中有一种电平规范较RS232规范,它用-3~-15V表示正逻辑,3~15V表示负逻辑,通过FPGA芯片实现RS232通信首先要解决的就是FPGA电平和RS232电平之间的矛盾,通常采用MAX3232作为物理层的电平接口,根据MAX3232提供的标准配制方式把物理电路设计好后,接下来的通信就是要实现逻辑的接收和发送……
设计最简单的RS232通信逻辑,FPGA实现将接收到的数据会发出去,总共两个数据传输引脚,一收一发。将此通信模块分为三个部分:接收模块,波特率控制模块,发送模块。
工作原理:此模块接收MAX3232传过来的串行数据,对齐进行判断采样,校验,最后将数据流中的串行数据转换为八位并行数据,将此八位数据储存,或送给发送模块发送出去。根据RS232通信标准器串行数据分为起始位、数据位、校验位、停止位,空闲时为高电平,起始位通常为低电平,数据位通常为8位,校验位分为奇校验、偶校验等,停止位一位或两位且为高电平。FPGA接收模块对此数据进行异步接收,首先就要检测其数据传输开始标识,当然就是检测开始位,于是要有下降沿检测电路,检测到下降沿是输出一高脉冲,此电路可以用两个D触发器加上基本门电路实现,脉冲触发开始进入接收状态,输出接收状态标志位,使其为1,此标志位使能波特率控制模块输出采样脉冲,此计数脉冲触发接收模块中的计数器计数,加到相应的位就把当前的串行总线上的值赋给缓冲器,或对其判断,当计数完成11次计数后,已将8位串行数据转成并行数据到缓冲器中,且进行了校验的判断和停止位的判别,这是接收状态结束,接收状态位置0,计数器清零。对于波特率产生模块用于控制采样数据脉冲的周期,其周期就为串行数据传送一个bit所用的时间,根据此时间和时钟周期设置计数值。当接收模块完成工作时,接收状态位为0时可以触发发送模块,发送模块检测接收状态的下降沿,由此产生一高脉冲,与发送模块类似,根据波特率控制模块产生的计数脉冲将并行数据转成串行数据,并加上开始位、校验位、停止位。由此完成整个串行通信模块。
要熟悉:下降沿检测程序设计,并转串设计等。
顶层模块图如下所示:
各模块的程序如下:
//本程序实现rs232通信中的串行数据接收模块
module rs232_rx(
//input
clk,//50M的时钟输入
rst_n,//低电平复位信号输入
rx_cnt_pluse,//采样脉冲输入,总共11个采样脉冲,一个时钟宽度的高电平
rs232_in_s,//串行数据输入,空闲时为高电平,1bit低电平作为起始位,接着8bit数据位LSB传输模式,接着偶数校验位,接着1bit低电平作为停止位
//output
rs232_out_p,//输出8位并行数据
rx_flag,//数据接收状态输出,接收状态下为高电平,其余为低电平
rx_error_flag//接收校验错误标识位,若检测奇数校验位或者停止位不正确时输出高电平 );
parameter WIGTH=8;
input clk,rst_n;
input rx_cnt_pluse;
input rs232_in_s;
output [WIGTH-1:0] rs232_out_p;
output rx_flag;
output rx_error_flag;
reg [3:0] cnt=0;
reg rx_flag=0;
reg [WIGTH-1:0] rs232_out_p;
reg rs232_in_s_r1,rs232_in_s_r2,rs232_in_s_r3,rs232_in_s_r4;
wire rs232_in_s_start_flag;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rs232_in_s_r1<=0;
rs232_in_s_r2<=0;
end
else//串行数据开始传输检测电路,检测其下降沿,有下降沿是输出一个clk宽度的高脉冲begin
rs232_in_s_r1<=rs232_in_s;
rs232_in_s_r2<=rs232_in_s_r1;
rs232_in_s_r3<=rs232_in_s_r2;
rs232_in_s_r4<=rs232_in_s_r3;
end
end
assign
rs232_in_s_start_flag=rs232_in_s_r4&(~rs232_in_s_r1)&(~rs232_in_s_r2)&(~rs232_in_ s_r3);
always@(posedge clk or negedge rst_n)
begin//接收状态控制电路,第一个下降沿时标识位置高,当cnt计数到11时置低
if(!rst_n)
rx_flag<=0; //数据接收状态输出,接收状态下为高电平,其余为低电平
else if(rs232_in_s_start_flag)
rx_flag<=1;
else if(cnt==11)
rx_flag<=0;
end
reg rx_error_flag_r1,rx_error_flag_r2;
rx_error_flag//接收校验错误标识位,若检测奇数校验位或者停止位不正确时输出高电平reg [WIGTH-1:0] rs232_out_p_temp=0;
always@(posedge clk or negedge rst_n)
begin//串转并逻辑
if(!rst_n)
begin
cnt<=0;
rs232_out_p_temp<=0;
rx_error_flag_r1<=0;
rx_error_flag_r2<=0;
end
else if(rx_flag)//接收有效状态下,开始接收数据
begin
if(rx_cnt_pluse)//采样脉冲出发cnt累加
// rx_cnt_pluse,//采样脉冲输入,总共11个采样脉冲,一个时钟宽度的高电平
begin
cnt<=cnt+1;
case(cnt)//将当前串行数据输入线上的数据锁存到寄存器的相应的位
1: rs232_out_p_temp[0]<=rs232_in_s;
2: rs232_out_p_temp[1]<=rs232_in_s;
3: rs232_out_p_temp[2]<=rs232_in_s;
4: rs232_out_p_temp[3]<=rs232_in_s;
5: rs232_out_p_temp[4]<=rs232_in_s;
6: rs232_out_p_temp[5]<=rs232_in_s;
7: rs232_out_p_temp[6]<=rs232_in_s;
8: rs232_out_p_temp[7]<=rs232_in_s;
9: