基于FPGA与PC串口自收发通信VerilogWord文档格式.docx
《基于FPGA与PC串口自收发通信VerilogWord文档格式.docx》由会员分享,可在线阅读,更多相关《基于FPGA与PC串口自收发通信VerilogWord文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
0]rx_data;
//接收数据寄存器,保存直至下一个数据来到
wirerx_int;
//接收数据中断信号,接收到数据期间始终为高电平
//----------------------------------------------------
speed_select
speed_select(
.clk(clk),
//波特率选择模块,接收和发送模块复用,不支持全双工通信
.rst_n(rst_n),
.bps_start(bps_start),
.clk_bps(clk_bps)
);
my_uart_rx
my_uart_rx(
//接收数据模块
.rs232_rx(rs232_rx),
.clk_bps(clk_bps),
.rx_data(rx_data),
.rx_int(rx_int)
my_uart_tx
my_uart_tx(
//发送数据模块
.rx_int(rx_int),
.rs232_tx(rs232_tx),
.bps_start(bps_start)
endmodule
modulespeed_select(clk,rst_n,bps_start,clk_bps);
inputbps_start;
outputclk_bps;
parameter
bps9600
=5207,
//波特率为9600bps
bps19200
=2603,
//波特率为19200bps
bps38400
=1301,
//波特率为38400bps
bps57600
=867,
//波特率为57600bps
bps115200
=433;
//波特率为115200bps
bps9600_2
bps19200_2
bps38400_2
=650,
bps57600_2
=433,
bps115200_2=216;
reg[12:
0]bps_para;
//分频计数最大值
0]bps_para_2;
//分频计数的一半
0]cnt;
//分频计数
regclk_bps_r;
//波特率时钟寄存器
//----------------------------------------------------------
reg[2:
0]uart_ctrl;
//uart波特率选择寄存器
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
uart_ctrl<
=3'
d0;
//默认波特率为9600bps
end
elsebegin
case(uart_ctrl)
//波特率设置
3'
d0:
begin
bps_para<
=bps9600;
bps_para_2<
=bps9600_2;
d1:
=bps19200;
=bps19200_2;
d2:
=bps38400;
=bps38400_2;
d3:
=bps57600;
=bps57600_2;
d4:
=bps115200;
=bps115200_2;
default:
;
endcase
always@(posedgeclkornegedgerst_n)
rst_n)cnt<
=13'
elseif(cnt<
bps_para&
&
bps_start)cnt<
=cnt+1'
b1;
//波特率时钟计数启动
elsecnt<
rst_n)clk_bps_r<
=1'
b0;
elseif(cnt==bps_para_2&
bps_start)clk_bps_r<
//clk_bps_r高电平为接收或者发送数据位的中间采样点
elseclk_bps_r<
assignclk_bps=clk_bps_r;
modulemy_uart_rx(clk,rst_n,rs232_rx,clk_bps,bps_start,rx_data,rx_int);
inputclk_bps;
//clk_bps的高电平为接收或者发送数据位的中间采样点
outputbps_start;
output[7:
//接收数据寄存器,保存直至下一个数据来到
outputrx_int;
//----------------------------------------------------------------
regrs232_rx0,rs232_rx1,rs232_rx2;
//接收数据寄存器,滤波用
wireneg_rs232_rx;
//表示数据线接收到下降沿
rst_n)begin
rs232_rx0<
rs232_rx1<
rs232_rx2<
=rs232_rx;
=rs232_rx0;
=rs232_rx1;
assignneg_rs232_rx=rs232_rx2&
~rs232_rx1;
//接收到下降沿后neg_rs232_rx置高一个时钟周期
regbps_start_r;
reg[3:
0]
num;
//移位次数
regrx_int;
bps_start_r<
bz;
rx_int<
elseif(neg_rs232_rx)begin
//启动接收数据
//接收数据中断信号使能
elseif(num==4'
d12)begin
//数据接收完毕
//接收数据中断信号关闭
end
assignbps_start=bps_start_r;
reg[7:
0]rx_data_r;
rx_temp_data;
//但前接收数据寄存器
regrx_data_shift;
//数据移位标志
rx_data_shift<
rx_temp_data<
=8'
num<
=4'
rx_data_r<
elseif(rx_int)begin
//接收数据处理
if(clk_bps)begin
//读取并保存数据,接收数据为一个起始位,8bit数据,一个结束位
=num+1'
if(num<
=4'
d8)rx_temp_data[7]<
//锁存9bit(1bit起始位,8bit数据)
elseif(rx_data_shift)begin
//数据移位处理
d8)rx_temp_data<
=rx_temp_data>
>
1'
//移位8次,第1bit起始位移除,剩下8bit正好时接收数据
//接收到STOP位后结束,num清零
=rx_temp_data;
//把数据锁存到数据寄存器rx_data中
assignrx_data=rx_data_r;
modulemy_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start);
input[7:
//接收数据寄存器
inputrx_int;
//接收数据中断信号,接收到数据期间始终为高电平,在次利用它的下降沿来启动发送数据
//RS232发送数据信号
//接收或者要发送数据,波特率时钟启动信号置位
//---------------------------------------------------------
regrx_int0,rx_int1,rx_int2;
//rx_int信号寄存器,捕捉下降沿滤波用
wireneg_rx_int;
//rx_int下降沿标志位
rx_int0<
rx_int1<
rx_int2<
=rx_int;
=rx_int0;
=rx_int1;
assignneg_rx_int=
~rx_int1&
rx_int2;
//捕捉到下降沿后,neg_rx_int拉地保持一个主时钟周期
0]tx_data;
//待发送数据的寄存器
regtx_en;
//发送数据使能信号,高有效
0]num;
tx_en<
tx_data<
elseif(neg_rx_int)begin
//接收数据完毕,准备把接收到的数据发回去
=rx_data;
//把接收到的数据存入发送数据寄存器
//进入发送数据状态中
d11)begin
//数据发送完成,复位
regrs232_tx_r;
rs232_tx_r<
elseif(tx_en)begin
if(clk_bps)
case(num)
4'
//发送起始位
=tx_data[0];
//发送bit0
=tx_data[1];
//发送bit1
rs232_tx_r<
=tx_data[2];
//发送bit2
=tx_data[3];
//发送bit3
d5:
=tx_data[4];
//发送bit4
d6:
=tx_data[5];
//发送bit5
d7:
=tx_data[6];
//发送bit6
d8:
=tx_data[7];
//发送bit7
d9:
//发送结束位
d11)num<
//复位
assignrs232_tx=rs232_tx_r;