当前位置:文档之家› Verilog程序6、UART(串口通信)

Verilog程序6、UART(串口通信)

这个程序没有仿真、没有测试。

1 UART功能设计1.1 UART的工作原理异步通信时,UART发送/接收数据的传输格式如图1所示,一个字符单位由开始位、数据位、停止位组成。

异步通信的一帧传输经历以下步骤:(1)无传输。

发送方连续发送信号,处于信息“1”状态。

(2)起始传输。

发送方在任何时刻将传号变成空号,即“1”跳变到“O”,并持续1位时间表明发送方开始传输数据。

而同时,接收方收到空号后,开始与发送方同步,并期望收到随后的数据。

(3)奇偶传输。

数据传输之后是可供选择的奇偶位发送或接收。

(4)停止传输。

最后是发送或接收的停止位,其状态恒为“1”。

其程序的结构框图如下:该程序的效果是串口接受到从计算机发送过来的数据后,又把数据发回给计算机,串口通信是串行的。

其uart.v为顶层文件,包含其他模块,speed_select.v文件的作用为为uart_rx.v和uart_tx.v 设置波特率。

uart.v(顶层文件)`timescale 1ns / 1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 16:08:27 11/12/2010// Design Name:// Module Name: uart// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart(clk,rst_n,rs232_rx,rs232_tx);input clk,rst_n,rs232_rx;output rs232_tx;wire bps_start1,bps_start2,clk_bps1,clk_bps2,rx_int;wire [7:0] rx_data;//发送模块的时钟speed_select speed_tx (.clk(clk),.rst_n(rst_n),.bps_start(bps_start2),.clk_bps(clk_bps1));//接受模块的时钟speed_select speed_rx (.clk(clk),.rst_n(rst_n),.bps_start(bps_start2),.clk_bps(clk_bps2));//接受模块uart_rx uart_rx (.clk(clk),.rst_n(rst_n),.clk_bps(clk_bps1),.rs232_rx(rs232_rx),.bps_start(bps_start1),.rx_int(rx_int),.rx_data(rx_data));//发送模块uart_tx uart_tx (.clk(clk),.rst_n(rst_n),.clk_bps(clk_bps2),.rx_int(rx_int),.rx_data(rx_data),.bps_start(bps_start2),.rs232_tx(rs232_tx));endmodulespeed_select.v`timescale 1ns / 1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 16:12:45 11/12/2010// Design Name:// Module Name: speed_select// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module speed_select(clk,rst_n,bps_start,clk_bps);input clk,rst_n,bps_start;output clk_bps;reg [12:0] cnt;reg clk_bps_r;/*波特率对应的脉冲的个数。

计算方法如下:以9600bps为例:1s/9600/20ns=5208.33333,即有5208个周期。

parameter bps9600 = 5208,bps19200 = 2604,bps38400 = 1302,bps57600 = 868,bps115200 = 434;个数的一半,即在周期的中间位置。

进行采样。

parameter bps9600_2 = 2604,bps19200_2 = 1302,bps38400_2 = 652,bps57600_2 = 434,bps115200_2 =217;*/`define bps9600 5208`define bps9600_2 2604always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt <= 0;else if((cnt == `bps9600)|| !bps_start) //在bps_start为低时,进行开始计数,bps_start 为高时,停止计数。

cnt <= 0;elsecnt <= cnt+1;endalways @(posedge clk or negedge rst_n)if(!rst_n)clk_bps_r <= 0;else if(cnt == `bps9600_2) //岂不是只在一个时刻为高电平clk_bps_r <= 1;elseclk_bps_r <= 0;assign clk_bps = clk_bps_r;endmoduleuart_rx.v`timescale 1ns / 1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 16:14:13 11/12/2010// Design Name:// Module Name: uart_rx// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_rx(clk,rst_n,clk_bps,rs232_rx,bps_start,rx_int,rx_data); input clk,rst_n,clk_bps,rs232_rx;output bps_start,rx_int;output [7:0] rx_data;//接受数据寄存器,捕捉rs232_rx的下降沿reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;wire neg_rs232_rx; //表示数据线接收到下降沿always @(posedge clk or negedge rst_n)if(!rst_n)beginrs232_rx0 <= 1'b0;rs232_rx1 <= 1'b0;rs232_rx2 <= 1'b0;rs232_rx3 <= 1'b0;endelsebeginrs232_rx0 <= rs232_rx;rs232_rx1 <= rs232_rx0;rs232_rx2 <= rs232_rx1;rs232_rx3 <= rs232_rx2;end//下面的下降??检测??以滤掉20ns-40ns之间的毛刺。

assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx;reg bps_start_r;reg [3:0] num;reg rx_int;always @(posedge clk or negedge rst_n)if(!rst_n)beginbps_start_r <= 1'bz;rx_int <= 1'b0;endelse if(neg_rs232_rx)beginbps_start_r <= 1'b1;rx_int <= 1'b1;endelse if(num == 4'd12) // 当数据传送结束时,bps_start==0,则,波特率中的计数器不用工作。

beginbps_start_r <= 1'b0;rx_int <= 1'b0;endassign bps_start = bps_start_r;reg [7:0] rs_data_r; //串口接受数据寄存器reg [7:0] rs_temp_data;always @(posedge clk or negedge rst_n)if(!rst_n)beginnum = 4'd0;rs_data_r = 8'd0;rs_temp_data = 8'd0;endelse if(rx_int)beginif(clk_bps)beginnum <= num+1;case(num)4'd1: rs_temp_data[0] = rs232_rx;4'd2: rs_temp_data[1] = rs232_rx;4'd3: rs_temp_data[2] = rs232_rx;4'd4: rs_temp_data[3] = rs232_rx;4'd5: rs_temp_data[4] = rs232_rx;4'd6: rs_temp_data[5] = rs232_rx;4'd7: rs_temp_data[6] = rs232_rx;4'd8: rs_temp_data[7] = rs232_rx;default: ;endcaseendendelse if(num == 4'd12)beginnum <= 0;rs_data_r <= rs_temp_data;endassign rs232_data = rs_data_r;endmoduleuart_tx.v`timescale 1ns / 1ps///////////////////////////////////////////////////////////////////// /////////////// Company:// Engineer://// Create Date: 16:16:24 11/12/2010// Design Name:// Module Name: uart_tx// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://///////////////////////////////////////////////////////////////////// /////////////module uart_tx(clk,rst_n,clk_bps,rx_int,rx_data,bps_start,rs232_tx); input clk,rst_n,clk_bps,rx_int;input [7:0] rx_data;output bps_start,rs232_tx;reg rx_int0,rx_int1,rx_int2; //信号寄存器,捕捉下降沿。

相关主题