串口RS485

  • Post author:
  • Post category:其他



实验目的:


两块开发板互连,实现led灯的相互控制,显示呼吸灯或者流水灯

起始位+数据位+停止位,共10bit

控制板:消抖后的两路按键信息传入led_ctrl,将它打包成数据帧,产生po_flag标志信号,然后传给tx模块按照UART异步串口通信协议串行发送给被控板

被控板:rx模块接收串行数据帧进行串并转换,之后发送给led_ctrl进行解码,解码后的控制信息控制自身led的显示



1. 串口简介

RS232属于UART串口的一种常用的通信协议,RS485也是

RS485是

双向



半双工

通信协议,信号采用差分传输方式,允许多个驱动器和接收器挂在总线上,其中每个驱动器都能够脱离总线

差分信号,赋值相同,相位相反

根据电压差值的大小判断逻辑1/0

差分信号有更好的抗干扰能力,如果碰到了干扰信号,对两路差分信号的影响是相同的,根据电位差,判断干扰部分的逻辑值为0

在这里插入图片描述

RS232支持全双工,RS485支持半双工

RS485和232使用相同的通信协议,数据帧结构相同(起始位+数据位+停止位,共10bit)



2. 实验目的

两块开发板互连,实现led灯的相互控制,显示呼吸灯或者流水灯

起始位+数据位+停止位,共10bit

控制板:消抖后的两路按键信息传入led_ctrl,将它打包成数据帧,产生po_flag标志信号,然后传给tx模块按照UART异步串口通信协议串行发送给被控板

被控板:rx模块接收串行数据帧进行串并转换,之后发送给led_ctrl进行解码,解码后的控制信息控制自身led的显示

在这里插入图片描述



3. 代码实现



按键消抖key_filter

复用

对按键信号进行消抖处理

在这里插入图片描述



流水灯water_led

复用

在这里插入图片描述



呼吸灯breath_led

复用

在这里插入图片描述



串口接收模块uart_rx

复用RS232的接收模块

作为

被控板

,接收控制板tx模块传来的串行数据信号,接收完了之后发送给自身的led控制模块

在这里插入图片描述



灯控模块led_ctrl

作为

控制板

,接收消抖后的按键信号打包进串口数据帧po_data中,生成po_flag一起发送给自己的tx发送模块

作为

被控板

,接收rx传来的串并转换数据,根据数据帧中的两种灯型的控制信号,控制自身的led显示流水灯还是呼吸灯

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述



串口发送模块uart_tx

在原先RS232的基础上,修改一下

因为要多输出一个收发器使能信号re,当开发板接收的时候,输出0,当开发板发送的时候,输出1,这样就可以参考RS232中tx模块的work_en信号

work_en是只在起始位和8bit数据位的时候拉高,需要对它拉长一下使能时间

在这里插入图片描述

在这里插入图片描述

module uart_tx 
#(
	parameter	UART_BPS	=	'd9600			,
	parameter	CLK_FREQ	=	'd50_000_000	
)
(
	input	wire			sys_clk		,
	input	wire			sys_rst_n	,
	input	wire	[ 7: 0]	pi_data		,
	input	wire			pi_flag		,
	
	output	reg				tx			,
	output	reg				work_en
);

	localparam	BAUD_CNT_MAX	=	CLK_FREQ / UART_BPS;


	reg		[15: 0]	baud_cnt	;
	reg				bit_flag	;
	reg		[ 3: 0]	bit_cnt		;
	
	
	// work_en
	always @ (posedge sys_clk or negedge sys_rst_n)
		if (sys_rst_n == 1'b0)
			work_en	<=	1'b0;
		else	if ((bit_cnt == 4'd9) && (bit_flag == 1'b1))
			work_en	<=	1'b0;
		else	if (pi_flag == 1'b1)
			work_en	<=	1'b1;
		else
			work_en	<=	work_en;
			
	
	// baud_cnt
	always @ (posedge sys_clk or negedge sys_rst_n)
		if (sys_rst_n == 1'b0)	
			baud_cnt	<=	16'd0;
		else	if ((work_en == 1'b0) || (baud_cnt == BAUD_CNT_MAX - 1'b1))
			baud_cnt	<=	16'd0;
		else	if (work_en == 1'b1)
			baud_cnt	<=	baud_cnt + 1'b1;
	
	
	// bit_flag
	always @ (posedge sys_clk or negedge sys_rst_n)
		if (sys_rst_n == 1'b0)
			bit_flag	<=	1'b0;
		else	if (baud_cnt == BAUD_CNT_MAX - 1'b1)
			bit_flag	<=	1'b1;
		else
			bit_flag	<=	1'b0;
	
	
	// bit_cnt
	always @ (posedge sys_clk or negedge sys_rst_n)
		if (sys_rst_n == 1'b0)
			bit_cnt	<=	4'd0;
		else	if ((bit_cnt == 4'd9) && (bit_flag == 1'b1))
			bit_cnt	<=	4'd0;
		else	if ((work_en == 1'b1) && (bit_flag == 1'b1))
			bit_cnt	<=	bit_cnt + 1'b1;
		else
			bit_cnt	<=	bit_cnt;


	// tx
	always @ (posedge sys_clk or negedge sys_rst_n)
		if (sys_rst_n == 1'b0)
			tx	<=	1'b1;
		else	if (work_en == 1'b1)
			case (bit_cnt)
				0:	tx	<=	1'b0;
				1:	tx	<=	pi_data[0];
				2:	tx	<=	pi_data[1];
				3:	tx	<=	pi_data[2];
				4:	tx	<=	pi_data[3];
				5:	tx	<=	pi_data[4];
				6:	tx	<=	pi_data[5];
				7:	tx	<=	pi_data[6];
				8:	tx	<=	pi_data[7];
				9:	tx	<=	1'b1;
				default:	tx	<=	1'b1;
			endcase
	
endmodule



顶层模块

在这里插入图片描述



4. 仿真验证

模拟按下流水灯控制按键、按下呼吸灯控制按键、按下呼吸灯控制按键、按下流水灯控制按键、按下流水灯控制按键

在这里插入图片描述



5. 下板验证

用跳线连接两块板子,实现通过串口的交叉互联

在这里插入图片描述



版权声明:本文为Bunny9__原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。