verilog RS232 串口通信 verilog
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//=============================顶层模块=====================================
module uart_top(clk,rs232_rx,rs232_tx);
input clk; //时钟信号50M
input rs232_rx; //数据输入信号
bps_start,
clk_bps,
rs232_rx,
rx_data,
rx_int
);
input clk; //50MHz时钟
input rst_n; //低电平复位信号
input rs232_rx; //接收数据信号
);
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),
else
begin
if(int_cnt<250) int_cnt<=int_cnt+1'b1;
end
end
assign data_flg=(int_cnt==10)?1'b1:1'b0;
always @(posedge data_flg or negedge rst_n)
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;
input clk; //50M时钟
input rst_n; //复位信号
input bps_start;//接收到数据后,波特率时钟启动信号置位
//或者开始发送数据时,波特率时钟启动信号置位
output clk_bps; //clk_bps的高电平为发送或者接收数据中间采样点,
bps57600 = 867, //波特率为57600bps
bps115200 = 433; //波特率为115200bps
parameter bps9600_2 = 2603,
bps19200_2 = 1301,
end
end
speed_select_rx speed_rx(//波特率选择模块
.clk(clk),
.rst_n(rst_n),
.clk_bps(clk_bps1),
.bps_start(bps_start1)
bps38400_2 = 650,
bps57600_2 = 433,
bps115200_2 = 216;
*/
//-----------------------------------------------------------------------------
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;
if (rst_cnt>10000) begin
rst_n<=1;
end
else
begin
rst_n<=0;
reg [1:0]addr_r;
reg data_flg_r;
always @(posedge clk or posedge rx_int)
begin
if(rx_int)
out_cnt<=20'd0;
else
begin
if(out_cnt<4194300) out_cnt<=out_cnt+1'b1;
//将中间时刻作为发送数据的数据改变点(发送模块)
reg[12:0] cnt;//分频计数器
reg clk_bps_r;//波特率时钟寄存器
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt<=13'd0;
else if((cnt==5207||!bps_start))//判断计数是否达到1个脉宽
if((out_cnt<60000)||((out_cnt>1000000)&&(out_cnt<1060000))||((out_cnt>2000000)&&(out_cnt<2060000))||((out_cnt>3000000)&&(out_cnt<3060000)))
begin
/* 波特率
parameter bps9600 = 5207, //波特率为9600bps
bps19200 = 2603, //波特率为19200bps
bps38400 = 1301, //波特率为38400bps
input clk_bps; //高电平时为接收信号中间采样点
output bps_start; //接收信号时,波特率时钟信号置位
output [7:0] rx_data;//接收数据寄存器
output rx_int; //接收数据中断信号,接收过程中为高
reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;//接收数据寄存器
data_flg_r<=1'b1;
end
else
begin
data_flg_r<=1'b0;
end
end
end
always @(posedge data_flg_r or negedge rst_n)
begin
if(!rst_n)
addr_r<=8'd0;
else
begin
addr_r<=addr_r+1'b1;
end
end
always @(negedge data_flg_r )
begin
if(addr_r==0)
begin
if(!rst_n)
addr<=0;
else
begin
addr<=addr+1'b1;
end
end
always @(negedge data_flg )
begin
if(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;
.rx_int(rx_int)
);
reg [7:0] int_cnt;
reg [1:0] addr;
wire data_flg;
always @(posedge clk or posedge rx_int)
begin
if(rx_int)
int_cnt<=8'd0;
//以下波特率分频计数值可参照上面的参数进行更改
//计算方法:
//以9600bps为例,9600bps表示每秒9600bit,则传输1bit需要10^9/9600=104166ns,
//所以再我们使用50MHz的时钟频率的前提下,需要104166/20=5208个时钟周期
//5208个时钟周期内传送了1bit位,则在中间的时刻处,进行取样(接收模块)或者
end
speed_select_rx speed_tx( //波特率选择模块
.clk(clk),
.rst_n(rst_n),
.bps_start(bps_start2),
reg [7:0] rx_data3;
reg [7:0] rx_data4; //接收数据存储器,用来存储接收到的数据,直到下一个数据接收
wire rx_int; //接收数据中断信号,接收过程中一直为高,
reg [29:0] rst_cnt;
reg rst_n;
.clk_bps(clk_bps2)
);
uart_tx uart_tx(//发送数据模块
.clk(clk),
.rst_n(rst_n),
.clk_bBiblioteka s(clk_bps2), wire neg_rs232_rx;//表示数据线接收到下沿
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
rs232_rx0 <= 1'b0;
initial begin
rst_cnt<=0;
rst_n<=0;
end
always @(posedge clk ) begin
if(rst_cnt<20000000) rst_cnt<=rst_cnt+1'b1;
cnt<=13'd0;
else
cnt<=cnt+1'b1;//波特率时钟启动
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
clk_bps_r<=1'b0;
else if(cnt== 2603)//当波特率计数到一半时,进行采样存储
clk_bps_r<=1'b1;
else
clk_bps_r<=1'b0;
end
assign clk_bps = clk_bps_r;//将采样数据输出给uart_rx模块
endmodule
module uart_rx(//串口接收模块
clk,
rst_n,
.rs232_tx(rs232_tx),
.tx_data(tx_data),
.tx_int(data_flg_r),
.bps_start(bps_start2)
);
endmodule
module speed_select_rx(clk,rst_n,clk_bps,bps_start);//波特率设定
module uart_top(clk,rs232_rx,rs232_tx);
input clk; //时钟信号50M
input rs232_rx; //数据输入信号
bps_start,
clk_bps,
rs232_rx,
rx_data,
rx_int
);
input clk; //50MHz时钟
input rst_n; //低电平复位信号
input rs232_rx; //接收数据信号
);
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),
else
begin
if(int_cnt<250) int_cnt<=int_cnt+1'b1;
end
end
assign data_flg=(int_cnt==10)?1'b1:1'b0;
always @(posedge data_flg or negedge rst_n)
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;
input clk; //50M时钟
input rst_n; //复位信号
input bps_start;//接收到数据后,波特率时钟启动信号置位
//或者开始发送数据时,波特率时钟启动信号置位
output clk_bps; //clk_bps的高电平为发送或者接收数据中间采样点,
bps57600 = 867, //波特率为57600bps
bps115200 = 433; //波特率为115200bps
parameter bps9600_2 = 2603,
bps19200_2 = 1301,
end
end
speed_select_rx speed_rx(//波特率选择模块
.clk(clk),
.rst_n(rst_n),
.clk_bps(clk_bps1),
.bps_start(bps_start1)
bps38400_2 = 650,
bps57600_2 = 433,
bps115200_2 = 216;
*/
//-----------------------------------------------------------------------------
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;
if (rst_cnt>10000) begin
rst_n<=1;
end
else
begin
rst_n<=0;
reg [1:0]addr_r;
reg data_flg_r;
always @(posedge clk or posedge rx_int)
begin
if(rx_int)
out_cnt<=20'd0;
else
begin
if(out_cnt<4194300) out_cnt<=out_cnt+1'b1;
//将中间时刻作为发送数据的数据改变点(发送模块)
reg[12:0] cnt;//分频计数器
reg clk_bps_r;//波特率时钟寄存器
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt<=13'd0;
else if((cnt==5207||!bps_start))//判断计数是否达到1个脉宽
if((out_cnt<60000)||((out_cnt>1000000)&&(out_cnt<1060000))||((out_cnt>2000000)&&(out_cnt<2060000))||((out_cnt>3000000)&&(out_cnt<3060000)))
begin
/* 波特率
parameter bps9600 = 5207, //波特率为9600bps
bps19200 = 2603, //波特率为19200bps
bps38400 = 1301, //波特率为38400bps
input clk_bps; //高电平时为接收信号中间采样点
output bps_start; //接收信号时,波特率时钟信号置位
output [7:0] rx_data;//接收数据寄存器
output rx_int; //接收数据中断信号,接收过程中为高
reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;//接收数据寄存器
data_flg_r<=1'b1;
end
else
begin
data_flg_r<=1'b0;
end
end
end
always @(posedge data_flg_r or negedge rst_n)
begin
if(!rst_n)
addr_r<=8'd0;
else
begin
addr_r<=addr_r+1'b1;
end
end
always @(negedge data_flg_r )
begin
if(addr_r==0)
begin
if(!rst_n)
addr<=0;
else
begin
addr<=addr+1'b1;
end
end
always @(negedge data_flg )
begin
if(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;
.rx_int(rx_int)
);
reg [7:0] int_cnt;
reg [1:0] addr;
wire data_flg;
always @(posedge clk or posedge rx_int)
begin
if(rx_int)
int_cnt<=8'd0;
//以下波特率分频计数值可参照上面的参数进行更改
//计算方法:
//以9600bps为例,9600bps表示每秒9600bit,则传输1bit需要10^9/9600=104166ns,
//所以再我们使用50MHz的时钟频率的前提下,需要104166/20=5208个时钟周期
//5208个时钟周期内传送了1bit位,则在中间的时刻处,进行取样(接收模块)或者
end
speed_select_rx speed_tx( //波特率选择模块
.clk(clk),
.rst_n(rst_n),
.bps_start(bps_start2),
reg [7:0] rx_data3;
reg [7:0] rx_data4; //接收数据存储器,用来存储接收到的数据,直到下一个数据接收
wire rx_int; //接收数据中断信号,接收过程中一直为高,
reg [29:0] rst_cnt;
reg rst_n;
.clk_bps(clk_bps2)
);
uart_tx uart_tx(//发送数据模块
.clk(clk),
.rst_n(rst_n),
.clk_bBiblioteka s(clk_bps2), wire neg_rs232_rx;//表示数据线接收到下沿
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
rs232_rx0 <= 1'b0;
initial begin
rst_cnt<=0;
rst_n<=0;
end
always @(posedge clk ) begin
if(rst_cnt<20000000) rst_cnt<=rst_cnt+1'b1;
cnt<=13'd0;
else
cnt<=cnt+1'b1;//波特率时钟启动
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
clk_bps_r<=1'b0;
else if(cnt== 2603)//当波特率计数到一半时,进行采样存储
clk_bps_r<=1'b1;
else
clk_bps_r<=1'b0;
end
assign clk_bps = clk_bps_r;//将采样数据输出给uart_rx模块
endmodule
module uart_rx(//串口接收模块
clk,
rst_n,
.rs232_tx(rs232_tx),
.tx_data(tx_data),
.tx_int(data_flg_r),
.bps_start(bps_start2)
);
endmodule
module speed_select_rx(clk,rst_n,clk_bps,bps_start);//波特率设定