目录
串口概念
串口rs232
数据格式
注意事项
总体结构图
代码verilog
接收模块
结构图
波形图编辑
代码 verilog
发送模块
结构图
波形图
代码 verilog
串口rs485
串口概念
- 串口是异步串行通信接口,spi和iic是同步串行通信接口
- 同步表示收发双方在一个时钟下,发送时包含数据和时钟信号,数据和时钟是同步的;
- 异步表示收发双方不同时钟下,发送时只需要发送数据,不需要时钟信号,根据起始位和停止位进行数据的同步,异步接收
串口rs232
全双工通信
信号采用单端传输方式
缺点:传输距离近和传输速度慢
优点:都有com口,方便使用
波特率:每秒钟传输码元的个数 baus Bps 码元:一个二进制位 常用:4800 9600 115200
比特率:每秒钟传输bit数 比特率=波特率*单个调制状态对应二进制数 bps
单端传输:使用一根信号线,通过与地信号比较来区分逻辑0,1;
数据格式
共10bit的数据,其中起始位1bit,8bit的数据位,停止位1bit
注意事项
数据接受模块需要进行寄存器打拍,因为数据与时钟不同步,会出现亚稳态
亚稳态:信号在进入寄存器时的建立时间和保持时间不满足条件(信号 是必须稳定的才满足)导致的
危害:亚稳态会一直向下传播,组合逻辑是无法消除的
解决:多级寄存器,因为寄存器会减缓亚稳态 一般两级打拍
Tco:寄存器延迟 Tmet:决断时间
总体结构图
代码verilog
module AX301_rs232(
input clk,
input rst_n,
input rx,
output tx
);
wire [7:0] po_data;
wire po_flag;
rs232_rx
#(
.uart_Bps ('d9600),
.clk_fre ('d50_000_000)
)
rs232_rx_inst
(
.clk (clk),
.rst_n (rst_n),
.rx (rx),
.po_data (po_data),
.po_flag (po_flag)
);
rs232_tx
#(
.uart_Bps ('d9600),
.clk_fre ('d50_000_000)
)
rs232_tx_inst
(
.clk (clk),
.rst_n (rst_n),
.po_data (po_data),
.po_flag (po_flag ),
.tx (tx)
);
endmodule
接收模块
结构图
波形图
代码 verilog
module rs232_rx
#(
parameter uart_Bps = 'd9600,
parameter clk_fre = 'd50_000_000
)
(
input clk,
input rst_n,
input rx,
output reg po_flag,
output reg [7:0] po_data
);
parameter max_cnt = clk_fre / uart_Bps;
reg rx_reg1,rx_reg2,rx_reg3;
reg work_en;
reg [15:0] bps_cnt;
reg bit_flag;
reg [3:0] bit_cnt;
reg [7:0] rx_data;
reg rx_flag;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
rx_reg1 <= 1'b1;
else
rx_reg1 <= rx;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
rx_reg2 <= 1'b1;
else
rx_reg2 <= rx_reg1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
rx_reg3 <= 1'b1;
else
rx_reg3 <= rx_reg2;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
work_en <= 1'b0;
else if(rx_reg2 == 1'b0 && rx_reg3 == 1'b1)
work_en <= 1'b1;
else if(bit_cnt ==4'd8 && bit_flag ==1'b1)
work_en <=1'b0;
else
work_en <= work_en;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bps_cnt <= 16'd0;
else if(work_en == 1'b0 || bps_cnt == max_cnt - 1)
bps_cnt <= 16'd0;
else
bps_cnt <= bps_cnt + 16'd1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bit_flag <= 1'b0;
else if(bps_cnt == max_cnt/2 - 1)
bit_flag <= 1'b1;
else
bit_flag <= 1'b0;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bit_cnt <= 4'd0;
else if(bit_cnt ==4'd8 && bit_flag ==1'b1)
bit_cnt <= 4'd0;
else if(bit_flag ==1'b1)
bit_cnt <= bit_cnt + 4'd1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
rx_data <= 8'b0;
else if(bit_cnt >= 4'd1 && bit_cnt <=4'd8 && bit_flag == 1'b1)
rx_data <= {rx_reg3,rx_data[7:1]};
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
rx_flag <= 1'b0;
else if(bit_cnt ==4'd8 && bit_flag == 1'b1)
rx_flag <= 1'b1;
else
rx_flag <= 1'b0;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
po_data<=8'b0;
else if(rx_flag==1'b1)
po_data<=rx_data;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
po_flag<=1'b0;
else
po_flag<=rx_flag;
end
endmodule
发送模块
结构图
波形图
代码 verilog
module rs232_tx
#(
parameter uart_Bps = 'd9600,
parameter clk_fre = 'd50_000_000
)
(
input clk,
input rst_n,
input [7:0] po_data,
input po_flag,
output reg tx
);
parameter max_cnt = clk_fre / uart_Bps;
reg work_en;
reg [15:0] bps_cnt;
reg bit_flag;
reg [3:0] bit_cnt;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
work_en <= 1'b0;
else if(po_flag == 1'b1)
work_en<=1'b1;
else if(bit_cnt == 4'd9 &&bit_flag == 1'b1)
work_en <= 1'b0;
else
work_en <= work_en;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bps_cnt <= 16'd0;
else if(work_en == 1'b0 || bps_cnt == max_cnt - 1)
bps_cnt <= 16'd0;
else
bps_cnt <= bps_cnt + 16'd1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bit_flag <= 1'b0;
else if(bps_cnt == 16'd1)
bit_flag <= 1'b1;
else
bit_flag <= 1'b0;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bit_cnt <= 4'd0;
else if(bit_cnt ==4'd9 && bit_flag ==1'b1)
bit_cnt <= 4'd0;
else if(bit_flag ==1'b1)
bit_cnt <= bit_cnt + 4'd1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
tx <=1'b1;
else if(bit_flag == 1'b1)
case(bit_cnt)
0: tx<=1'b0;
1: tx<=po_data[0];
2: tx<=po_data[1];
3: tx<=po_data[2];
4: tx<=po_data[3];
5: tx<=po_data[4];
6: tx<=po_data[5];
7: tx<=po_data[6];
8: tx<=po_data[7];
9: tx<=1'b1;
default: tx<=1'b1;
endcase
end
endmodule
串口rs485
- 半双工通信
- 信号采用差分传输方式
- 允许多个驱动器和接收器挂在总线上,其中每个驱动器都能够脱离总线。
- 优点:rs485相对于rs232抗干扰能力强,传输距离远,因为rs485上有收发器,可以检测到200mv的电压,最远通信距离可以达到1200m左右,速度可以达到10Mb/s
- 差分传输:使用两根信号线进行传输,两个信号相位相反,幅值相同,通过两根信号的电压差值判断是逻辑0还是1,抗干扰能力强;
- rs485相对于rs232抗干扰能力强,传输距离远,因为rs485上有收发器,可以检测到200mv的电压,最远通信距离可以达到1200m左右,速度可以达到10Mb/s
- 具体代码实现同RS232相同
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)