//波特率时钟计数启动
elsecnt<=13'd0;
always@(posedgeclkornegedgerst_n)
if(!
rst_n)clk_bps_r<=1'b0;
elseif(cnt==bps_para_2&&bps_start)clk_bps_r<=1'b1;
//clk_bps_r高电平为接收或者发送数据位的中间采样点
elseclk_bps_r<=1'b0;
assignclk_bps=clk_bps_r;
endmodule
modulemy_uart_rx(clk,rst_n,rs232_rx,clk_bps,bps_start,rx_data,rx_int);
inputclk;
//50MHz主时钟
inputrst_n;
//低电平复位信号
inputrs232_rx;
//RS232接收数据信号
inputclk_bps;
//clk_bps的高电平为接收或者发送数据位的中间采样点
outputbps_start;
//接收到数据后,波特率时钟启动信号置位
output[7:
0]rx_data;
//接收数据寄存器,保存直至下一个数据来到
outputrx_int;
//接收数据中断信号,接收到数据期间始终为高电平
//----------------------------------------------------------------
regrs232_rx0,rs232_rx1,rs232_rx2;
//接收数据寄存器,滤波用
wireneg_rs232_rx;
//表示数据线接收到下降沿
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
rs232_rx0<=1'b1;
rs232_rx1<=1'b1;
rs232_rx2<=1'b1;
end
elsebegin
rs232_rx0<=rs232_rx;
rs232_rx1<=rs232_rx0;
rs232_rx2<=rs232_rx1;
end
end
assignneg_rs232_rx=rs232_rx2&~rs232_rx1;
//接收到下降沿后neg_rs232_rx置高一个时钟周期
//----------------------------------------------------------------
regbps_start_r;
reg[3:
0]
num;
//移位次数
regrx_int;
//接收数据中断信号,接收到数据期间始终为高电平
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
bps_start_r<=1'bz;
rx_int<=1'b0;
end
elseif(neg_rs232_rx)begin
bps_start_r<=1'b1;
//启动接收数据
rx_int<=1'b1;
//接收数据中断信号使能
end
elseif(num==4'd12)begin
bps_start_r<=1'bz;
//数据接收完毕
rx_int<=1'b0;
//接收数据中断信号关闭
end
end
assignbps_start=bps_start_r;
//----------------------------------------------------------------
reg[7:
0]rx_data_r;
//接收数据寄存器,保存直至下一个数据来到
//----------------------------------------------------------------
reg[7:
0]
rx_temp_data;
//但前接收数据寄存器
regrx_data_shift;
//数据移位标志
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
rx_data_shift<=1'b0;
rx_temp_data<=8'd0;
num<=4'd0;
rx_data_r<=8'd0;
end
elseif(rx_int)begin
//接收数据处理
if(clk_bps)begin
//读取并保存数据,接收数据为一个起始位,8bit数据,一个结束位
rx_data_shift<=1'b1;
num<=num+1'b1;
if(num<=4'd8)rx_temp_data[7]<=rs232_rx;
//锁存9bit(1bit起始位,8bit数据)
end
elseif(rx_data_shift)begin
//数据移位处理
rx_data_shift<=1'b0;
if(num<=4'd8)rx_temp_data<=rx_temp_data>>1'b1;
//移位8次,第1bit起始位移除,剩下8bit正好时接收数据
elseif(num==4'd12)begin
num<=4'd0;
//接收到STOP位后结束,num清零
rx_data_r<=rx_temp_data;
//把数据锁存到数据寄存器rx_data中
end
end
end
end
assignrx_data=rx_data_r;
endmodule
modulemy_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start);
inputclk;
//50MHz主时钟
inputrst_n;
//低电平复位信号
inputclk_bps;
//clk_bps的高电平为接收或者发送数据位的中间采样点
input[7:
0]rx_data;
//接收数据寄存器
inputrx_int;
//接收数据中断信号,接收到数据期间始终为高电平,在次利用它的下降沿来启动发送数据
outputrs232_tx;
//RS232发送数据信号
outputbps_start;
//接收或者要发送数据,波特率时钟启动信号置位
//---------------------------------------------------------
regrx_int0,rx_int1,rx_int2;
//rx_int信号寄存器,捕捉下降沿滤波用
wireneg_rx_int;
//rx_int下降沿标志位
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
rx_int0<=1'b0;
rx_int1<=1'b0;
rx_int2<=1'b0;
end
elsebegin
rx_int0<=rx_int;
rx_int1<=rx_int0;
rx_int2<=rx_int1;
end
end
assignneg_rx_int=
~rx_int1&rx_int2;
//捕捉到下降沿后,neg_rx_int拉地保持一个主时钟周期
//---------------------------------------------------------
reg[7:
0]tx_data;
//待发送数据的寄存器
//---------------------------------------------------------
regbps_start_r;
regtx_en;
//发送数据使能信号,高有效
reg[3:
0]num;
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
bps_start_r<=1'bz;
tx_en<=1'b0;
tx_data<=8'd0;
end
elseif(neg_rx_int)begin
//接收数据完毕,准备把接收到的数据发回去
bps_start_r<=1'b1;
tx_data<=rx_data;
//把接收到的数据存入发送数据寄存器
tx_en<=1'b1;
//进入发送数据状态中
end
elseif(num==4'd11)begin
//数据发送完成,复位
bps_start_r<=1'bz;
tx_en<=1'b0;
end
end
assignbps_start=bps_start_r;
//---------------------------------------------------------
regrs232_tx_r;
always@(posedgeclkornegedgerst_n)begin
if(!
rst_n)begin
num<=4'd0;
rs232_tx_r<=1'b1;
end
elseif(tx_en)begin
if(clk_bps)
begin
num<=num+1'b1;
case(num)
4'd0:
rs232_tx_r<=1'b0;
//发送起始位
4'd1:
rs232_tx_r<=tx_data[0];
//发送bit0
4'd2:
rs232_tx_r<=tx_data[1];
//发送bit1
4'd3:
rs232_tx_r<=tx_data[2];
//发送bit2
4'd4:
rs232_tx_r<=tx_data[3];
//发送bit3
4'd5:
rs232_tx_r<=tx_data[4];
//发送bit4
4'd6:
rs232_tx_r<=tx_data[5];
//发送bit5
4'd7:
rs232_tx_r<=tx_data[6];
//发送bit6
4'd8:
rs232_tx_r<=tx_data[7];
//发送bit7
4'd9:
rs232_tx_r<=1'b0;
//发送结束位
default:
rs232_tx_r<=1'b1;
endcase
end
elseif(num==4'd11)num<=4'd0;
//复位
end
end
assignrs232_tx=rs232_tx_r;
endmodule