Verilog程序6、UART(串口通信)
- 格式:doc
- 大小:132.00 KB
- 文档页数:10
这个程序没有仿真、没有测试。。
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)
);
endmodule
speed_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 2604
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 0;
else if((cnt == `bps9600)
|| !bps_start) //在bps_start为低时,进行开始计数,bps_start 为高时,停止计数。
cnt <= 0;
else
cnt <= cnt+1;
end
always @(posedge clk or negedge rst_n)
if(!rst_n)