串口RS485

实验目的:
两块开发板互连,实现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. 下板验证

用跳线连接两块板子,实现通过串口的交叉互联
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值