串口UART

目录

串口概念

串口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相同
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值