串口RS485

news2024/12/24 2:29:40

1.原理

全双工:在同一时刻可以同时进行数据的接收和数据的发送,两者互不影响

半双工:在同一时刻只能进行数据的接收或者数据的发送,两者不能同时进行

差分信号幅值相同,相位相反,有更强的抗干扰能力。

干扰对差分信号的影响都是相同的,所以差分信号的干扰一相减就没有了

RS485的优点,采用差分信号有更强的抗干扰能力;相比RS232能能进行长距离传输(RS485要用到收发器芯片,收发器的灵敏度是很高的,可以检测到低至200mv的电压,表示传输信号在千米之外都可以恢复,最远的通信距离可以达到1200米左右,速度最快10MB/s,速度和距离是成反比的,速度越小,传输距离越长,长距离的通信可以增加RS485的中继器);缺点就是只支持半双工。

RE是低电平有效,表示数据的收,当接收时,RE=0,DE=0;然后芯片将差分信号转换为单端信号。当RE=1,DE=1时,数据发送,将单端信号转换为差分信号。

485和232使用相同的传输协议

2.代码

以上是控制板的波形图

以上是被控板的时序图

2.1 led_ctrl.v

module led_ctrl(
	input wire 			sys_clk		,
	input wire 			sys_rst_n	,
	input wire [3:0]	led_out_w	,//流水灯
	input wire			led_out_b   ,//呼吸灯
	input wire [7:0]	pi_data		,
	input wire 			key_flag_w	,
	input wire 			key_flag_b	,
	
	output reg  [3:0]	led			,
	output wire  [7:0]	po_data		,
	output wire 		po_flag	
);

reg w_en;
reg b_en;


assign po_data={6'b000_000,b_en,w_en};
assign po_flag=key_flag_b||key_flag_w;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		w_en<=1'b0;
	else if(key_flag_b==1'b1)
		w_en<=1'b0;
	else if(key_flag_w==1'b1)
		w_en<=~w_en;
	else
		w_en<=w_en;
	
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		b_en<=1'b0;
	else if(key_flag_w==1'b1)
		b_en<=1'b0;
	else if(key_flag_b==1'b1)
		b_en<=~b_en;
	else 
		b_en<=b_en;
			
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		led<=4'b1111;
	else if(po_data[0]==1'b1)
		led<=led_out_w;
	else if(po_data[1]==1'b1)
		led<=led_out_b;
	else
		led<=4'b1111;
		
endmodule
		
	

2.2 uart_tx.v

闲杂输出的赋值条件不再是bit_flag信号,而是使能信号,rx下降沿延迟work_en一个周期,因为是时序逻辑,而且只延迟一个时钟周期,一个Bit传输有5208个周期。若是想对齐可以把work_en打一拍

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 			work_en			,
	output reg 			tx		
);
 
parameter BAUD_CNT_MAX=CLK_FREQ/UART_BPS;

reg [15:0]	baud_cnt;
reg bit_flag;
reg [3:0]bit_cnt;
 
 
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;
	
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		baud_cnt<=16'd0;
	else if((baud_cnt==BAUD_CNT_MAX-1'b1)||(work_en==1'b0))
		baud_cnt<=16'd0;
	else if(work_en==1'b1)
		baud_cnt<=baud_cnt+1'b1;
	else
		baud_cnt<=baud_cnt;
		
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) //因为只有使能信号为高电平时,使能信号才进行计数,使能信号为低电平,波特计数器为0。所以不适合用计数值为0来作为条件
		bit_flag<=1'b1;
	else 
		bit_flag<=1'b0;
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(bit_flag==1'b1)
		bit_cnt<=bit_cnt+1'b1;
	else
		bit_cnt<=bit_cnt;
		
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)
			4'd0: tx<=1'b0;
			4'd1: tx<=pi_data[0];
			4'd2: tx<=pi_data[1];
			4'd3: tx<=pi_data[2];
			4'd4: tx<=pi_data[3];
			4'd5: tx<=pi_data[4];
			4'd6: tx<=pi_data[5];
			4'd7: tx<=pi_data[6];
			4'd8: tx<=pi_data[7];
			4'd9: tx<=1'b1;
			default:tx<=1'b1;
		endcase
endmodule

2.3 rs485.v

module rs485(
	input wire		sys_clk		,
	input wire 		sys_rst_n	,
	input wire	    key_in_w	,
	input wire		key_in_b	,
	input wire 		rx			,
	
	output wire 	tx			,
	output wire 	re			,
	output wire[3:0]led
);

parameter KEY_CNT_MAX=20'd999_999;
parameter WATER_LED_CNT_MAX=25'd24_999_999;

parameter CNT_1US_MAX  =    6'd49	 ,
          CNT_1MS_MAX  =    10'd999  ,
          CNT_1S_MAX   =    10'd999  ;
		
parameter UART_BPS=9600,
          CLK_FREQ=50_000_000;

wire w_flag;
wire b_flag;
wire [3:0]w_led;
wire b_led;        
wire [7:0]rx_data;	
wire [7:0]po_data;
wire po_flag;



key_filter
#(
	.CNT_MAX(KEY_CNT_MAX)
)
key_filter_inst_w
(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n	)	,
	.key_in		(key_in_w	)	,
	             
	.key_flag	(w_flag)	
);



key_filter
#(
	.CNT_MAX(KEY_CNT_MAX)
)
key_filter_inst_b
(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n	)	,
	.key_in		(key_in_b	)	,
	             
	.key_flag	(b_flag	)	
);


water_led
#(
	.CNT_MAX(WATER_LED_CNT_MAX)
)
water_led_inst
(
	.sys_clk	(sys_clk	),
	.sys_rst_n	(sys_rst_n	),
	             
	.led_out	(w_led	)
);


breath_led#(
	.CNT_1US_MAX(CNT_1US_MAX ),
	.CNT_1MS_MAX(CNT_1MS_MAX ),
	.CNT_1S_MAX (CNT_1S_MAX  )

)
breath_led_inst
(
	.sys_clk	(sys_clk	)	,
	.sys_rst_n	(sys_rst_n),
	             
	.led_out    (b_led  )
);
 

uart_rx
#(
	.UART_BPS(UART_BPS),
	.CLK_FREQ( CLK_FREQ )
)
uart_rx_inst
(
 	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n	)	,
	.rx			(rx			)	,
	             
	.po_data	(rx_data	)		,
	.po_flag    ()
);

led_ctrl led_ctrl_inst(
	.sys_clk	(sys_clk)	,
	.sys_rst_n	(sys_rst_n),
	.led_out_w	(w_led),
	.led_out_b  (b_led),
	.pi_data	(rx_data)	,
	.key_flag_w	(w_flag),
	.key_flag_b	(b_flag),
	
	.led		(led)	,
	.po_data	(po_data)	,
	.po_flag	(po_flag)
);

uart_tx
#(
	.UART_BPS(UART_BPS    	),
	.CLK_FREQ(CLK_FREQ )
 
)
uart_tx_inst
(
	.sys_clk	(sys_clk)		,
	.sys_rst_n	(sys_rst_n)	,
	.pi_data	(po_data)		,
	.pi_flag	(po_flag)		,
	
	.work_en	(re)		,
	.tx		    (tx)
);

endmodule

2.4 tb_rs485.v

`timescale 1ns/1ns

module tb_rs485();

reg sys_clk;
reg sys_rst_n;
reg key_in_w	;
reg key_in_b	;
reg rx			;
wire tx;
wire re;
wire [3:0]led;

initial 
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		key_in_b<=1'b1;
		key_in_w<=1'b1;
		#20
		sys_rst_n<=1'b1;
		//流水灯
		#2000000  key_in_w<=1'b0; //按下流水灯的按键
		#20 	  key_in_w<=1'b1;
		#20 	  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1; //模拟前抖动
		#20 	  key_in_w<=1'b0; //模拟稳定状态
		#200  	  key_in_w<=1'b1; //模拟后抖动
		#20 	  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1;
		#20 	  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1;
		//呼吸灯
		#2000000  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#200  	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		//呼吸灯
		#2000000  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#200  	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		#20 	  key_in_b<=1'b0;
		#20 	  key_in_b<=1'b1;
		//流水灯
		#2000000  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1;
		#20 	  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1;
		#20 	  key_in_w<=1'b0;
		#200  	  key_in_w<=1'b1;
		#20 	  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1;
		#20 	  key_in_w<=1'b0;
		#20 	  key_in_w<=1'b1;
	
	end
	
always #10 sys_clk=~sys_clk;

defparam rs485_inst0.KEY_CNT_MAX=5;
defparam rs485_inst0.WATER_LED_CNT_MAX=4000;
defparam rs485_inst1.WATER_LED_CNT_MAX=4000;
defparam rs485_inst0.CNT_1US_MAX=4;
defparam rs485_inst1.CNT_1US_MAX=4;
defparam rs485_inst0.CNT_1MS_MAX=9;
defparam rs485_inst1.CNT_1MS_MAX=9;
defparam rs485_inst0.CNT_1S_MAX=9;
defparam rs485_inst1.CNT_1S_MAX=9;
defparam rs485_inst0.UART_BPS=1000_000;
defparam rs485_inst1.UART_BPS=1000_000;//越大越快

	
//控制板不用rx信号
rs485 rs485_inst0(
	.sys_clk	(sys_clk)	,
	.sys_rst_n	(sys_rst_n),
	.key_in_w	(key_in_w	),
	.key_in_b	(key_in_b	),
	.rx			(),//对于控制板来说,rx是无效的,因为我们只需要两路按键
	
	.tx			(tx),
	.re			(re),
	.led        ()//控制板的led灯一直是熄灭状态不需要引出来
);

//被控板
rs485 rs485_inst1(
	.sys_clk	(sys_clk)	,
	.sys_rst_n	(sys_rst_n),
	.key_in_w	(	),//对于被控板来说,按键信号是无效的
	.key_in_b	(	),
	.rx			(tx),
	
	.tx			(),//tx和re没有用到不需要引出
	.re			(),
	.led        (led)
);


endmodule

看控制模块

看被控模块

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1595112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java实现二叉树(下)

1.前言 http://t.csdnimg.cn/lO4S7 在前文我们已经简单的讲解了二叉树的基本概念&#xff0c;本文将讲解具体的实现 2.基本功能的实现 2.1获取树中节点个数 public int size(TreeNode root){if(rootnull){return 0;}int retsize(root.left)size(root.right)1;return ret;}p…

基于深度学习的花卉检测系统(含PyQt界面)

基于深度学习的花卉检测系统&#xff08;含PyQt界面&#xff09; 前言一、数据集1.1 数据集介绍1.2 数据预处理 二、模型搭建三、训练与测试3.1 模型训练3.2 模型测试 四、PyQt界面实现参考资料 前言 本项目是基于swin_transformer深度学习网络模型的花卉检测系统&#xff0c;…

正确使用@RequestMapping(包含属性详解)

目录 一、基本认知二、RequestMapping的基本使用三、深入学习RequestMapping1、RequestMapping的源码2、RequestMapping的属性2.1 path2.2 method2.3 params2.4 headers2.5 consumes2.6 produces2.7 name 一、基本认知 客户端发起Http请求&#xff0c;会提供一个URL [协议://域…

Unity 2D让相机跟随角色移动

相机跟随移动 最简单的方式通过插件Cinemachine 在窗口/包管理器选择全部找到Cinemachine&#xff0c;导入。然后在游戏对象/Cinemachine创建2D Camera。此时层级中创建一个2D相机。选中人物拖入检查器Follow。此时相机跟随人物移动。 修改相机视口距离 在检查器中Lens下调正…

单细胞RNA测序(scRNA-seq)构建人类参考基因组注释

细胞定量是scRNA-seq重要的分析步骤,主要是进行细胞与基因的定量, cell ranger将比对、质控、定量都封装了起来,使用起来也相当便捷。 单细胞RNA测序(scRNA-seq)基础知识可查看以下文章: 单细胞RNA测序(scRNA-seq)工作流程入门 单细胞RNA测序(scRNA-seq)细胞分离与…

logistic分叉图

MATLAB代码 % 初始化 r_min 2.5; % 参数r的起始值 r_max 4.0; % 参数r的结束值 r_step 0.001; % 参数r的步长 r_values r_min:r_step:r_max; % 参数r的范围% 分岔图数据初始化 num_iterations 1000; % 总迭代次数 num_last_points 100; % 用于绘图的最后的这些…

MySQL Innodb 中的排它锁、共享锁、意向锁、记录锁、间隙锁、临键锁、死锁讲解

一、MySQL 锁机制 MySQL作为流行的关系型数据库管理系统之一&#xff0c;在处理并发访问时&#xff0c;锁起着至关重要的作用。锁的使用可以确保数据的完整性&#xff0c;同时也是实现并发操作的必备工具。在MySQL Innodb 引擎中锁可以理解为两个方向的东西&#xff0c;一个是…

stm32移植嵌入式数据库FlashDB

本次实验的程序链接stm32f103FlashDB嵌入式数据库程序资源-CSDN文库 一、介绍 FlashDB 是一款超轻量级的嵌入式数据库&#xff0c;专注于提供嵌入式产品的数据存储方案。与传统的基于文件系统的数据库不同&#xff0c;FlashDB 结合了 Flash 的特性&#xff0c;具有较强的性能…

白话微机:10.民风淳朴的MCS-51小镇(小镇方言:汇编)

1. 基本结构与周期 MCS-51系列单片机属于8位单片机用 8051单片机构成最小应用系统时&#xff0c;只要将单片机接上时钟电路和复位电路即可MCS-51单片机由CPU、存储器和I/O三部分组成CPU是指&#xff1a;运算器和控制器 “PC CPU 3BUS RAM I/O” 在执行指令过程中&#xff…

cdn加速与ssl加速

cdn CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输的更快、更稳定。 简单的来说&#xff0c;就是把原服务器上数据复制到其他服务器上&#xff0c;用户访…

论文笔记:SmartPlay : A Benchmark for LLMs as Intelligent Agents

iclr 2024 reviewer评分 5688 引入了 SmartPlay&#xff0c;一种从 6 种不同游戏中提取的基准 衡量LLM作为智能体的能力 1 智能代理所需的能力 论文借鉴游戏设计的概念&#xff0c;确定了智能LLM代理的九项关键能力&#xff0c;并为每项能力确定了多个等级&#xff1a; 长文…

Python杂记--使用asyncio构建HTTP代理服务器

Python杂记--使用asyncio构建HTTP代理服务器 引言基础知识代码实现 引言 本文将介绍 HTTP 代理的基本原理&#xff0c;并带领读者构建一个自己的 HTTP 代理服务器。代码中不会涉及到任何第三方库&#xff0c;全部由 asyncio 实现&#xff0c;性能优秀&#xff0c;安全可靠。 基…

[管理者与领导者-163] :团队管理 - 高效执行力 -1- 高效沟通的架构、关键问题、注意事项

目录 前言&#xff1a;沟通是管理者实施管理最重要的工作 一、人与人沟通模型 1.1 模型 1.2 完整过程 1.3 发送和接受方式 1.4 传输 1.5 关于编码与解码 1.6 反馈 1.7 沟通中常见问题 二、管理者如何提高沟通的效率 2.1 为什么管理者布置任务后&#xff0c;总有人…

MYSQL执行过程和顺序详解

一、前言 1.1、说明 就MySQL在执行过程、sql执行顺序&#xff0c;以及一些相关关键字的注意点方面的学习分享内容。 在参考文章的基础上&#xff0c;会增加自己的理解、看法&#xff0c;希望本文章能够在您的学习中提供帮助。 如有错误的地方&#xff0c;欢迎指出纠错&…

Web端Excel的导入导出Demo

&#x1f4da;目录 &#x1f4da;简介:✨代码的构建&#xff1a;&#x1f4ad;Web端接口Excel操作&#x1f680;下载接口&#x1f680;导入读取数据接口 &#x1f3e1;本地Excel文件操作⚡导出数据&#x1f308;导入读取数据 &#x1f4da;简介: 使用阿里巴巴开源组件Easy Exce…

在Windows上安装Go编译器并配置Golang开发环境

文章目录 1、安装Go语言编译程序1.1、下载GoLang编译器1.2、安装GoLang编译器 2、配置Golang IDE运行环境2.1、配置GO编译器2.1.1、GOROOT 概述2.1.2、GOROOT 作用2.1.2、配置 GOROOT 2.2、配置GO依赖管理2.2.1、Module管理依赖2.2.2、GOPATH 管理依赖 2.3、运行GO程序2.3.1、创…

OpenCV 学习笔记2 C++

1.图像直方图 直方图&#xff08;Histogram&#xff09;是图像处理中常用的工具&#xff0c;它表示图像中每个像素强度值的分布情况。在OpenCV中&#xff0c;可以使用 cv::calcHist 函数来计算图像的直方图。 图像直方图是一种展示图像像素强度分布的统计图表。它显示了图像中…

Eclipse+Java+Swing实现图书信息管理系统-TXT存储信息

一、系统介绍 1.开发环境 操作系统&#xff1a;Win10 开发工具 &#xff1a;Eclipse2021 JDK版本&#xff1a;jdk1.8 存储方式&#xff1a;Txt文件存储 2.技术选型 JavaSwingTxt 3.功能模块 4.工程结构 5.系统功能 1.系统登录 管理员可以登录系统 2.查看图书 管理员…

Python数据分析案例42——基于Attention-BiGRU的时间序列数据预测

承接上一篇的学术缝合&#xff0c;排列组合模型&#xff0c;本次继续缝合模型演示。 Python数据分析案例41——基于CNN-BiLSTM的沪深300收盘价预测-CSDN博客 案例背景 虽然我自己基于各种循环神经网络做时间序列的预测已经做烂了.....但是还是会有很多刚读研究生或者是别的领…